Testing in JavaScript using Velocity
Unit testing required for to ensure the reliability and maintainability of software, and more there is also methods like Test-Driven Development and Behavior Driven Development are avilable.
Velocity supports many javascript framework for testing it includes;
Jasmine
Cucumber
Mocha
Jasmine supports most of the modes of testing in meteor. Following image shows testing modes and supported frameworks.
Jasmine
Each of the framework has advantages and disadvantage but Jasmine has unique fratures that makes it eady to use and get started with.
To use Jasmine, it does not required to have Node.js installed.
Installation
To install Jasmine run following command in your project directory.
meteor add sanjo:jasmine
We also need to install Velocity Reporter package to see test result.
meteor add velocity:html-reporter
Suites and Specs
Each suite in turn contains a set of Expectations that compare the results of the test - called the actual - with the expected value. A Suite is defined by calling the describe() function. It takes two parameters: the name of the Suite, and the function which contains the calls to the expectation methods called Specs. These are defined using the it() method. Like describe(), it() also accepts a name and function parameter. The it() function parameter may contain variables and one or more calls to the expect() method. Used in conjunction with a Matcher function, these carry out the task of comparing the actual and expected values. Here's a simple example to demonstrate:
describe ("the todo page : page contents", function() {
it ("should include a page title of 'Todo List'", function() {
expect($('title').text()).toEqual('Todo List');
});
it ("should include a page heading of 'Todo List'", function() {
expect($('h1').text()).toEqual('Todo List');
});
});
Put above code in
/test/jasmine/client/integration/todos/page-contents-spec.js, Jasmine supports folder structures.
Pre-defined Matchers
In the above example, the toBeGreaterThan() method is a matcher. It represents a comparison such as ">" using plain English. There are many other matchers available, including:
toBe: represents the exact equality (===) operator.
toEqual: represents the regular equality (==) operator.
toMatch: calls the RegExp match() method behind the scenes to compare string data.
toBeDefined: opposite of the JS "undefined" constant.
toBeUndefined: tests the actual against "undefined".
toBeNull: tests the actual against a null value - useful for certain functions that may return null, like those of regular expressions (same as toBe(null))
toBeTruthy: simulates JavaScript boolean casting.
toBeFalsy: like toBeTruthy, but tests against anything that evaluates to false, such as empty strings, zero, undefined, etc…
toContain: performs a search on an array for the actual value.
toBeLessThan/toBeGreaterThan: for numerical comparisons.
toBeCloseTo: for floating point comparisons.
toThrow: for catching expected exceptions.
Example
Put follwing code in demoapplication.css
<head>
<title>jasminetest</title>
</head>
<body>
<h1>Welcome to Meteor!</h1>
{{> hello}}
</body>
<template name="hello">
<button id="clickButton">Click Me</button>
<p id="buttonText">You've pressed the button {{counter}} times.</p>
</template>
Put follwing code in demoapplication.js
if (Meteor.isClient) {
// counter starts at 0
Session.setDefault('counter', 0);
Template.hello.helpers({
counter: function () {
return Session.get('counter');
}
});
Template.hello.events({
'click button': function () {
// increment the counter when button is clicked
Session.set('counter', Session.get('counter') + 1);
}
});
}
Write following tets to check counter display proper or not
inside tests/jasmine/cleint/integration/sample/buttonSpec.js
describe('clicking the button', function () {
// reset the counter before each test
beforeEach(function() {
Session.set('counter', 0);
});
it('should show how many times the button was pressed', function () {
// Get the text we are testing
var text = $('p#buttonText').text();
// assert that we see 'You've pressed the button times.'
expect(text).toEqual("You've pressed the button 0 times.");
});
});
Output: