Simple Test-Driven Development (TDD) With Mocha and Node.js
Published: 2022-01-16 21:31:39

---
title: Simple Test-Driven Development (TDD) With Mocha and Node.js
published: true
description: A tutorial on test-driven development (TDD) using Mocha and Node.js
tags: 
//cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5og41hq6bu7tk0rm7p9.png
---
Here is a quick tutorial on Test-Driven Development (TDD) with the [Mocha](https://mochajs.org/) test tool and Node.js.

## Overview

**Test-Driven Development**, or _TDD_, is a [programming style](https://www.agilealliance.org/glossary/tdd/) that includes three tightly integrated activities: _coding_, _unit testing_, and _refactoring_.

The TDD approach is a cycle:

![Test-Driven Development](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q5og41hq6bu7tk0rm7p9.png)

1. **RED/FAIL** - Write one unit test for a single feature of the program, execute the test, and ensure that it fails. It should fail because the program feature has not been developed yet.
1. **GREEN/PASS** - Write "just enough" code to make the test pass. The code may simply hard-code the correct output for a given input value.
1. **REFACTOR** - Refactor the code with real logic until it passes the unit test. Implement the feature and remove the hard-coded result. Refactoring does *not* change the behavior of the program; the given input must still produce the expected output. Refactoring may also enhance a program or improve efficiency.
1. _Repeat_.

## TDD With Mocha and Node.js

### Prerequisites

* Download and install [Node.js](https://nodejs.org/en/download/) locally on your computer.
* A terminal application: _Terminal_ (macOS) or [_Git Bash_](https://gitforwindows.org/) (Windows).

### Tutorial

Here is a new program feature to implement. The _Restaurant Tip Calculator_ calculates tips for a restaurant bill.

| **Feature:** Restaurant Tip Calculator |
| ---------------------- |
| **Scenario:** Calculate a 20% restaurant tip. |
| **When** the restaurant bill is `$100` |
| **Then** the tip amount is `$20` |

Here are steps that illustrate the TDD process:

1. Open a terminal and go into a working folder:

    ```bash 
    $  cd myfolder
    $
    ```

1. Initialize the folder to use the _Mocha_ test tool:

    ```bash
    $  git init .  # for Git versioning later
    $
    $  npm install -g mocha  # install mocha locally
    $
    $  mocha  # try mocha. It will fail; no tests yet...
    $  Error: No test files found: "test"         
    $
    ```

1. From inside the `myfolder` folder, create a directory named _test_: `mkdir test` .
1. Create an empty unit test program inside the `test` folder named `TipTest.js`: `touch test/TipTest.js` .
1. In the `myfolder` folder create an empty program for the program we are testing: `touch Tip.js` .
1. Run the Mocha test. We now have the minimal amount of code to have a failed test:

    ```bash
    $  mocha


      0 passing (2ms)

    $ 
    ```

1. Add the first unit test to the `TipTest.js` program. This unit test checks the tip amount for a $100 amount. The correct/expected tip amount is $20:

    ```JavaScript
    assert = require("assert");

    Tip = require("../Tip.js").Tip  // program to test

    // new unit test
    describe("Check tip amount", function() {
      describe("sending in 100", function() {
        it("should return 20", function() {
          var result = new Tip().CalculateTip(100);
          assert.equal(20,result);
        }); 
      }); 
    }); 
    ```
1. **RED**: Add minimal code to the `Tip.js` program that initially fails the test:

    ```JavaScript
    function Tip() {
    }

    Tip.prototype.CalculateTip = function(p1) {

      return 0; // hard-code a result that will FAIL

    }

    module.exports.Tip = Tip;
    ```

1. Run the Mocha test. It will execute the test and fail, because the actual result of the program is `0`, but the expected result is `20`:

    ```bash
    $  mocha


      Check tip amount
        sending in 100
          1) should return 20


      0 passing (6ms)
      1 failing

      1) Check tip amount
           sending in 100
             should return 20:

          AssertionError [ERR_ASSERTION]: 20 == 0
          + expected - actual

          -20
          +0
      
          at Context.<anonymous> (test/TipTest.js:10:14)
          at processImmediate (internal/timers.js:456:21)



    $
    ```

1. **GREEN**: Modify the `Tip.js` program to hard-code it to succeed:

    ```JavaScript
    function Tip() {
    }

    Tip.prototype.CalculateTip = function(p1) {

      return 20; // hard-code a result that will SUCCEED

    }

    module.exports.Tip = Tip;
    ```

1. Run the Mocha test again. This time it succeeds, because the actual and expected results are both `20`:

    ```bash
    $  mocha


      Check tip amount
        sending in 100
          ✔ should return 20


      1 passing (4ms)

    $
    ```

1. **REFACTOR**: Modify the code by implementing the _correct_ logic for the `Tip.js` program:

    ```JavaScript
    function Tip() {
    }

    Tip.prototype.CalculateTip = function(p1) {

      // NEW
      let tipAmount = p1 * 0.20
      return tipAmount;

    }

    module.exports.Tip = Tip;
    $
    ```

1. Run the Mocha test and see it succeed with real, correct logic:

    ```bash
    $  mocha


      Check tip amount
        sending in 100
          ✔ should return 20


      1 passing (6ms)

    $  
    ```

14. You have successfully used TDD to develop this first feature of the _Tip Calculator_ program. Add more unit tests to test the program further or add new features.

## Your turn

Create a new unit test for the _Tip Calculator_ app that implements this feature:

| **Feature:** Restaurant Tip Calculator |
| ---------------------- |
| **Scenario:** Calculate a 25% restaurant tip. |
| **When** the restaurant bill is at least `$200` |
| **Then** the tip amount is 25% of the restaurant bill |

## Conclusion

This completes the TDD tutorial with Mocha. Note how TDD occurs in iterations. Establish a test that you expect to fail. Modify the test to make it succeed with the expected value. Finally, implement real logic in your program that passes the test. Repeat the process for each new feature of the program.

Thanks for reading!

Follow me on Twitter [@realEdwinTorres](https://twitter.com/realEdwinTorres) for programming tips, software engineering content, and career advice. 😊