Skip to content

Testing

Alejandro Gomez edited this page Nov 22, 2023 · 10 revisions

Table of Contents

  1. Testing the TDM Client
  2. Testing the TDM Server

Testing the TDM Client

This guide will help you set up and run tests for the TDM Client

Unit Tests

Jest is used for unit testing of non-react ES6 modules, such as the tdm-engine. These also get run when you type

npm test

at the command line, and all should pass. In fact, we should eventually implement a "gated check-in" policy in github that automatically runs the unit tests, and blocks the check-in if any unit test fails. See the Create React App documentation on testing with Jest here for further information on how this works.

Cypress Integration Tests

AKA Acceptance Tests AKA End-to-End Tests AKA Journey Tests

Cypress is a front end testing tool built for the modern web. Cypress can test anything that runs in a browser. Cypress enables you to write all types of tests End-to-end tests, Integration tests, Unit tests. We're currently using Cypress for integration tests.

By default, Cypress runs headlessly in the terminal. Alternatively, Cypress runs tests in the browser where you can visually see the tests interacting with the app's UI.

There are a few different ways to start up the Cypress tests depending on if the application servers (Node server and React Client) are already running or not.

Running Cypress Tests

Open a terminal window, and change directories into in the cypress folder. Make sure the npm dependencies are installed with npm install --legacy-peer-deps.

Cypress in Browser

If the TDM app is not already up, run in the terminal:

npm run open

This will start up the Node server and client server concurrently, and after a moment, the Cypress Test Runner will launch in the browser.

If the app servers are already running elsewhere, you can run

npm run cypress:open

to only start up the cypress tests.

You can click on individual tests to run, or click on Run XX integration specs on the top right hand corner to run all the available tests.

You can read the Cypress Test Runner docs to learn more about the tool and how to debug using the test runner.

Note: If you get an error about Cypress not being installed or being unable to load V8, see this Stack Overflow post.

Cypress in Terminal

To run cypress tests headlessly in the terminal (i.e. non-interactively), you can either run

npm run test

to concurrently start up the application Node & React servers, and also run tests in the terminal;

or if the application servers are already up, you can just run

