Simple steps to make your JUnit tests better (part 1)

One of my latest tasks was to review and refactor unit tests in our system, which I found especially suitable for me. After presenting my results to the team guys asked me to create a page on Confluence describing my remarks and proposed practices we should follow – what a great occasion for a blog post. So here I present some practices that in my opinion (and my team’s opinion too) can improve your tests and make them cleaner, simpler and more readable.

Proper test method naming

The name of the test method is as important as the test itself. The key is that it should describe the behaviour that is tested – not the name of the method that is tested, not all the arguments that are taken, but the behaviour. So names like testMethodA are absolutely wrong and please never use such a construct. Also have in mind that such naming lead to monsters like testMethodA2, then 3, 4, 64, 382 and so on leaving the code in a state that nobody knows what is actually tested and where. If naming was done well you don’t even need to look inside the test method to understand what’s going on and what is actually tested. To achieve it use on of BDD naming conventions which enforces you to think about the behaviour that it under test before you start coding and describe it well. Personally my favourite naming convention is “should do something when something” In example:

@Test
public void shouldPopulateAuthorDataWhenGeneratingReport()

This is a powerful practice for beginners as starting the test method with the magic “should” word makes you literally stop and ask your self “Yeah, what it actually should do?”.

Don’t be afraid of long method names – we’re not having any limits on that so you can put inside method name everything that you consider essential to fully express what’s going on under the hood. Test are for developers and developers should read camel case text as fast as normal one so argument that long names are unreadable for me is invalid. However, if you method name is getting longer and longer check if the test isn’t doing too much and if you design is fine.

 Use matchers instead of simple asserts

Using matchers library will make working with test much simpler because of two reasons. First, tests are more readable. Your assertions are starting to tell a story describing the behaviour. To give an example look at these two assertion below and for full effect try to read them aloud.

assertTrue(!(shoppingList.size() > 2));
assertThat(shoppingList, hasSize(not(greaterThan(2))));

Hope you got the point. I have seen lots of tests with all assertions done with assertTrue only and this is why I used it here. Even though using hamcrest gives you a bit more code, you gain on readability – you don’t have to analyze carefully what are the conditions, it’s given on a silver platter. Here the assertion is quite simple, but imagine analysis on more complicated cases.

Secondly, matchers simplify debugging a lot providing elegant logging when assertions fail. Let’s look at logs from both failures of assertion given in the code above. When using first assertion all we get is

java.lang.AssertionError

which literally tells nothing and we have no information what went wrong. On the other hand using matchers we get quite informative log giving us a first place to start analysis.

java.lang.AssertionError:
Expected: a collection with size not a value greater than <2>
but: collection size was <3>

 Write concise tests

You should keep inside the test method only things that are essential to describe tested behaviour, extract everything else to increase readability and the ease of understanding what is going on inside the test. Take a look at this example.

	@Test
	public void shouldDetrminePaperAsPackingMaterialIfItemIsRound() {
		Item item = new Item();
		item.setWidth(10);
		item.setHeight(20);
		item.setColor(RED);
		item.setShape(ROUND);
		
		Material material = packingAdvisor.determinePackingMaterial(item);
		
		assertThat(material, is(instanceOf(PAPER)));
	}

Do we need all the details of an item inside the test when the only thing that matters is it’s size? This is nothing but a noise in the code leading to more time spent on understanding it. Person looking at this test will try to analyze all the fields, thinking that possibly the values have some kind of influence on the test result. Item’s size and color are values that are not tested and should be extracted to separate method used to construct items – how to do it well is a topic for another blog post of course.

Setting up all items fields in each test case is causing also code duplication which is one of basic faults.

To be continued.

Advertisements

Hello world!

Changes came to my life, quite huge ones I must say…

First of all I change my place of residence from Krakow to Wroclaw, which was quite an expected change as for last 1.5 year I had to travel these 300 kilometers almost every weekend. Of course a change of work place came along so… I moved from one investment bank to another. And here begins the story of this blog.

For a longish time I was thinking about starting a blog and now finally I found a moment which gave me a boost to put thoughts into action. In Krakow I was working in a very mature environment with well developed agile practices. Working there was a great pleasure and I must admit that I learned more then anywhere else before. In Wroclaw the situation appeared to be quite different – I joined a quite new team, where the very first members have been there for less than half a year. New situation brings new opportunities of course.

In this very moment the team is definitely in the forming stage, looking forward to finding their own best practices for the delivery process. The environment is a greenfield, which satisfies me a lot as since the very beginning I can propose process improvements and put my current knowledge and experience into test. Having a lot of challenges ahead I decided that it can be useful to share my experiences with the community for both sharing and gaining new knowledge. I really hope that by describing my experience I will receive advises and also I hope that my thoughts shared here will possibly help others that are facing similar situation.

I hope that many of you will find this blog useful or at least interesting. I also hope to find enough time to share as much of the things happening as possible so you will be able to see the change that is ongoing in my working environment. I am really looking forward to see this happening as the team is very open-minded and one can fell that their need to change and improve is huge.

Of course I would also like to share my thought about all other agile related stuff that I will find interesting and worth sharing in my very own opinion. I will be very glad if you find my posts and thoughts useful.

Stay tuned.