Automated Testing (IT)Automation QA Lead

How to implement automation testing of business logic in complex, multi-level applications so that tests remain stable during changes in architecture and requirements?

Pass interviews with Hintsage AI assistant

Answer.

Automation testing of business logic in complex applications has a long history, starting from the first scripts for validating validators to modern microservice tests. As the architectures have become more complex (monolith, SOA, micro- and macroservices), a problem has arisen: changes at one level of architecture often break tests at other levels.

The problem lies in the need to write tests that are resilient to the reorganization of interactions between the layers of the application: changing contracts, data structures, and business processes. Often, tests are tied to implementation details, making them "fragile" and difficult to maintain.

The solution is to build tests according to the "black box" principle, focusing on input/output data, using layers of abstraction to access system entities (e.g., Service Layer and Domain Layer in architecture). It is essential to separate business logic from infrastructural details and use mocks/stubs for external dependencies to ensure isolation and stability of tests.

Key features:

  • Emphasis on testing contracts: verifying business invariants independent of internal implementations.
  • Using layers of abstraction to access logic (e.g., Application Service → Domain Service → Repository).
  • Implementing MVP/mocks/stubs for reproducibility and isolation of the testing environment.

Trick questions.

What is the difference between testing business logic through the UI layer and testing through the API/Domain Layer?

UI tests are often less resilient to changes since even minor changes in the interface lead to test failures. Tests through the API or Domain Layer depend less on the front end and more successfully isolate the verification of business rules.

Do we need to mock all dependencies of business logic for testing them?

No! It is not necessary to mock what can be implemented in the testing environment (e.g., lightweight memory instead of a database). Mocks are needed for complex, expensive, or external dependencies. Complete mocking can lead to "fake" tests that do not reflect real scenarios.

Is testing only positive scenarios sufficient for business logic?

No! It is crucial to cover all corner cases and negative scenarios; otherwise, critical errors will go unnoticed, leading to vulnerabilities in the main business process.

Common mistakes and anti-patterns

  • Tying tests to internal objects/structures, fragile selectors.
  • Lack of negative/alternative paths.
  • Multiple duplicate tests with minor variations.

Real-life example

Negative case

In a project, business logic was tested only through UI Selenium tests, directly interacting with buttons and forms. Each frontend refactor led to mass test failures.

Pros:

  • Quick initial coverage of all functionality
  • Easy to explain the essence of scenarios to management

Cons:

  • Fragility: even a slight change in UI breaks everything
  • Slow, unstable tests, hard to maintain

Positive case

In the project, a layer of API and unit tests was implemented. The UI covered only critical paths, while all other validation occurred through the service layer with mocking of expensive services.

Pros:

  • Resilience — changes in UI do not affect business logic tests
  • Speed: API and unit tests run significantly faster
  • Reliability of checking only business logic

Cons:

  • Requires more technical expertise
  • Integration between layers is not always visible in isolation