Zimki provides a framework for writing unit tests for your server-side JavaScript code. This page explains how to write tests and suggests some best practices for doing so.
Using a staging realm
Unit test code in zimki is run in the same context as all other JavaScript code in your realm. This means that you can add, modify and delete data in your realm. This is necessary in order to write thorough unit tests that cover all of the functions that modify data in your realm, but could of course be damaging to a live application.
We recommend that you do your development in a staging realm and merge changes into a live realm when you are happy with them and all of your tests pass. This allows you to write tests in the staging realm that thoroughly exercise your code without having to worry about data in the realm. The realm backup and restore features in the portal provide the ability to merge by backing up the staging realm and restoring it over the live realm.
Writing a test
In our application we want a Person class to represent people. We want instances of Person to stringify to the person's name followed by their age in parentheses. We also want a method that tells us if the person is old enough to vote.
Let's start off by writing the test. Unit tests are created in the Unit Tests section of the portal under the Realm menu, much in the same way that JavaScript and Template instances are created. Create a test and enter the code below:
plan(2);
var fred = Person.create({ name: 'Fred', age: 16 });
assertEquals('toString correct', fred.toString(), 'Fred (16)');
assert('Fred not old enough to vote', !fred.canVote());
If you run this test you should see if fail as expected. Let's now create the Person class and write the JavaScript code that implements the behaviour that we want. Create a class called Person and a JavaScript instance with the following code:
Person.prototype.toString = function() {
return this.name + ' (' + this.age + ')';
}
Person.prototype.canVote = function() {
return this.age >= 18;
}
Now if you run the test again you should see it pass. We now know that the Person class behaves in the way that we want it to.
Test methods
- plan(n)
The number of assertions that you expect to be made in this unit test. This is not mandatory but it is recommended. If specified and the actual number of assertions made does not equal the plan, the test will fail.
- assert([comment], value)
Test passes if (value)
- assertEquals([comment], value1, value2)
Test passes if (value1 == value2)
- assertNotEquals([comment], value1, value2)
test passes if (value1 != value2)
Assertion comments
Every assert function can take an optional comment. This comment will be displayed next to failed tests and makes test output much clearer. You can either pass the comment as the first argument of the assertion method (as with JSUnit), or you can pass it to the comment-handling function returned by all assertion methods:
assertEquals('1 plus 1 equals 2', 1 + 1, 2);
// or
assertEquals(1 + 1, 2)('1 plus 1 equals 2');