Explore my works and
side projects  here

Research, Design & Development.

unit tests

by

Unit testing is a crucial practice in software development that helps ensure the reliability and maintainability of your code. Here are some best practices for writing and organising unit tests:

1. Follow the Arrange-Act-Assert (AAA) Pattern:

  • Arrange: Set up the necessary preconditions.
  • Act: Perform the action you want to test.
  • Assert: Verify that the expected results occurred.

2. Keep Tests Independent:

  • Ensure that each test is independent of others. The order of execution should not affect the outcome.

3. Use Descriptive Test Names:

  • Write clear and descriptive names for your test cases. A good test name should explain what the test is doing and what is expected.

4. Test One Thing Per Test Case:

  • Each test should focus on a specific behavior or functionality. This makes it easier to identify the cause of failures.

5. Use Before and After Hooks Sparingly:

  • Utilize beforeEach and afterEach hooks when needed, but be cautious as they can introduce hidden dependencies between tests.

6. Mock External Dependencies:

  • Use mocks, stubs, or spies to isolate the code under test from external dependencies. This ensures that the tests focus on the unit of work.

7. Run Tests in Isolation:

  • Ensure that tests do not rely on external state or the order in which they are executed.

8. Test Edge Cases:

  • Test not only typical use cases but also edge cases and boundary conditions to ensure your code handles all scenarios.

9. Regularly Refactor Tests:

  • Just like production code, refactor your tests as the codebase evolves. Keep them clean and maintainable.

10. Use a Testing Framework:

  • Choose a testing framework such as Jest, Mocha, or Jasmine to simplify test organization, execution, and reporting.

11. Run Tests Automatically:

  • Integrate your tests into your continuous integration (CI) pipeline to ensure that tests are run automatically with every code change.

12. Keep Tests Close to the Code:

  • Place your tests in the same directory or a parallel directory structure as the code they are testing.

13. Use Code Coverage Tools:

  • Monitor code coverage to identify areas of your codebase that lack test coverage. Tools like Istanbul or Jest’s built-in coverage can help.

14. Review and Refactor Tests:

  • Regularly review your tests with the same rigor as your production code. Refactor tests for clarity and maintainability.

15. Write Readable Assertions:

  • Use assertion libraries that provide clear error messages when a test fails. This helps in quickly identifying the issue.

16. Be Mindful of Asynchronous Code:

  • If your code involves asynchronous operations, make sure to handle them appropriately using tools like async/await or promises.

17. Document Your Tests:

  • Include comments or documentation in your test code to explain the purpose of the test, especially if the intent is not immediately obvious.

18. Learn from Failures:

  • When a test fails, take the time to understand why. Use failures as an opportunity to improve both your code and your tests.

Adhering to these best practices will contribute to the effectiveness and maintainability of your unit tests in code.


Code to be Tested (math.js):

// math.js

function add(a, b) {
  return a + b;
}

module.exports = { add };


Unit Tests (math.test.js):

// math.test.js

const { add } = require('./math');

describe('add function', () => {
  test('should add two numbers correctly', () => {
    // Arrange
    const num1 = 3;
    const num2 = 5;

    // Act
    const result = add(num1, num2);

    // Assert
    expect(result).toBe(8);
  });

  test('should handle negative numbers', () => {
    // Arrange
    const num1 = -2;
    const num2 = 7;

    // Act
    const result = add(num1, num2);

    // Assert
    expect(result).toBe(5);
  });

  test('should handle zero', () => {
    // Arrange
    const num1 = 10;
    const num2 = 0;

    // Act
    const result = add(num1, num2);

    // Assert
    expect(result).toBe(10);
  });
});


Running the Tests:

With Jest you can run the tests by executing the following command:

npx jest


Jest will discover and execute the tests, providing clear feedback on whether each test passed or failed. The output will also include coverage information if you have configured Jest to collect code coverage.

This is a basic example, but it illustrates the AAA pattern, descriptive test names, and the use of the Jest testing framework. Depending on your project and requirements, you may need to configure Jest further, use additional testing libraries, or employ different testing strategies.

There are several JavaScript libraries and frameworks for unit testing. Each has its own strengths and is suitable for different use cases. Here are some popular JavaScript unit testing libraries:

  1. Jest:
    Developed by Facebook, Jest is a popular and widely-used testing framework. It comes with built-in assertion libraries, mocking capabilities, and supports parallel test execution. It’s easy to set up and is commonly used for testing React applications.
  2. Mocha:
    Mocha is a flexible testing framework that supports both asynchronous and synchronous testing. It provides a clear and simple syntax and can be used with various assertion libraries like Chai. Mocha is often used for testing Node.js applications.
  3. Chai:
    Chai is an assertion library that works well with Mocha, but it can also be used with other testing frameworks. It offers a variety of assertion styles, including BDD, TDD, and exports functions for both Node.js and the browser.
  4. Jasmine:
    Jasmine is a behavior-driven development (BDD) framework that doesn’t require any external libraries for assertions. It has a clean syntax and is suitable for both frontend and backend testing.
  5. Enzyme:
    Enzyme is a testing utility for React developed by Airbnb. It works well with Jest and Mocha and provides additional utilities for testing React components. Enzyme is especially useful for testing component rendering and behavior.
  6. AVA:
    AVA is a minimalistic testing framework that runs tests concurrently to provide faster results. It has a simple syntax and is designed to be easy to use. AVA is often chosen for its speed and simplicity.
  7. QUnit:
    QUnit is a JavaScript unit testing framework developed by the jQuery team. It’s lightweight and easy to set up, making it a good choice for testing JavaScript code in the browser. QUnit is particularly well-suited for testing jQuery plugins.
  8. Sinon:
    While not a testing framework on its own, Sinon is a powerful library for creating spies, stubs, and mocks. It can be used alongside other testing frameworks to simulate and control function behavior, making it a valuable tool for testing.

When choosing a testing library, consider factors such as ease of use, community support, integration with other tools, and compatibility with your project’s requirements. Many projects use a combination of these libraries, depending on their specific needs and preferences.