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.
Unit tests
Unit tests are fast to write and quick to execute, therefore cheap.
In Java, following test libraries are commonly used:
- JUnit
- TestNG
- KoTest
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:
- Mockito
- EasyMock
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