3

In TDD you write the smallest unit of code to make your test pass.

For example if building a Stack object you will want to test the push and pop methods. That is pretty straightforward. Those are both small units that can be tested in isolation. No external dependencies. It is about that object and what it does.

This is not the world though. Most objects depend on a lot of other objects. Those object might be filled from a service call or DB queries.

I know that use of Mocks, Stubs and Fakes can help here but also have limitations and pitfalls such as mocking too much which essentially lets test pass no matter what.

There is also integration testing that can make sure databases and services are all still integrating as expected but this is a step above unit-tests from my understanding. From what I have gathered this could be in a dev environment over a local.

Overall it would seem the act of removing these dependencies would be more work than it is worth almost. Which could lead to over-engineered test-suites.

Edit (including title)

Rather then understanding what the smallest unit is (the method thanks Robert) It appear my question is more:

  • Where does unit-testing end and integration begin?
  • For example is an integration test written by the developer like a unit test and then ran on the local with a test suite?
  • If that is the case then how can someone distinguish between a unit test and integration tests or should they?
  • Should unit-test and integration testing all be running at the same time?
15
  • 1
    Actually, the least over-engineered test suite is the one that tests code requiring the smallest number of dependencies. This should be self-evident: the fewer dependencies there are, the less mocks, stubs and fakes you have to use. The whole point of TDD is to force you to think this way: is my code readily testable? Commented Aug 9, 2016 at 16:42
  • @RobertHarvey That is what is puzzling me. To create a well engineered test suite you need to know the smallest unit. But with all the other dependencies it seems like to get a test-suite a developer would spend more time on Mocks and such to get it to work. How can someone make code that is readily testable with all the external calls.
    – nerdlyist
    Commented Aug 9, 2016 at 16:48
  • The smallest unit is generally a method. Commented Aug 9, 2016 at 16:49
  • The point is that in TDD you write the test first and then the code. Since you are obviously not willing to write an overly complex testsuite, you will write a simple test with few dependencies, and this test will then force you to write well-designed, encapsulated code. Commented Aug 9, 2016 at 16:50
  • 1
    That's where integration tests come in. Commented Aug 9, 2016 at 16:59

2 Answers 2

6

Where does unit-testing end and integration [testing] begin?

Integration testing begins when you allow the units (methods) to talk to each other through their natural dependencies, and not to stubs, mocks or fakes.

is an integration test written by the developer like a unit test and then ran on the local with a test suite?

It can be. It can also be a command line test, a batch file, or the actual application automated through some tool like Selenium.

If that is the case then how can someone distinguish between a unit test and integration tests or should they?

You distinguish between a unit test and integration test by observing whether mocks or real dependencies are being used in the test.

The distinction between a real database or service and a mocked one is an important one. Mocking only demonstrates that the method under test behaves as you expect it to in isolation. It might have significantly different behavior when executed within the context of its actual operating environment.

Should unit-test and integration testing all be running at the same time?

Test methods should always be written in such a way that each one can be executed independently of the others. Most test frameworks allow more than one test to be run concurrently.

1
  • Would it make sense to hold off on integration testing until deploying to another environment like dev?
    – nerdlyist
    Commented Aug 9, 2016 at 18:07
0

I'll try and answer your bullet points.

•Where does unit-testing end and integration begin?

As soon as one starts development. Keep tests focused. Know when a unit test is a good choice versus an integration test. Try and isolate your business logic so that unit tests can be written easily with a minimum amount of mocking/faking/stubbing.

•For example is an integration test written by the developer like a unit test and then ran on the local with a test suite?

Yes, they can be run like unit tests. For integrations tests, you can run them locally pointing to your local environment or the lowest environment in your stack. Typically these would be done/run by the developer to ensure the code works with real data and real services.

•If that is the case then how can someone distinguish between a unit test and integration tests or should they?

Yes, one should distinguish. With most testing frameworks this is easy with additional testing attributes.

[Test]
[Category=Unit]

[Test]
[Category=Integration]

Your team would come up with the categories.

•Should unit-test and integration testing all be running at the same time?

No, unit tests are run during the build on the build machine and integration tests are run post deployment on an environment. If one categorizes each test, the test runner can be configured only to run a certain suite of tests.

If a unit test fails, the build should fail. If an integration test fails, there may be issues with the environment or code. One should not deploy the code to a higher environment until the issue is identified and resolved.

As mentioned earlier, integration tests can be triggered manually by the developer to verify code correctness with actual service calls, but for automated scenarios=> build=unit tests : deployment=integration tests

4
  • What is the purpose of the category taggings? Why would it be important to know this at the coding level? Wouldn't it be apparent through visual inspection of the code? Why not simply put integration tests into their own namespace, if the distinction is that important? Commented Aug 9, 2016 at 17:32
  • @Robert - Yes one should know whether it is a unit test or integration test by looking at the code. It is not that important from a coding level, but when running the tests in an automated fashion it is important. For example, when doing a build if I only want to run the unit tests I could do: nunit-console-x86 /include:Unit and then only the unit tests run based on categorization of tests. This is an nUnit example, but the technique can be applied in a similar fashion to other tools/technologies.
    – Jon Raynor
    Commented Aug 9, 2016 at 17:41
  • It's an interesting idea, but if I wanted that behavior I would simply put my unit tests and integration tests each in their own container. Commented Aug 9, 2016 at 17:43
  • @Robert - True, that would be ideal separation but many times I have seen integration and unit tests in the same code file/namespace so tagging them is really the only way to identify/separate them.
    – Jon Raynor
    Commented Aug 9, 2016 at 17:47

Your Answer

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

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