Files
2023-03-09 11:19:11 -07:00

4.0 KiB

Testing in 0x-rfq-api

Tests in 0x-rfq-api are written in Jest with the ts-jest plugin.

Currently, assertions are written using Chai with the chai-as-promised plugin. However, "expect" to migrate to Jest expect in the future.

Migrating from Mocha

The only superficial difference when writing tests is that Jest uses beforeAll and afterAll instead of before and after.

Since we're using ts-jest, no build is required before running the tests. If there are build errors, they will be caught by Jest.

Running the tests

yarn test

This invokes the script jest --forceExit --runInBand.

--forceExit makes the test suite close while the dependencies shut down. --runInBand runs the tests sequentially. This is necessary for the docker service dependencies. If we can swap those for in memory versions, we should be able to run the tests in parallel.

Customizing your test run

View details at https://jestjs.io/docs/cli.

Run tests for specific files

yarn test --findRelatedTests src/services/rfqm_service.ts src/services/rfq_maker_service.ts

Testing uncommitted file changes

yarn test -o

Watch for changes

To watch for changes in all files, run yarn test --watchAll.

To watch for changes in uncommitted files, run yarn test --watch.

Run tests by name

Use the -t flag with the name of your test:

yarn test -t "RfqmService HTTP Logic"

Test by test file name

Append the file name (you can omit the extension).

yarn test rfqm_service_test

Failing fast

By default Jest will run all the tests and then exit.

To exit after the first failure, run

yarn test --bail

Under the hood

First Jest fetches the configuration in jest.config.ts.

Next, Jest runs test/configureTestEnv.ts to configure the test environment.

This logic:

  • Sets the environment variables present in test/test_env
  • Loads chai-as-promised
  • Silences the output of the logger

If you need to see the output from the logger, change the line process.env.LOG_LEVEL = 'silent' to use the log level you need (i.e. info, warn, error).

Dependencies

Dependency managment logic lives in test/test_utils/deployment.ts.

Services are specified in docker-compose-test.yml. Currently, the available services are a Postgres database (postgres), Redis key-value store (redis), and Ganache local blockchain (ganache).

To startup dependencies, use

const teardownDependencies = await setupDependenciesAsync(['ganache', 'postgres']);

This will use the docker compose file to start the services specified in the argument.

The function returns a handle to a function that will shut down the services.

Adding a dependent service

  • Add the service to docker-compose-test.yml
  • Update test/test_utils/deployment.ts to support the dependency
    • Update waitForDependencyStartupAsync with the log line that indicates that the service is up

Writing new tests

Tests files live under the test directory and must end with _test.ts or Test.ts.

Each file should have a top level describe block with the name of the test suite.

Snapshot testing

Snapshot testing is a technique where, instead of making individual assertions about a test result, you commit a "snapshot" of the test result to a file, then assert that the test result matches the snapshot.

This can be beneficial when the result of a test is complex; for instance a large server response.

A snapshot test can replace

expect(appResponse.body.price).to.equal(expectedPrice);
expect(appResponse.body.type).to.equal(RfqmTypes.OtcOrder);
expect(appResponse.body.orderHash).to.match(/^0x[0-9a-fA-F]+/);
expect(appResponse.body.order.maker).to.equal(MARKET_MAKER_2_ADDR);

with

expect(appResponse).toMatchSnapshot();

Read more at https://jestjs.io/docs/snapshot-testing