Universal unit testing (browser, Node.js) with Jasmine
Join the DZone community and get the full member experience.
Join For FreeThis post gives a quick introduction to the JavaScript unit test framework Jasmine. It has the advantage of allowing tests to be run both in browsers and on Node.js.
The example project
As an example, this post uses the project jasmine-intro on GitHub. It is a directory with the following files:jasmine-intro/ ├── repeat.js ├── repeat.runner.html └── repeat.spec.jsrepeat.js is the code to be tested:
if (! String.prototype.repeat) { String.prototype.repeat = function (times) { return new Array(times+1).join(this); } }repeat.spec.js contains the tests and can be run on Node.js, repeat.runner.html loads and executes repeat.spec.js in a web browser.
Writing tests
An expectation is used to test one single assertion, such as “if I call this method in this manner then the result has to be X”. You write an expectation by calling the function expect() with a value you want to test. The returned object has matchers, methods that allow you to examine the value. See below for a list of commonly used matchers. Example:expect("abc".repeat(2)).toEqual("abcabc");A spec is a sequence of expectations that tests a single functionality. You write a spec via the function
it(description, function)where description is a text string describing the functionality being tested and function runs the expectations. Example:
it("repeats strings", function() { expect("abc".repeat(2)).toEqual("abcabc"); expect("abc".repeat(0)).toEqual(""); });A suite groups related specs. You cannot write stand-alone specs. A spec is created via the function
describe(description, function)where description is a text string describing what entity the suite is about and function runs the specs. Example:
describe("repeat", function() { it("repeats strings", function() { expect("abc".repeat(2)).toEqual("abcabc"); expect("abc".repeat(0)).toEqual(""); }); });
Matchers
The following matchers are frequently used in Jasmine – quoting the Jasmine documentation:You negate a matcher by prepending .not:
expect(x).toEqual(y); compares objects or primitives x and y and passes if they are equivalent expect(x).toBe(y); compares objects or primitives x and y and passes if they are the same object expect(x).toMatch(pattern); compares x to string or regular expression pattern and passes if they match expect(x).toBeDefined(); passes if x is not undefined expect(x).toBeUndefined(); passes if x is undefined expect(x).toBeNull(); passes if x is null expect(x).toBeTruthy(); passes if x evaluates to true expect(x).toBeFalsy(); passes if x evaluates to false expect(x).toContain(y); passes if array or string x contains y expect(x).toBeLessThan(y); passes if x is less than y expect(x).toBeGreaterThan(y); passes if x is greater than y expect(fn).toThrow(e); passes if function fn throws exception e when executed
expect(x).not.toEqual(y);
Running tests on Node.js
In order to run Jasmine on Node.js, we only need to install the module jasmine-node via npm:sudo npm install -g jasmine-nodeThe nice thing about jasmine-node is that it also installs a command line tool for running tests. Given the following content of repeat.spec.js.
require("./repeat.js"); describe("repeat", function() { it("repeats strings", function() { expect("abc".repeat(2)).toEqual("abcabc"); expect("abc".repeat(0)).toEqual(""); }); });Now you can perform the above tests via
$ jasmine-node repeat.spec.js Started . Finished in 0.003 seconds 1 test, 1 assertion, 0 failuresIf invoked without an argument, the jasmine-node command looks in the current directory and all of the directories it contains for files ending with “.spec.js” and runs them.
Running tests in the browser
The following HTML runs the file repeat.spec.js in a browser.<!doctype html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Jasmine Spec Runner: repeat</title> <link rel="shortcut icon" type="image/png" href="/Users/rauschma/local/jasmine/images/jasmine_favicon.png"> <link href="/Users/rauschma/local/jasmine/lib/jasmine-core/jasmine.css" rel="stylesheet"/> <!-- Jasmine files --> <script type="text/javascript" src="/Users/rauschma/local/jasmine/lib/jasmine-core/jasmine.js"></script> <script type="text/javascript" src="/Users/rauschma/local/jasmine/src/html/TrivialReporter.js"></script> <!-- CUSTOMIZE: The code to be tested and the tests --> <script type="text/javascript" src="repeat.js"></script> <script> function require() { // do nothing, allows repeat.spec.js to require a node module } </script> <script type="text/javascript" src="repeat.spec.js"></script> <script type="text/javascript"> (function() { var jasmineEnv = jasmine.getEnv(); ... window.onload = function() { ... jasmineEnv.execute(); }; })(); </script> </head> <body> </body> </html>Apart from the paths starting with
/Users/rauschma/local/jasmine/only the lines after
<!-- CUSTOMIZE: ... -->need to be changed for a given spec.js file. Opening the HTML file in a web browser looks as follows. All the tests ran successfully, which explains why there is only green and no red.
Related reading
unit test
Node.js
Jasmine (JavaScript testing framework)
Pass (software)
Opinions expressed by DZone contributors are their own.
Comments