Getting started
In this tutorial you’ll learn how to write your first tests using jstest
and how to run them in the browser. Let’s start by writing a spec for some
code we want to write, say, an implementation of the Set
data structure.
This class must be able to store a unique collection of strings and tell us
whether a string is in the set or not.
Let’s start by creating a few directories to hold our project (this mirrors
the structure of the jstest
GitHub repo
if you want to download the finished example). Download jstest
and save it
into the build/
directory, and create the following directories:
build/ jstest.js example/ browser.html lib/ set.js spec/ set_spec.js
Writing a spec
We’ll write a spec for our project in spec/set_spec.js
. A spec begins with
a call to JS.Test.describe()
, with the tests nested inside.
// example/spec/set_spec.js JS.Test.describe('Set', function() { with(this) { before(function() { with(this) { this.set = new Set(['foo']) }}) describe('hasMember', function() { with(this) { it('returns true for members', function() { with(this) { assert( set.hasMember('foo') ) }}) it('returns false for non-members', function() { with(this) { assertNot( set.hasMember('bar') ) }}) }}) }})
Setting up a test page
We’ve written a simple spec for one method in our class, now we need a way to
run it. To do this, make a page in browser.html
containing the following
code. All it does it load jstest
, our code, and our tests, and tell
JS.Test
to run the test suite:
<!-- example/browser.html --> <!doctype html> <html> <head> <meta charset="utf-8"> <title>jstest</title> </head> <body> <script src="../build/jstest.js"></script> <script src="./lib/set.js"></script> <script src="./spec/set_spec.js"></script> <script> JS.Test.autorun() </script> </body> </html>
If you don’t like wrangling script
tags, you can use any module loader you
like; jstest
doesn’t care how your code gets loaded.
If you open this page in your browser you’ll see something like this. If you click the names of the tests to expand them you can see why each one failed.
Making the tests pass
Okay, looks like Set
is not defined, which makes sense – we’ve not written
any code yet. So let’s add the following to lib/set.js
to remove the error:
// example/lib/set.js var Set = function() {}
If we reload the tests we have a different error this time:
A bit better, we just need to add the missing method. Let’s add the smallest amount of code to make this error go away:
// example/lib/set.js var Set = function() {} Set.prototype.hasMember = function() { return true }
This has made one of the tests pass, but one is still broken:
Finally, let’s implement the logic we really need to make the tests pass:
// example/lib/set.js var Set = function(members) { this._members = {} for (var i = 0, n = members.length; i < n; i++) { this._members[members[i]] = true } } Set.prototype.hasMember = function(value) { return this._members.hasOwnProperty(value) }
At last, when we reload the page we see all the tests have passed: