11

In unit tests I'm always trying to test as many business cases as possible, trying to reach 100% code coverage. Unit tests are great and pretty simple because all tests are made in isolation.

Absolutely opposite situation with integration tests - it is a real pain, because we need to work with real data storages (DB, logging, cache, etc.).

Should we test business logic in integration tests or not? Sometimes testing all possible cases with integration tests seems to be absolutely impossible.

What's your opinion - should integration tests test business logic or not? If no, then what should they test? Are there any samples of unit testing and integration testing the same piece of code?

2 Answers 2

11

No if it can be done in Unit tests

The answer however is not a yes / no as this is not really a binary choice.

When possible use Unit tests. If you are testing 'based on this information from this interface...", i.e. business logic, then you can mock or stub that interface to provide that specific data for that condition.

In many organizations not all services can easily be mocked however and there are inter relationships that can't easily be avoided. Using programmatic approaches to mock and stub services, set up proxy servers, etc. also requires technical knowledge that may not be present in the organization, especially within many traditional testing organizations.

In these cases I recommend following two principles:

  • Use the Agile testing pyramid as a guide to the volume of test cases
  • Focus on happy/positive tests and a small number of sad/negative integration test cases

I recommend that each time you want to test business logic, you follow the route of

  • many unit tests for positive and negative cases
  • some integration tests to make sure systems can talk to each other
  • some integration tests to make sure systems can handle other system being down
  • fewer automated UI tests to ensure the end user experience works
  • a small amount of exploratory testing to catch unknowns and stay humble

Remember that the point of integration testing is specifically to test the integration between systems and is needed because unit tests use mocks and stubs.

One approach for integration tests is for them to simply verify the method signatures (names and params) for the public methods and interfaces to ensure they have not changed. This can be done without complex integration tests requiring domain knowledge.

Another approach is to actually use the same set of tests with one run using mocks and stubs to run in unit test mode, the other run using real dependencies. This can have the advantage of less maintenance.

One point of note for integration tests is that they test the interface between systems - or sometimes between parts of the same system. Their data can be from the real interfaces, or from an interfaces that you supply ('data for pre-made answers'). When you control the interface you may be able to use grey box testing where you can create data conditions you need, by faking out the service and providing the response. The main consideration here is that foreign systems will eventually change and sometimes it will be unknown / unexpected / unannounced and usually seem to be at the worst time. This is why a combination of tests for both fake and real sources may be the best solution.

See What is really tested in an integration test?

See How to do integrated testing?

See What's the recommended practice for separating unit tests from integration tests for automated testing?

6

I think you fell on the Integrated Tests scam.

Integration tests are about "determining if independently developed units of software work correctly when they are connected to each other".

Legos can be a metaphor for it:

Let's say you want to create a big block, half blue, and half red. You can make these independent checks if:

  1. The first half is blue;
  2. The second half is red;
  3. You check if the two blocks can be connected (regardless of their colors).

Only the third check is about the integration, and notice that it doesn't matter the "behavior" of each block, only their "interfaces", "their I/O". It means that the number of checks grows linearly to the number of components, not exponentially as in the case of the Integrated Tests strategy.

enter image description here

In terms of software, we are talking about Interfaces Adapters, not the Business Rules.

enter image description here

If we look at Consumer-Driven Contract Testing, e.g. in Pact, one only needs to extract the expected interactions from the data Consumer (on their Client objects) and check if the data Provider can give this data (on their Controllers). There is no need to boot up both components in the same environment.

enter image description here

2
  • 1
    Already decided to upvote when I saw "lego". rest of it confirmed the vote :) Sep 27, 2021 at 14:22
  • From integrated tests are a scam: Integrated tests pose a significant risk to the health of your code base. If you’re not careful, accumulating integrated tests will gradually suffocate your code base, I doubt that this is always the case. We are using an external web api and some edge case are sometimes erroneous. To be aware that edge cases are broken we will implement some testcases to verify that the api sends the expected values.
    – surfmuggle
    Feb 28 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.