Skip to content

Latest commit

 

History

History
119 lines (112 loc) · 5.49 KB

05 - Integration testing.md

File metadata and controls

119 lines (112 loc) · 5.49 KB

Practical 5 - Integration testing

Objectives

  • Ensure integration tests are kept separate from unit tests
  • Spin up a live copy of the system from your test code
  • Write a test which calls an API, and asserts on the API result (black-box)
  • Write a test which calls an API, and asserts on database contents (white-box)
  • Use tear-down hooks to clean up state left behind by the test

Extensions

  • Write integration tests for all APIs exposed by the system, stubbing things if necessary :)
  • Write a bash script to execute unit tests first, then integration tests

Set-up steps

Same pattern as previous pracs

  1. Commit any outstanding changes on your Prac04 branch: git commit -am 'Some message'
  2. Head back over to master: git checkout master
  3. Check out the Start Point for Prac 5: git checkout Prac05-StartPoint
  4. Create a branch to make your changes on without impacting the main repo: git checkout -b Prac05

Practical Steps

  1. Push existing unit tests down into a "unit" folder within the "test" folder
  2. Create a new "integration" folder under the "test" folder
  3. Update the existing package.json and launch.json config for the new location
  4. Add new package.json and launch.json entries to run integration tests separately to unit tests
  5. Create an integration test file
  6. Make the app.js exportable and get a reference to it in
  7. Add placeholder describe and it blocks
  8. Run the integration tests and ensure the app was spun up
  9. Implement a test that calls the /api/pets/generateMatch API and asserts on the result
  10. Implement a test that calls the /api/pets/random API, and asserts on the history content directly from the database
  11. Add a tear-down hook to reset the app's state after each test

Solutions

Here's a step-by-step walkthrough of the practical steps, for if you get stuck :)

  1. Push existing unit tests down into a "unit" folder within the "test" folder
    • Create a test/unit folder
    • Move existing tests into the new folder
    • Update any require references to our app's code to ensure their relative paths are still correct
    • eg require('../src/pet-service'); will need to become require('../../src/pet-service');, because the test file is now one level deeper in the directory structure
  2. Create a new "integration" folder under the "test" folder
    • Create a test/integration folder
  3. Update the existing package.json and launch.json config for the new location
    • In package.json, update the test script with a pathspec: "test": "mocha test/unit/**/*.js"
    • In launch.json:
      • Update the name of the existing Mocha Tests configuration to Unit Tests
      • Update the final args entry to point to the new unit test folder: "${workspaceFolder}/test/unit"
  4. Add new package.json and launch.json entries to run integration tests separately to unit tests
    • Add a new package.json script called int-test which sets the NODE_ENV variable to test, and starts the integration tests
      • Linux/OSX: NODE_ENV=test mocha --timeout 5000 test/integration/**/*.js
      • Windows: SET NODE_ENV=test& mocha --timeout 5000 test/integration/**/*.js
    • Add a new Mocha configuration to launch.json which points to the integration folder:
      {
          "type": "node",
          "request": "launch",
          "name": "Integration Tests",
          "program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
          "args": [
              "-u",
              "tdd",
              "--timeout",
              "5000",
              "--colors",
              "${workspaceFolder}/test/integration"
          ],
          "env": {
              "NODE_ENV": "test"
          },
          "internalConsoleOptions": "openOnSessionStart"
      }
  5. Create an integration test file
    • Add a new file test/integration/api-tests.js
  6. Make the app.js exportable and get a reference to it in
    • Open app.js
    • At the bottom of the file, add a line to export the app once it's spun up: module.exports = app;
  7. Add placeholder describe and it blocks
  8. Run the integration tests and ensure the app was spun up
  9. Implement a test that calls the /api/pets/generateMatch API and asserts on the result
    describe("When requesting a dog match for Alice", function() {
        it("returns a Beaglier", function() {
            return httpClient.get("http://localhost:4000/api/pets/generateMatch?ownerName=Alice&petType=Dog")
                .then(result => {
                    result.should.exist;
                    result.should.have.property('petName').that.equals("Beaglier");
                });
        });
    });
  10. Implement a test that calls the /api/pets/random API, and asserts on the history content directly from the database
    describe("When requesting a random pet match", function() {
        it("adds a single entry to the request history", function() {
            return httpClient.get("http://localhost:4000/api/pets/random")
                .then(function() {
                    var keys = db.getKeys();
                    keys.length.should.equal(1);
                });
        });
    });
  11. Add a tear-down hook to reset the app's state after each test
    • Add an afterEach() function which calls db.clear(), like this:
      afterEach(function() {
          db.clear();
      });