Automated Testing - rorymacleod/Toolbox GitHub Wiki
Tests can be categorised into two types:
Acceptance tests
Acceptance tests take the customer's requirements, expressed as acceptance criteria, and maps them to automated tests that execute the application from end-to-end, the way a user would, in a production-like environment. For a web application, this might involve using tools like Cypress or Selenium to open a browser. For a web API, the tests might make HTTP calls to the endpoints.
As many of the application's external dependencies as possible should be in place, and used during the tests. There could be limits on what dependencies can be used based on whether test environments are available, or how those systems will handle a large volume of randomised test data being inserted.
By basing the acceptance tests on the customer's acceptance criteria, the goal is not to cover 100% of the code, but to cover 100% of the customer's requirements.
Test class structure
Test environment
Test isolation
Unit tests
Unit tests target the application's business logic, skipping the UI, and mocking any external dependencies. "Unit" should be interpreted as referring to a unit of work, not (as is typically seen in examples of unit tests) a single class or method. Each test should apply inputs to the business layer's entry points, assert against any return values or calls to dependencies, and treat everything in-between as implementation details. In fact, for refactoring to be possible, it is imperative that the implementation can be changed without touching the tests. This avoids the common problem of brittle tests suites that to be extensively rewritten every time a class is refactored.
The goal for the unit test suite is to cover 100% of the application's business logic.