Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

CoffeeScript uses Nodeunit testing


May 09, 2021 CoffeeScript


Table of contents


Test with Nodeunit

Problem

If you're using CoffeeScript and want to verify that the functionality is as expected, you can decide to use the Nodeunit test framework.

Discuss

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()

Install Nodeunit

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

Run the test

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

Pass the test

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)

Refactor the test

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.