Testing - fidransky/kiv-pia-labs GitHub Wiki

TOTD:

  • learn about test pyramid and different test types
  • implement unit, integration and e2e tests of our bikesharing app

Terms and theory

Automated vs. manual tests

Generally, testing is repetitive, boring and prone to false-positives/false-negatives when done manually. To make testing more manageable, tests are (ideally fully) automated.

Test pyramid

The test pyramid is a way of thinking about how different kinds of automated tests should be used to create a balanced portfolio.

the test pyramid is a way of thinking about how different kinds of automated tests should be used to create a balanced portfolio

Unit tests

Unit tests are fast to write and quick to execute, therefore cheap.

In Java, following test libraries are commonly used:

In unit tests (as their name suggests), we test individual units of code. When given unit depends on other unit(s), those dependencies are typically mocked and tested separately.

In Java, following mock libraries are commonly used:

Integration tests (ITs)

In integration tests, we test how individual units work together. Here, integration often has different meanings to different teams.

  • Are tests which require DI container unit or integration tests?
  • Are user interface tests with mocked database integration tests or end-to-end tests?
  • ...

Integration tests are slower to author and to execute. As a result, there shouldn't be as many integration tests in your app as there are unit tests.

In Java, following integration test libraries are commonly used:

End-to-end tests (e2e tests)

End-to-end tests run similar scenarios as real clients, either using actual browsers or API calls. In both cases, a whole app is typically running and serving test requests.

Following e2e testing tools are commonly used (not only in Java):

Practice

1. Configure environment

Add maven-surefire-plugin and maven-failsafe-plugin to bikesharing-core and bikesharing-repository-jdbctemplate submodules. Learn about their differences here.

2. Implement core unit tests

Use JUnit Jupiter and Mockito to implement unit tests of core services.

Add org.junit.jupiter:junit-jupiter, org.mockito:mockito-core and org.mockito:mockito-junit-jupiter dependencies to core and implement unit tests of StandService using Mockito to mock and inject StandRepository.

3. Implement JDBC integration tests

Use Spring TestContext Framework and Testcontainers to implement integration tests of JDBC implementation of repository interfaces.

Add org.springframework:spring-test dependency together with Testcontainers dependencies to bikesharing-repository-jdbctemplate submodule.

Use Testcontainers to start MySQL container in Docker prior to running integration tests of JdbcTemplateStandRepository implementation.

4. Implement web end-to-end tests

Use Playwright to implement e2e tests of the web user interface.

In the src/test/resources/ folder of the bikesharing-ui_ submodule, initialize Playwright test environment:

npm init playwright@latest

Then, start the app and run the following command to start Playwright Codegen:

npx playwright codegen localhost:8080

Copy the generated Playwright code to initialized tests/example.spec.ts file, edit it to actual do some assertions and execute the tests:

npx playwright test

Sources