Unit Frontend Component Tests
Testing Frameworks and Tools
Framework Details
Jest is the testing framework used
Babel is used It is used in this project to transform modern JavaScript and TypeScript code for testing purposes
Version Information
Jest:
29.7.0
Babel: Core version
7.22.20
with specific presets and plugins for React and TypeScript.
Setup and Configuration
Installation Instructions
Prerequisites
Node.js installed on your machine.
npm (Node Package Manager) available.
Install Project Dependencies
Navigate to the root directory of the project.
Run the following command to install all project dependencies, including those required for testing:
npm install
Install Jest and Babel Dependencies
npm install --save-dev jest babel-jest @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript
Jest Configuration
Configuration file: jest.config.js
// jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
transform: {
'^.+\\.[tj]sx?$': ['babel-jest', { configFile: './babel.config.jest.js' }],
},
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/$1',
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
'\\.(jpg|jpeg|png|gif|webp|svg)$': '<rootDir>/__mocks__/fileMock.js',
'^public/(.*)$': '<rootDir>/__mocks__/fileMock.js', // Added this line
},
transformIgnorePatterns: [
'/node_modules/(?!(jwt-decode|js-cookie|react-icons)/)',
],
// ... any other configurations
};
Preset and Environment
ts-jest: This preset is used to enable Jest to work seamlessly with TypeScript. It allows you to write tests in TypeScript and ensures that TypeScript code is properly compiled before testing.
jsdom: This test environment simulates a browser-like environment for testing purposes. It is particularly useful for testing React components and other code that interacts with the DOM.
Transformations
Babel is used to transform JavaScript and TypeScript code before running tests. The
babel-jest
package is specified in thetransform
configuration to handle files with.ts
,.tsx
,.js
, and.jsx
extensions. This ensures that modern JavaScript and TypeScript syntax is compatible with the test environment.
Setup Files
The
setupFilesAfterEnv
option specifies files that should be executed after the test environment is set up but before the tests are run. In this configuration,<rootDir>/jest.setup.js
is used to configure the testing environment, such as setting up global variables or configuring testing libraries.
Module Name Mapper
This configuration maps module paths and asset files to specific mock implementations. For example:
^@/(.*)$
maps to<rootDir>/$1
, allowing for simplified import paths.\\.(css|less|scss|sass)$
maps toidentity-obj-proxy
, which mocks style imports.Image and asset files (e.g.,
.jpg
,.png
,.svg
) are mapped to<rootDir>/__mocks__/fileMock.js
, providing a mock implementation for these files during tests.
Transform Ignore Patterns
The
transformIgnorePatterns
option specifies patterns for files that should not be transformed by Babel. In this configuration, the/node_modules/
directory is ignored, except for specific packages likejwt-decode
,js-cookie
, andreact-icons
, which are explicitly included for transformation. This ensures that these packages are compatible with the test environment.
These configurations help tailor Jest to work effectively with the project's TypeScript and React code, ensuring a smooth testing process.
Babel Configuration
Configuration file: babel.config.jest.js
|
|
---|---|
@babel/preset-env
@babel/preset-react
@babel/preset-typescript
| @babel/plugin-syntax-top-level-await
|
Test Organization and Structure
Directory Structure
root/tests/name.test.tsx or .ts
Writing Unit Tests
Test Structure
A typical test file in this project follows a structured format to ensure clarity and maintainability:
Imports: Import necessary libraries and components at the beginning of the file. This includes React, testing utilities from
@testing-library/react
, and any components or modules being tested.Mocks: Define any mocks needed for the test. This can include mocking components, functions, or APIs that the component interacts with.
Setup and Teardown: Use
beforeAll
,beforeEach
,afterAll
, andafterEach
hooks to set up and clean up any global state or configurations needed for the tests.Test Suite: Use
describe
to group related tests together. This helps organize tests and provides a clear context for each group of tests.Individual Tests: Use
test
orit
to define individual test cases. Each test should focus on a single aspect of the component's behavior.
Test Naming Conventions
Test Files: Name test files to reflect the component or module being tested. For example, if testing a component named
CopyButton
, the test file should be namedCopyButton.test.tsx
.Test Cases: Name test cases to clearly describe the expected behavior. Use a consistent format, such as "should [do something] when [condition]". For example, "button should be disabled when no content is provided".
Common Test Patterns
Setup and Teardown: Use
beforeEach
to reset mocks and any shared state before each test. This ensures that tests do not interfere with each other.Mocking: Use
jest.mock
to mock dependencies that the component interacts with. This can include components, functions, or APIs. In the provided test, theIconButton
component and the clipboard API are mocked.Assertions: Use assertions to verify that the component behaves as expected. Common assertions include checking if elements are present in the document, if functions are called with the correct arguments, and if the component's state changes as expected.
Async Testing: Use
waitFor
to handle asynchronous operations, ensuring that assertions are made after the component has updated.Timers: Use
jest.useFakeTimers
andjest.advanceTimersByTime
to test components that rely on timing functions, such assetTimeout
.
Running Tests
Command Line Instructions
To run tests in different environments, use the following commands. These commands are defined in the package.json
under the scripts
section, allowing for easy execution of tests in different environments and facilitating efficient local testing.
Development Environment: By default, running
npm test
will execute tests in the local development environment.Staging Environment: To run tests in the staging environment, use the following command. This sets the environment variable
NEXT_PUBLIC_APP_ENV
toSTG
.Production Environment: To run tests in the production environment, use the following command. This sets the environment variable
NEXT_PUBLIC_APP_ENV
toPROD
.Preferred Local Testing Command: When testing unit tests locally, it is recommended to redirect the output to a log file for easier analysis:
For production tests:
For staging tests:
This approach captures the test results and console logs in the jest-output.log
file, which is particularly useful when dealing with a large number of tests. It allows for easier troubleshooting and review of test outputs compared to viewing them directly in the terminal.
Continuous Integration
The unit tests are integrated into the CI/CD pipeline to ensure code quality and prevent regressions before deploying to staging or production environments.
Staging Pre-checks: The
pre-check-staging.yml
file defines a workflow that runs unit tests as part of the pre-checks when a pull request is made to thedev
branch. This workflow:Checks out the code and configures AWS credentials.
Sets environment variables and fetches secrets from AWS Secrets Manager.
Installs dependencies using
pnpm
.Runs the unit tests using the
pnpm run test:stg
command.If the tests pass, the workflow proceeds to build, tag, and push the Docker image to Amazon ECR.
Production Pre-checks: The
pre-checks-production.yml
file defines a similar workflow for themain
branch, running unit tests as part of the pre-checks for production releases. It uses thepnpm run test:prod
command to execute tests in the production environment.Release Approval: If any of the pre-checks, including unit tests, fail, the release is rejected. Otherwise, the release is approved, ensuring that only thoroughly tested code is deployed.