npm run cypress:run`

to only run tests in the terminal.

Testing the TDM Server

This guide will help you set up and run tests for the TDM Server API using Docker-Desktop, Jest, and Supertest. The tests are written in JavaScript and use the Jest testing framework. The tests are located in the __tests__ directory within the server directory.

Tests, Configuration, and Testing Goals for the TDM Server

This section delves into the tests, configurations, and testing goals specifically for the TDM Server. It provides an overview of the tests and what they encompass within this context.

Integration Tests

Integration tests evaluate the interaction of different parts of the application to ensure they work correctly together. TDM Server Tests, test the API endpoints to evaluate the authentication middleware, third-party API calls, and database operations to ensure the entire request-response cycle is working as expected from the route -> middleware -> controller -> service.

Directory Structure and File Breakdown

server
├── __tests__                 # Directory containing all test files
│   └── account.test.js
├── _jest-setup_              # Setup files for the testing environment
│   ├── global-setup          # Global setup files
│   │   ├── global-setup.js
│   │   └── global-teardown.js
│   ├── local-setup           # Local environment setup files
│   │   └── setup-after-env.js
│   ├── utils                 # Utility scripts for test setup
│   │   ├── mssql-container-setup.js
│   │   ├── env-setup.js
│   │   └── server-setup.js
├── app
│   ├── controllers
│   ├── routes
│   ├── schemas
│   └── services
├── db
├── jest.config.js            # Jest configuration file
├── middleware
├── package.json              # Script to configure 'npm test'
└── server.js

_jest-setup_ Directory

global-setup Sub-directory

  • global-setup.js: Calls the mssql-container-setup code to initiate a Dockerized MS SQL Server Database for all tests. This file is referred to in the jest.config.js for global setup.
  • global-teardown.js: Gracefully shuts down the Docker container and manages any other cleanup operations.

local-setup Sub-directory

  • set-up-after-env.js: Sets up the server after Jest initializes a node environment.

utils Sub-directory

  • mssql-container-setup.js: Logic to initialize a Docker container with an MS SQL Server Database using the testcontainers library.
  • server-setup.js: Contains logic for starting a real instance of the server.

__tests__ Directory

This directory houses all test files. When adding new tests, ensure they are placed here.

jest.config.js Configuration File

Current configurations include:

  • globalSetup: Initializes resources before all tests start. For TDM Server, it might start a Docker container with an MS SQL Server Database.
  • globalTeardown: Cleans up resources after all tests finish. For TDM Server, it could shut down the previously started Docker container.
  • setupFilesAfterEnv: Modules that run after the test framework sets up but before tests run. Used to configure or modify the testing environment for each test file.
  • verbose: When true, provides detailed individual test results.

Adding New Tests

  1. Consider a testing goal for the API endpoints. For example, for the 'account' routes, we tested the user management workflow functions end-to-end and we included edge cases.
  2. Create a new test file in the __tests__ directory. The file name should be in the format <file-name>.test.js
  3. Parse through the client/src/services/ directory and go to the respective file for the new tests to find the base URL needed for testing e.g. /api/accounts/. Confirm this by navigating to server/app/routes/index.js and confirming

Note: Tests should be written similar to the _tests_/account.test.js file. The test file should contain a describe block that contains the name of the file and a beforeAll block that sets up the testing environment. The beforeAll block may contain the following:

const request = require("supertest");
const sgMail = require("@sendgrid/mail");
const {
  setupServer,
  teardownServer
} = require("../_jest-setup_/utils/server-setup");

let server;
let originalSendgrid = sgMail.send;

beforeAll(async () => {
  server = await setupServer();
});

afterAll(async () => {
  await teardownServer();
});

beforeEach(() => {
  sgMail.send = jest.fn(async () => {
    return { statusCode: 202 };
  });
});

afterEach(() => {
  sgMail.send = originalSendgrid;
});

describe("TDM Test Example", () => {

    it("should...", async () => {
        // Test logic
    });

    it("should NOT...", async () => {
        // Test logic
    });

});

Prerequisites

Windows Users:

  1. Ensure you have Docker Desktop installed and running.
  2. If using WSL2, make sure the Docker daemon is running within WSL2.
    • Verification: Execute the command sudo docker run hello-world.
      • If you see a success message, your Docker setup is correct.
      • If there's an error, ensure your Docker daemon is active.

Setting Up the Environment

  1. Start up docker on your machine
  2. Ensure no other instances of SQL Server are running on your machine on PORT 1434. You can stop any running SQL Server services via the Windows services panel.
  3. For firewall configurations, add the port specified as HOST_PORT in _jest-setup_/utils/mssql-container-setup.js to the inbound rules as a TCP port. This ensures unrestricted communication between your machine and the Docker container.

Running the Tests

  1. Navigate to the server directory from the root directory.
cd server/
  1. Install all dependencies
npm install
  1. Run all test suites
npm test

Optional: Run a single test suite

npm test -- <test-file-name>

Troubleshooting

  1. If encountering issues with Docker:
    • Test your Docker daemon using the command:
    docker info
  2. Set the HOST_PORT variable in _jest-setup_/utils/mssql-container-setup.js to 1433 and run the tests again.
  3. Turn off any VPNs, as they might interfere
  4. Ensure the required ports (especially 1433 and 1434) aren't being used by other services. If on Windows, you can check the services panel to see if any SQL Server services are running.

Understanding the Tests

The testing framework is set up to:

  1. Spin up a Docker container running SQL Server.
  2. Create a database within this container.
  3. Execute migrations and seed the created database.
  4. Use this container and database setup for all tests to ensure robust testing.
  5. Set up a server instance for testing or use an in-memory representation server from Supertest.

Testing Tools

  • Jest: JavaScript Testing Framework.
  • Supertest: A high-level abstraction for testing HTTP. We use this for an in-memory representation server using a function or an instance of our server. We can use this to test our API endpoints.
  • Testcontainers: Provides throwaway instances services that can run in Docker containers such as our SQL Server Database.

Additional Resources

Clone this wiki locally