Skip to content

Testing

Wei Zhe edited this page Dec 10, 2024 · 6 revisions

Backend testing ensures that the various components of the voting system, such as routes, helper functions, and models, perform as expected. The goal of backend tests is to validate that the voting system's core functionalities are reliable and secure before deployment.

Tests can be found in the __tests__ folder, with a structure that mirrors the src folder.

Testing Approach

The backend testing is divided into the following categories:

1. Route Testing

Route testing ensures that the API routes of the voting system respond correctly to requests. These tests simulate HTTP requests to the system’s endpoints and verify:

  • Correct HTTP status codes (e.g., 200 OK, 400 Bad Request, 404 Not Found)
  • Proper handling of request data and response formats
  • Validations for request parameters and payloads
  • Error handling and edge cases
  • Authentication and authorization checks (e.g., role-based access control)

2. Model Testing

Model tests verify that the system's database models are functioning correctly. These tests are written to check:

  • Database interactions (CRUD operations)
  • Error handling when database request fails

3. Helper Function Testing

Helper functions provide utility services to other parts of the system. Testing these functions ensures that they:

  • Perform the expected calculations and transformations (e.g., vote count aggregation, result formatting)
  • Handle edge cases and error scenarios gracefully
  • Return correct values based on given input

Unit Testing

Unit testing focuses on verifying individual components of the backend in isolation. For each component, unit tests are written to validate the smallest, independent parts of the system, including routes, models, and helper functions.

1. Unit Testing of Routes

Each route is unit tested individually by simulating requests and validating responses. Stubs are used to mock any external dependencies, such as database interactions, to ensure that the route's behavior is tested in isolation.

2. Unit Testing of Models

Models are tested in isolation, with stubs used for database interactions. This allows for testing model behavior, such as data validation, CRUD operations, and associations, without connecting to an actual database.

3. Unit Testing of Helper Functions

Helper functions are unit tested to ensure that they perform as expected under different scenarios. Stubs are used to isolate the functions from other components of the system, enabling focused tests on their functionality.

Integration Testing

Integration testing ensures that different components of the backend work together as expected. The goal is to verify that the system's components integrate correctly, starting from the lowest-level components (models) and progressing to higher-level components (helpers, routes).

1. Model and Database Integration

In the first stage of integration testing, the models are integrated with the database. This includes ensuring that CRUD operations are functioning correctly with an actual database, and validating that data is correctly persisted and retrieved.

2. Integration of Models with Helpers

Once the models are integrated with the database, the next step is to test how models interact with helper functions. This ensures that data processing and transformations are correctly handled when integrating with other system components.

3. Integration of Helpers with Routes

Finally, integration tests are written to ensure that routes work correctly with the helpers. This ensures that when a route makes use of helper functions (such as vote count aggregation or result formatting), the entire flow from route to helper is functioning correctly.

Test Case Creation

Test cases for the backend are created with the following guidelines:

  1. Set Up and Teardown: If multiple test cases use the same set up or tear down code, use the appropriate beforeAll, beforeEach, afterAll, afterEach` hooks provided by jest.

  2. Organization: Use describe blocks to logically group test cases for the same function.

  3. Isolate Tests: Each test case is designed to be independent, meaning it does not rely on other tests and can run in isolation. This is achieved by using mock data and database seeding to set up the necessary state before each test.

Tools and Libraries Used

  • Jest: A testing framework used for writing unit and integration tests.
  • Supertest: A tool for making HTTP requests and testing API routes.

Running Tests

First ensure that the database is properly seeded.

To run the backend tests, use the following command:

npm run test

Test Environment

Tests are run in an isolated environment to ensure consistency and avoid interfering with the production data. The following steps are taken to prepare the testing environment:

  • A dedicated test database is used, which is reset before each test run.
  • Mocking is used to simulate external services or dependencies where needed.

NUS Skylab v2 - Backend

Introduction

Project Organization

Project Requirements

Endpoints

Clone this wiki locally