Background:
Initially, automated tests were often written "in a straightforward manner", without architectural separations: verification logic and execution mechanisms were mixed together. As projects grew, it became evident that mixing the framework and test logic created a brittle, hard-to-maintain codebase. Architectural recommendations for separating responsibilities emerged.
Problem:
If tests depend on the internal implementations of the framework or include logic to interact with the environment, any changes would force a rewrite of numerous tests. Test cases become complex, code gets duplicated, and migrating to a new framework or platform becomes difficult.
Solution:
Strictly separate:
Key features:
Is it okay to write test steps directly in tests if there are very few of them?
No. Even short tests can grow, and the absence of layers will quickly lead to chaos.
Should test scenarios be aware of the execution mechanics (e.g., when to initialize the driver)?
No. All infrastructure details should be hidden within the framework layer.
Is it normal to hardcode test parameters within cases (e.g., URL, credentials)?
No. Test parameters should be configured via the framework and environment settings.
In the project, tests directly call Selenium driver methods, and each test repeats the connection to WebDriver. Each test independently parses the config.
Pros:
Cons:
Tests use the framework's basic abstractions: common initialization and teardown, parameter passing through a configurator, test logic expressed through high-level methods.
Pros:
Cons: