Jasmine is a nice testing framework that allows us to write tests in a BDD manner.
Let's see how to use it in our project.
First of all, we need to incorporate it into our build. There is a maven plugin that will let us execute JavaScript tests within test build phase. We will add it to our pom.xml :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<plugin> | |
<groupId>com.github.searls</groupId> | |
<artifactId>jasmine-maven-plugin</artifactId> | |
<version>1.3.1.2</version> | |
<executions> | |
<execution> | |
<goals> | |
<goal>test</goal> | |
</goals> | |
</execution> | |
</executions> | |
</plugin> |
Apart from executing tests within build, we can run them during development phase.
The maven goal jasmine:bdd starts the Jetty server and under http://localhost:8234 URL we can see the results of executing test fixtures.
Reloading the page will execute the latest version of our code.
Let's see it in action. We have a simple JavaScript function residing in src/main/javascript/simple.js that increments the number passed as an argument.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var increment = function (number) { | |
if (isNaN(number)) { | |
throw 'Argument ' + number + ' is not a number' | |
} | |
return number + 1 | |
} | |
incrementer = { | |
increment: increment | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe('incrementer tests', function() { | |
it ('should be defined', function() { | |
expect(incrementer).toBeDefined() | |
}) | |
it ('should increment', function() { | |
expect(incrementer.increment(1)).toEqual(2) | |
}) | |
it ('should throw exception when argument is not a number', function() { | |
var illegalArg = 'stringy' | |
var thrown | |
try { | |
incrementer.increment(illegalArg) | |
} catch (e) { | |
thrown = e | |
} | |
expect(thrown).toBe('Argument ' + illegalArg + ' is not a number') | |
}) | |
}) |
Then the specific test cases are defined by calling function it.
We're testing the sunny day scenario and border case that throws the exception.
At the beginning as a sanity check we can test if the function is defined.
Jasmine has a lot of advanced features, we can even use mocks, expectations and argument matchers.
Nothing stops us from writing tests first and going through red-green-refactor cycle.
Let's write a function that will count the number of specific elements on our page.
The behaviour of our component is defined by following spec:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
describe('counter tests', function() { | |
it ('should be defined', function() { | |
expect(elementCounter).toBeDefined() | |
}) | |
it ('should count 0 elements', function() { | |
expect(elementCounter.count()).toEqual(0) | |
}) | |
it ('should count 1 element', function() { | |
var container = document.createElement('div') | |
container.setAttribute('id','myId') | |
document.body.appendChild(container) | |
expect(elementCounter.count()).toEqual(1) | |
}) | |
}) |
To implement, it we'll use jquery (we need to add it to src/main/javascript):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var count = function () { | |
return $('#myId').length | |
} | |
elementCounter = { | |
count: count | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
------------------------------------------------------- | |
J A S M I N E S P E C S | |
------------------------------------------------------- | |
[INFO] | |
counter tests | |
should be defined | |
should count 0 elements | |
should count 1 element | |
incrementer tests | |
should be defined | |
should increment | |
should throw exception when argument is not a number | |
Results: 6 specs, 0 failures |