Jest Testing
what is Jest ?
Jest is an open-source testing framework built on JavaScript, designed majorly to work with React and React Native based web applications. Often, unit tests are not very useful when run on the frontend of any software. This is mostly because unit tests for the front-end require extensive, time-consuming configuration. This complexity can be reduced to a great extent with the Jest framework.
Why we use Jest ?
- Zero configuration required.
- Fast: Jest tests run in parallel – this in turn greatly reduces the test execution time.
- Built-in code coverage: Jest supports code coverage out of the box – this is a very useful metric for all CI-based delivery pipelines and overall test effectiveness of a project.
- Isolated and sandboxed tests: Each Jest test runs in its own sandbox, which ensures no two tests can interfere or impact each other.
- Powerful Mocking support: Jest tests support all types of mocking – be it functional mocking, timer mocking, or mocking individual API calls.
- Support snapshot testing: Snapshot testing is relevant from the React perspective. Jest supports capturing a snapshot of the react component being tested – this can validate with the component’s actual output. This greatly helps in validating the component’s behavior.
- Powerful, interactive CLI
Test Coverage Overview
Integration Tests
We use Jest for our API integration tests. This ensures that any changes made to the codebase do not break functionality in applications that rely on these APIs.
Here is an overview of the current test suites:
metadata.test.js
-
Purpose:
Validates the correctness and integrity of the metadata used across the APIs. This suite is foundational, as other test files depend on accurate metadata. -
What it covers:
- Metadata structure validation
- Snapshot consistency checks
-
When to run:
After generating or updating metadata, before executing other test suites.
full-crud-as-admin.test.js
-
Purpose:
Tests the full Create, Read, Update, Delete (CRUD) lifecycle of resources with admin privileges. -
What it covers:
- Creating new resources
- Retrieving resource details
- Updating existing resources
- Deleting resources
-
When to run:
To ensure core administrative operations function as expected.
negative.test.js
-
Purpose:
Ensures the API correctly handles invalid, unauthorized, or malformed requests. -
What it covers:
- Rejection of malformed requests
- Access control enforcement
- Input validation and error handling
-
When to run:
To verify the API handles edge cases and security boundaries reliably.
login-cas.test.js
-
Purpose:
Validates the authentication and authorization flows using the CAS (Central Authentication Service). -
What it covers:
- Successful login via CAS
- Token issuance and validation
- Authenticated access control
-
When to run:
After changes to authentication mechanisms, identity provider configurations, or session handling logic.
Metadata Generator
Before running tests, you need to fetch the metadata for each API. Most test assertions rely on this metadata to determine expected behavior.
For example, creating a valid entity requires knowing which properties are required in the request—this information comes from the metadata. Since metadata doesn’t change frequently, it makes sense to cache it locally. This way, it’s only fetched once rather than during every test run, which significantly improves test performance and reduces unnecessary load on the API.
Build metadata for a specific API
Replace <target_API> with the name of the API you want to build metadata for:
npm run build:metadata:<target_API>Build metadata for all APIs
To generate metadata for all available APIs at once:
npm run build:metadata:allList available APIs
To see all supported API targets:
npm run list:build:metadataExample: Generate metadata for the PHPR API
npm run build:metadata:phprUsage
Build the image and run the container
Use docker-compose to build the Docker image and start the container for testing:
docker-compose up -dThe resulting container image should be approximately 234 MB.
Attach to the container
To easily attach to the container, use the ./exec utility. It opens a shell session inside the container:
./execUpdating snapshots
Jest compares the body of received responses against stored snapshots. If the API changes, the new responses might not match the existing snapshots, causing tests to fail — even if the new behavior is correct.
To update the snapshots:
npx jest --updateSnapshotRunning tests
To run all tests:
npm test
# or
npx jestRunning a specific test suite (file)
Use the -f flag to run a specific test file:
npx jest -f path/to/file.test.jsRunning a specific test
Use the -t flag to filter and run tests matching a regex pattern:
# Run only the tests related to the 'product' entity
npx jest -t product
# Run only the listing tests
npx jest -t listing⚠️ Note: Some test suites are designed to run sequentially. For example, in the full CRUD test suite, the test that deletes an entity expects the entity to have been created first. Running only part of the suite may lead to failed tests. For the most accurate results, run the full test suite.
Jest Watch Mode
For an improved developer experience, you can use Jest’s watch mode to run tests interactively:
-
Use the
./execscript to enter the container:./exec -
Then run Jest in watch mode:
npx jest --watchAll
Watch mode allows Jest to rerun tests as files change and provides an interactive menu:
Watch Usage
› Press a to run all tests.
› Press f to run only failed tests.
› Press o to only run tests related to changed files.
› Press p to filter by a filename regex pattern.
› Press t to filter by a test name regex pattern.
› Press u to update failing snapshots.
› Press i to update failing snapshots interactively.
› Press q to quit watch mode.
› Press Enter to trigger a test run.You can also filter by test name using the t key:
Pattern Mode Usage
› Press Esc to exit pattern mode.
› Press Enter to filter by a tests regex pattern.
pattern › productTyping product will run only the tests with matching names:
PASS ./full-crud-as-admin.test.js
CRUD integration tests
Full Integration tests for bill_distributiontypes
○ skipped bill_distributiontypes listing
○ skipped bill_distributiontypes dropdown
○ skipped bill_distributiontypes POST with invalid body
○ skipped bill_distributiontypes POST new ressource
○ skipped bill_distributiontypes new ressource is in listing
○ skipped bill_distributiontypes new ressource is in dropdown
○ skipped bill_distributiontypes listing with ID query strings
○ skipped bill_distributiontypes listing with slug query strings
○ skipped bill_distributiontypes show new created entity
○ skipped bill_distributiontypes change new created entity
○ skipped bill_distributiontypes show new modified entity
○ skipped bill_distributiontypes DELETE new ressource
○ skipped bill_distributiontypes listing with removed entity
○ skipped bill_distributiontypes dropdown with removed entity
○ skipped bill_distributiontypes show on deleted entity
Full Integration tests for products
✓ products listing (459 ms)
✓ products dropdown (108 ms)
✓ products POST with invalid body (149 ms)
✓ products POST new resource (203 ms)
✓ products new resource is in listing (381 ms)
✓ products new resource is in dropdown (148 ms)
✓ products listing with ID query strings (143 ms)
✓ products listing with slug query strings (138 ms)
✓ products show new created entity (206 ms)
✓ products change new created entity (367 ms)
✓ products show new modified entity (192 ms)
✓ products DELETE new resource (172 ms)
✓ products listing with removed entity (516 ms)
✓ products dropdown with removed entity (147 ms)
✓ products show on deleted entity (130 ms)
Test Suites: 1 passed, 1 total
Tests: 91 skipped, 15 passed, 106 total
Snapshots: 2 passed, 2 total
Time: 4.281 s, estimated 16 s
Ran all test suites with tests matching "product".