To gain confidence when testing software, you want to test the program as much as possible. The conventional way to do this is to test the application extensively through its external endpoints. These external endpoints may be a user interface or web services. They can almost always be be automated and automation is a good start.
Unfortunately, testing from the external endpoints leads to a few problems:
The cure is to rely as much as you can on fast unit tests. But a unit test will only test one thing. To know if a class can collaborate with other classes, you need to test that collaboration scenario. This can lead to integrated tests that have bad diagnosis precision, are slow, and have too many execution paths.
There is one alternative, though, that many developers hasn't explored enough. That is using unit tests with mocks and stubs in a strict way. I will explore this alternative in this post.(more...)
Ever included Mockito in your project and lost the nice feedback from Hamcrest?
And only when running your unit tests from IntelliJ IDEA? Instead of a message describing what
you should fix, you see
I have. More than once and been very frustrated. These are tools I like. Not getting good messages upsets me.(more...)
A test must be independent. That is, a test should never depend on the result of another test.
If you run two tests in a specific order, you should expect the same result as if you run them in the reverse order.(more...)
Sometimes you want to verify that an exception is thrown in your code.
Let me show you three different ways to verify that the expected exception has been thrown.(more...)
When should you use which assert? It is a question developers new to unit tests may ask themselves.
It is easy as a seasoned developer to think that this is obvious. It isn't when you are learning.(more...)
Designing software can be done in different ways. The time and effort spent in designing have an important effect on the result. An interesting question is when should you you allow the software to evolve using Test Driven Development, TDD, and when should you not allow it to grow using TDD?
This blog post is the result of a session at an open space with the Software Development Gang in Ghent, Belgium, June 2015.(more...)
I had a need to stub a method the other day that had a var arg method. I failed in stubbing it using Mockito. It disturb me a lot. But after mulling on the problem a while, I searched and found a simple solution.
Mockito has a
anyVararg() method that you should use when you try to stub a method that takes a var arg
How can you pass a parameter to a unit test parametrised with JUnitParams? The answer is simple: As any other parameter.(more...)
Writing unit tests that test almost the same thing may introduce duplication. A solution could be to create parameters that should be varied in a list and iterate over it. Yet another solution is to create a parametrised test. Let us look at an example where these three options are explored.(more...)
The way Maven file structure is defined is a great way to separate unit tests and production code. Unit tests are fast. So fast that developers developing using Test Driven Development, TDD, doesn't have any performance problems when applying the Red-Green-Refactor cycle in their work. A large unit test suit is expected to be executed in seconds.
There is, however, no standard on how the files should be structured for slower tests (integration/acceptance/system et.al.). A common property for these tests is that they are slow. They often require a complete system setup in a known state. They use the filesystem, network, database and similar slow resources. Slow tests are normally not executed often. Developers seldom have the patience to wait for a build a long time before writing the next thing. Using them in a Red-Green-Refactor cycle is not practical. It takes too long time.
So what options do we have to separate the fast units tests and the slow tests? There are two main tracks that I have explored.
JUnit supports annotations so a method can be executed first in a test class or before each test method is executed. It also has annotations that supports methods to be executed after each test method or after the test class. This is very good if you need a common setup and a common tear down.
The after methods don't give you access to the test result. You cannot know if a test method failed or not. This may
pose a problem if you have a need to perform some specific actions after a failed test. A solution could be to
onError() method. But JUnit doesn't support it.
A solution is to employ a @Rule annotation.(more...)
It works on my machine!
Ever heard that from a developer? I have, and it happens that the reason is that it actually works on their machine. It may also be the case that the order in which tests are executed matters. Test classes depends on each other and the order they are executed in is important. The solution is to execute the tests in random order so that any dependencies between tests are found and can be removed.(more...)
Filed under: Clean code, Java, TDD, Test automation, — Tags: Bad tests, Dependency injection, Good test, JUnit, JUnit, Mockito, Parameterized JUnit, Readability, Test harness — Thomas Sundberg — 2012-03-08
A colleague asked that question the other day. What is a good test? It is a really difficult question to answer. There are a number of properties that hold true for a good test. I will list some of them and discuss why I think they are important. Others may think that the order of importance is different or that other properties are more important then those that I list.
I will show some examples using Java and JUnit of what I think are bad tests and how they can be refactored to something better.
Tests are automated in my world. I always try to avoid manually testing. The main reason for this is that manual testing is slow and hard to repeat arbitrary many times. Therefore, test should be read as automated test in for the rest of this text.(more...)
The simplest possible solution that could work. Ever heard that expression? What does it mean? Really?
The answer is obviously something that in a really simple way satisfies the test you currently are working on. Nothing more, nothing less.(more...)
Development guided by test is perhaps the best way to make sure that your solution works and is possible to verify. I will show how you can develop a database layer guided by tests. It will be divided into two parts. The first part will be an in memory solution and the second part will be implemented using Java Persistence API, JPA, and Hypersonic. The second implementation is supposed to replace the first one guided by the tests developed for the in memory solution.(more...)
Hamcrest is a great framework for assertThat and it is bundled with JUnit. It is getting some competition from another framework, the FEST assertThat framework. The idea behind FEST is to use a fluent interface. This means that you can use your development environments code completion features to build your asserts. Its main goal is to improve test code readability and make maintenance of tests easier.(more...)
Dependency injection is invaluable when building software. Decoupling components means that it is possible to test them independently.(more...)
We want to convert a POJO, Plain Old Java Object, to xml and we don’t want to alter the POJO in any significant way. How can this be done?(more...)