Unit Testing

In previous post I covered code coverage and made a concrete example with unit tests in java. In this post, I would like to get a bit more into what unit tests are.

What is Unit testing

unit testing is a method of software testing, where individual units of the source code is tested. A unit can be a complete module or function ( procedural programming), or a class or method ( object-oriented programming). Unit test allows to test and find issues early in the development lifecycle, as input, output and error behavior of a unit, are usually clear for a developer, when she writes the code. In addition, it also helps developers to think and improve the design of their units. The idea is, to test the unit in isolation, to ensure it’s proper function. This may not always be that simple, as some units may depend on other units, external data or states. This will require the use of mocks/ stubs, to satisfy these external dependencies and simulate their behavior.

Unit tests are available for the most known programming languages, which each offers it’s own unit test framework or test harness, which may offer more than just executing the tests, but also thinks like

  • setup and teardown of test data or test environments - also called a [test fixture]
  • parametrization of tests, where a test is executes with different data
  • test reporting

The methodology test driven development is a practice which has been established and used by developers. It improves the thinking process about the requirements and before writing the actual code. It basically goes like this

  1. Write the skeleton of your unit
  2. Write a test case for the unit, based on the requirements/specifications
  3. Run the test against the unit - all test should fail with expected results, as no functionality has been implemented yet
  4. Add code to your unit, which make your test pass
  5. Run the test against the unit - this time the tests should pass
  6. Refactor your code and improve it - if you re-run your tests, they still should pass as the expected input and output are still the same
  7. Repeat: If requirements/specification changes, you first will adjust your test cases and then update the unit.

This approach should also help the developers to keep the units small, so the debugging is easier.

How to write a good unit test?

Unit tests are here to give you fast feedback, so good unit tests should be

  • fast: as there are a lot of tests (thousands) they should take very little time (ms) to run
  • isolated: unit tests run in isolation and should not have any dependency to other test or external factors like services
  • repeatable: unit tests shall always give the same result, when there are no changes between the runs

But this is not all, important is that you understand what your are building i.e. have proper specifications and requirements.

Beyond unit tests

To be clear, even so you have a very good unit testing, this is not sufficient for testing an entire application/system. Some errors may not be detected as you cannot evaluate every execution path of the whole software. Using mocks just simulates the behavior of an external element but may not fully represent it’s real behavior. That’s wgy you also need integration tests, as well as manual tests, in addition to your unit tests.

The following post give you more details on: