May 09, 2021 CoffeeScript
If you're using CoffeeScript and want to verify that the functionality is as expected, you can decide to use the Nodeunit test framework.
Nodeunit is a JavaScript implementation of the xUnit family in the Unit Testing Libraries, Java, Python, Ruby, smalltalk.
When using the xUnit family test framework, you need to write code that describes the expected functionality of the required tests in a file.
For example, we want our calculator to add and subtract, and for both positive and negative numbers to be calculated correctly, our test is as follows.
# test/calculator.test.coffee
Calculator = require '../calculator'
exports.CalculatorTest =
'test can add two positive numbers': (test) ->
calculator = new Calculator
result = calculator.add 2, 3
test.equal(result, 5)
test.done()
'test can handle negative number addition': (test) ->
calculator = new Calculator
result = calculator.add -10, 5
test.equal(result, -5)
test.done()
'test can subtract two positive numbers': (test) ->
calculator = new Calculator
result = calculator.subtract 10, 6
test.equal(result, 4)
test.done()
'test can handle negative number subtraction': (test) ->
calculator = new Calculator
result = calculator.subtract 4, -6
test.equal(result, 10)
test.done()
Before you can run your tests, you must install Nodeunit:
Start by creating a package.json file
{
"name": "calculator",
"version": "0.0.1",
"scripts": {
"test": "./node_modules/.bin/nodeunit test"
},
"dependencies": {
"coffee-script": "~1.4.0",
"nodeunit": "~0.7.4"
}
}
Next run from one terminal.
$ npm install
Use the line of code to easily run the test file:
$ npm test
The test failed because we didn't have calculator.coffee
suki@Yuzuki:nodeunit_testing (master)$ npm test
npm WARN package.json calculator@0.0.1 No README.md file found!
> calculator@0.0.1 test /Users/suki/tmp/nodeunit_testing
> ./node_modules/.bin/nodeunit test
/Users/suki/tmp/nodeunit_testing/node_modules/nodeunit/lib/nodeunit.js:72
if (err) throw err;
^
Error: ENOENT, stat '/Users/suki/tmp/nodeunit_testing/test'
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
Let's create a simple file
# calculator.coffee
class Calculator
module.exports = Calculator
And re-run the test suite.
suki@Yuzuki:nodeunit_testing (master)$ npm test
npm WARN package.json calculator@0.0.1 No README.md file found!
> calculator@0.0.1 test /Users/suki/tmp/nodeunit_testing
> ./node_modules/.bin/nodeunit test
calculator.test
✖ CalculatorTest - test can add two positive numbers
TypeError: Object #<Calculator> has no method 'add'
...
✖ CalculatorTest - test can handle negative number addition
TypeError: Object #<Calculator> has no method 'add'
...
✖ CalculatorTest - test can subtract two positive numbers
TypeError: Object #<Calculator> has no method 'subtract'
...
✖ CalculatorTest - test can handle negative number subtraction
TypeError: Object #<Calculator> has no method 'subtract'
...
FAILURES: 4/4 assertions failed (31ms)
npm ERR! Test failed. See above for more details.
npm ERR! not ok code 0
Let's implement the method to see if the test can pass.
# calculator.coffee
class Calculator
add: (a, b) ->
a + b
subtract: (a, b) ->
a - b
module.exports = Calculator
When we re-run the test, we can see all pass:
suki@Yuzuki:nodeunit_testing (master)$ npm test
npm WARN package.json calculator@0.0.1 No README.md file found!
> calculator@0.0.1 test /Users/suki/tmp/nodeunit_testing
> ./node_modules/.bin/nodeunit test
calculator.test
✔ CalculatorTest - test can add two positive numbers
✔ CalculatorTest - test can handle negative number addition
✔ CalculatorTest - test can subtract two positive numbers
✔ CalculatorTest - test can handle negative number subtraction
OK: 4 assertions (27ms)
Now that all the tests have passed, we should look at our code or whether the tests can be refactored.
In our test file, each test creates its own calculator instance. T his makes our tests quite repetitive, especially for large test suites. Ideally, we should consider moving the initialization code to run before each test.
Typically in other xUnit libraries, Nodeunit provides a setUp (and tearDown) feature that is called before testing.
Calculator = require '../calculator'
exports.CalculatorTest =
setUp: (callback) ->
@calculator = new Calculator
callback()
'test can add two positive numbers': (test) ->
result = @calculator.add 2, 3
test.equal(result, 5)
test.done()
'test can handle negative number addition': (test) ->
result = @calculator.add -10, 5
test.equal(result, -5)
test.done()
'test can subtract two positive numbers': (test) ->
result = @calculator.subtract 10, 6
test.equal(result, 4)
test.done()
'test can handle negative number subtraction': (test) ->
result = @calculator.subtract 4, -6
test.equal(result, 10)
test.done()
We can re-run the test and still pass it all.