4 min read

Unit Testing

For me, the unit test is the most essential of all test stages. It is also the first thing I look at when I start a new consulting project. Why? This is where the robustness of the application is created. Without sufficient unit tests, stable integration, system and acceptance tests are difficult to achieve. Good unit tests help massively to ensure that the code remains consistent. Problems with the system becoming unstable due to changes or unexpected side effects can be minimized in advance with unit tests. And they are an excellent indicator of the quality of the architecture and design. A “unit test is not possible here” is a strong indication that potential trouble is lurking here. At the latest when refactoring this area, quality assurance in the form of tests is missing. Unit tests are an ideal feedback mechanism in software development.

If you change or extend the code, unit tests immediately provide feedback as to whether you have broken something. This, in turn, is the reason why unit tests must also be able to be executed quickly. If this is not possible, this is another indication to take another look at the architecture and design.

Definition Unittest

In the literature, the test level is defined as a component test and often appears under this term. Module test is also a common synonym. Of course, this also depends somewhat on the programming language and the context. In project practice, however, unit test has become established. I can’t remember a project in the last 20 years where this test stage was not called Unittest.

The ISTQB defines component testing as: “A test level focusing on a single hardware or software component.”

In general, you can say: Unittest is the test of the smallest unit. Whether this is called a module, class, instruction or something else.

Test base

All information that describes this small functional block serves as the test basis for the unit test. This can be information derived from the design or architecture, or parts of a user story or requirement. Sometimes there are also component specifications or models that describe the functionality of the unit.

Test case creation for unit tests

Structured test design methods such as equivalence class analysis, limit value analysis or decision tables are particularly suitable for creating test cases for unit or module testing. Also combinatorics such as pairwise or classification tree. Compared to other test levels such as system testing or acceptance testing, the advantage here is that value ranges, etc. are much more concrete, which makes it easier to derive test cases.

Agile software development has made Test Driven Development (TDD) very popular. The program code is not written first and then the test code, but vice versa. The test is written first, it fails, then the functional code is developed so that the test case becomes “green”. Further development takes place in this structure. TDD has many advantages, especially with regard to the focus on tests, but also a few disadvantages.

Test object

The test object for the unit test is the smallest unit of the respective programming language that can be meaningfully tested. The aim is to test this unit for itself, without interaction with other such units (classes, modules, etc.).

Test objectives of the unit test

The aim of the unit test is to test the functional and non-functional aspects at the lowest level. This has several advantages:

  • The tests create a robust foundation on which the other test levels and the entire architecture can build
  • Any errors that occur in the unit test can be rectified quickly and specifically due to the proximity to the code
  • Fast feedback mechanism when changes are made to the software.

The topic of code coverage comes up very often here. What is code coverage? Code coverage shows how much of the software source code is used when executing the test cases. Code coverage can target different parts of the code. A distinction is therefore made, for example, between statement coverage and branch coverage.

What is code coverage?

Code coverage is also often used as an end-of-test criterion or definition of done. Then you will find formulations such as “unit tests must have 80% code coverage”. Defining and measuring such figures is certainly an interesting aspect. However, this results in a serious problem: the quality of the test cases can fall, as attempts are made to achieve coverage with the simplest possible test cases. All special cases or negative tests (e.g. with other test data) are omitted as they make little or no contribution to increasing test coverage.

Therefore, these benchmarks such as “80% code coverage” should always be treated with caution. They can help to create awareness for unit tests, but can also lead to more negligence.

Test environment for unit tests

There are usually two test environments for unit tests. One is the developer’s development environment, where the test cases can be executed quickly and easily. The other is the build server or pipeline, in which the software is built for further purposes. Nowadays, there are a huge number of tools, scripts and best practices available for both variants.

Since unit tests only ever focus on one unit, the question is: What happens to the rest, e.g. the calling or called classes? These are typically replaced by test drivers and stubs that simulate the necessary calls and responses.

Test dating

Due to the modularity and small-scale nature of unit tests, the handling of test data is usually easy to implement. These only need to cover a certain aspect and can therefore be easily created or deleted. They are either located directly with the test cases or in a shared repository. A test data generator also makes sense in larger projects.

Test automation of the unit test

Test automation is a no-brainer in unit tests. There are now frameworks for all common programming languages that support both the creation and execution of unit tests. And this applies to both the development environments and the build pipelines.

Unit tests in agile projects

Unit tests are necessary in all types of projects and are now well represented. In agile projects, they have also enjoyed a high priority from the outset. Due to the ongoing refactoring and the short cycles in which the software is built, they are essential here as feedback.

Typical problems

In projects, I always come across three problems that need to be solved:

  1. no negative tests or special cases are tested. This means that unit tests only test whether the standard case works, but not what happens if corrupt data or parameters outside the specification are used.
  2. the focus is on functionality and no unit tests are written. The problem with this is that it also works well at the beginning. The software is still manageable, the complexity is low, everything works and the development progress is brilliant. However, a mountain of technical debt builds up in the background, which is difficult to work off afterwards.
  3. the necessity is not recognized. Statements such as “I’m done, I just need to write more tests” already indicate that unit tests are seen as a detached task. In contrast, high-performance teams only consider “done” when all tests have been developed. There is a different mindset here, which in my experience leads to significantly better results.

Unit test in practice

A minimum level of unit testing has already been put into practice - more so than the other test levels. Nevertheless, there are often problems with implementation. Too often the focus is purely on code coverage or test case development is perceived as an annoying evil. Yet it is precisely at this level that so many quick wins can be made for the success of the project.

Integration Testing

Integration testing is not so easy to grasp, because many things can be integrated. Modules, components, layers, services or entire systems....

Weiterlesen

Testing a Geoportal

The test process Motivation Many authorities and companies that work with spatial information are now building geoportals as an essential part of...

Weiterlesen
Software testing in the future - Interview with Wolfgang Platz

Software testing in the future - Interview with Wolfgang Platz

After successfully building up a test consulting company in the early 2000s, Wolfgang Platz founded Tricentis in 2007. With over 20 years of...

Weiterlesen