TDDing a Vert.x-Chat in Javascript (Pt.1)

Vert.x is a "a lightweight, high performance application platform for the JVM that's designed for modern mobile, web, and enterprise applications." 1

In essence Vert.x provides you with a framework to write reactive applications on the JVM in a polyglot fashion because for one it uses the reactor pattern like node.js and two the frameworks provides language bindings for several languages (e.g. Java, jRuby, Javascript and Scala).

Additional to its polyglot nature Vert.x has the benefit of being fast. Very fast according to Techempower's Web Framework Benchmark.

Another thing great about Vert.x is that it makes it easy to write near real-time client-side applications in Javascript. With Vert.x's EventBus you can create a bridge between your Server-Verticles and Client Browsers that push updates via a Sock.js-Bridge to connected clients whenever updates happen. Sounds great. Let's look at an example:

For this example I will walk you through building a small chat application with Vert.x. We will also have a look on how we can improve the Verticle code to use RSVP-Promises instead of the normal callback pattern Vert.x expects you to use out of the box when using the Javascript language in a follow up of this tutorial series.

TDD all the way

This tutorial will guide you through the process of building a chat application in a test driven fashion. I think TDD is the best way to learn new concepts (and to programm in general) because it forces you to challenge yourself to really understand a topic or problem set you are working on. If you disagree you can have a look at the source-code on Github and move on.

For the first part of this tutorial we will simply try to get everything setup correctly and write a first test.

Test-Driven-Development and Vert.x

We will write our server-side verticle and our client in javascript. So the First thing we have to do is to setup Vert.x and find out how to test Vert.x code in javascript.

Installing Vert.x

Installing Vert.x is pretty straight forward. Please follow the guide on the Vert.x homepage.

If you are on MacOS you are lucky and you can install Vert.x via homebrew.

brew install vert.x  

This gives you the vertx command.

vertxQunitSinon

To execute Vert.x test code written in Javascript you need to install the vertxQunitSinon-module from the Vert.x registry. This happens automatically when trying to run the module so we can continue in creating a test verticle right away.

Writing the first test

Working with vertxQunitSinon can be kind of strange when starting with it but bare with me. First we have to create Vert.x-module that includes our testcode. In the example I have created a module named com.firstiwaslike~vertx-tdd~0.0.1 which roughly follows the naming scheme for Vert.x modules.

mods/com.firstiwaslike~chat-test~0.0.1  
├── main.js
├── mod.json
└── test_chat.js

Let's walk through the different files quickly:

mod.json is the definition of our test module. We simply define what the main entry file of our module is (the file that gets run when you run the module via vertx runmod) and its dependencies (in this case the vertxQunitSinon-module).

{
  "main": "main.js",
  "includes": "mohlemeyer~vertxQunitSinon~0.0.3"
}

main.js is the entry file of our module. In main.js we tell vert.x to execute our test with qunit and then exit.

var container = require('vertx/container');  
var runTests = require('jslibs/qunit/vertxTestRnr');

runTests(  
  function () {
    container.exit();
  }
);

test_chat.js is the file where we will write our tests. This file is empty.

When running the module in its current state we will see the following output:

» vertx runmod com.firstiwaslike~chat-test~0.0.1
Downloading mohlemeyer~vertxQunitSinon~0.0.3. Please wait...  
Downloading 100%  
Module mohlemeyer~vertxQunitSinon~0.0.3 successfully installed  
Loading testfile: test_chat.js  
----------------------------------------
    PASS: 0  FAIL: 0  TOTAL: 0
    Finished in 14 milliseconds.
----------------------------------------

This output is interesting for two reasons. First we see that Vert.x automatically downloads the vertQunitSinon-module which we had not installed previously. This is the way Vert.x's module system works and you can dive into its mods manual if you want to learn more. The second thing is that the outputs tells us that it has loaded our testfile and we have just run 0(!) tests. Great! Our setup seems to be working.

To actually get a test running we define the simplest test and check if Vert.x is present. Because we are doing TDD we of course write a failing test first:

// we need to require qunitContext from vertxQunitSinon
// to have access to QUnit
require('jslibs/qunit/qunit/qunitContext')(this);

var vertx = undefined;

// always prepend QUnit it front of module when using vertxQunitSinon
QUnit.module('Vert.x-TDD');

test('requiring vertx works in testfile', function() {  
  ok(vertx, 'vertx is defined');
});

And this is what we get:

Loading testfile: test_chat.js  
----------------------------------------
Vert.x-TDD  
----------------------------------------
 FAIL - requiring vertx works in testfile
    | OK | vertx is defined
----------------------------------------
    PASS: 0  FAIL: 1  TOTAL: 1
    Finished in 180 milliseconds.
----------------------------------------

As expected and intended this test fails. The test is easily fixed by requiring vertx.

require('jslibs/qunit/qunit/qunitContext')(this);

var vertx = require('vertx');

QUnit.module('Vert.x-TDD');

test('requiring vertx works in testfile', function() {  
  ok(vertx, 'vertx is defined');
});
Loading testfile: test_chat.js  
----------------------------------------
Vert.x-TDD  
----------------------------------------
 PASS - requiring vertx works in testfile
----------------------------------------
    PASS: 1  FAIL: 0  TOTAL: 1
    Finished in 187 milliseconds.
----------------------------------------

Ok great. The test is passing and we made sure we can use Vert.x.

The next thing we want to do is to work with the Vert.x-EventBus to send chat messages around with Vert.x. We will come to this in Part 2 of this tutorial.

[1] Vert.x.io - Website

comments powered by Disqus