Book review: Sujoy Acharya – Mastering unit testing using Mockito and JUnit

Some weeks ago, I was contacted by Packt Publishing to write a review about the book above. Without any further introduction, let’s just jump in and see the pros and cons of this book.

Mastering unit testing using Mockito and JUnit is a pretty new book, it was published in July 2014.

Right in the first chapter, the author digs deep into the capabilities of JUnit 4. This is a very thorough analysis of the JUnit API, starting from basic things (like how to write a basic test case) and gradually moving towards more and more advanced topics (test categories, expected exceptions). Anything you’re ever going to use from JUnit is described here – and much more. While reading this chapter I had a feeling that if the reader is an expert, chances are high that they’ve already met most of those method calls and annotations; if they’re new to unit testing, then this chapter may be somewhat too fast.
Every single aspect (method, annotation etc.) is backed by some example code, but unfortunately these problems have little to do with real life applications (like assertTrue(true)). Quick note: the book uses the when_something_then_something naming convention for tests. I like this very much, this is my favorite too, as test names become much more readable.

Chapter 2 introduces automated build tools such as maven (ant, gradle) and Jenkins. I think this is a very good idea, as nowadays such tools are compulsory for a software engineer. However, three build tools (maven, ant and gradle) described in detail (I really mean in detail: how to download and configure tehm, how to put together a simple project) is a bit too much. (I think most readers want to be true masters of unit testing, and not of different build tools. To describe the concept along with an example is awesome and would have been more than enough).

Chapter 3 is very short compared to the others. It describes the test doubles – as defined by Gerard Meszaros, which is really a prerequisite to mocking. Many times people fail to see the difference between all the types of test doubles, so this chapter is very welcome.

Chapter 4 is all about mocking with Mockito. It again dives deep into Mockito with all its annotations, API methods and capabilities.  Although similar to Chapter 1, this chapter introduces a more complex example (manipulating stocks), through which it unfolds different aspects of Mockito. There are very nice tips in this chapter, like inline stubbing (saves a lot of code lines) or configuring mock default behaviors for mocks. I’m looking forward to putting in practice some of the ideas described here.

Chapters 5 and 6 will take you to the world of code coverage and code analysis tools. This is again, very cool idea to talk about in conjunction with unit tests. Maybe I would have liked it more right after chapter 2, so Mocito and its usage could have been one after another.

Chapters 7 and 8 are about using Mockito in real life. Chapter 7 is about testing web application, while Chapter 8 talks about testing the data tier. These, indeed are tough things to handle in real projects, so I like it very much that these chapters made it into the book. However, I think there is a slight focus loss here; these two chapters shouldn’t put that much attention on Spring (MVC and JDBC Template), but rather on general, technology independent problems. Sometimes  I felt like I was reading a book on Spring, with some unit testing and not the other way around.

My favorite parts were the last two chapters. Chapter 9 talks about problems that pop up every single day while fighting huge legacy code bases. Those things described there happen exactly as presented – I encountered almost each and every of them when I was a maintenance guy. The book offers practical solutions on how to overcome these obstacles and get legacy code base under test. This chapter is an awesome one, everybody should know and practice those tricks.

Chapter 10 is about best practices when it comes to unit testing. This chapter is really for the inexperienced, who have just  met unit testing but are not familiar with all the good practices about the framework. This chapter should be a very good starting point for junior programmers at the beginning of their career.

Summary.
Mastering unit testing using Mockito and JUnit has got pretty cool tips and tricks, very thorough analysis of the frameworks and practical applications for everybody out there. One thing I particularly liked is that the book offers a very good overview on all the different reasons why a piece of code becomes hard to test. Nevertheless, I can’t really figure out who is this book for. It is too fast paced for absolute beginners, but somewhat too obvious for experienced engineers – in my honest opinion, some parts may miss the targeted audience.

Having said all these, I’m rating this book 3 out of 5.

Advertisements

Prototyping vs TDD Prototyping

I often hear “I’m prototyping” as an excuse not to do TDD. In this context prototyping means  “there will be no unit tests around this piece of code, ever”.

In my opinion prototyping does not mean avoiding writing tests at any price, but to

  1. Create a piece of code without tests and  check whether it works or not. If it does not, make it functional and – here it gets tricky – delete/comment out the whole thing. After that recreate the certain functionality using TDD practices. This process is kind of laborious and can be used when the functionality being implemented cannot be decoupled from the system. This approach can be employed when the functionality being implemented depends on a third party product, where the communication protocol is unclear.
  2. Create an application totally outside the boundaries of the system. The prototype application can be created with no test cases at all. It is because the prototype is not part of production code; it doesn’t matter for example if the code is not in a good shape because it is not part of the system and there is little chance that it will be read or modified by anyone other than its creator. Since the application is decoupled from the system under development it should be fast to run and see whether it produces the correct output (in less than five minutes, for example). The idea behind such a prototype application is to be created as fast as possible (sometimes in order to decide whether a third party application should be used or not), so anything beyond the happy execution path can be omitted. When the prototype works perfectly, it can be either thrown away and rewritten in TDD, or refactored/tested thoroughly and inserted into the system (this is risky though; by thorough I mean really thorough with all kinds of exception handlings and so on).  Remember, this is not TDD anymore.

Basically, prototyping can be used when the functionality under development depends on a third party application. In my opinion, there’s nothing to prototype when dealing with parsing input commands, validating things, calculating hashes etc. In those cases the word “prototyping” is just a cheap trick not to write unit tests.

Hey Ho, Let’s Go (Agile again)

I’ve already complained enough about us not being agile enough. I also realized that complaining and crying will not help us solve the situation we got into. There were a few problems arisen, ranging from tiny to not-so-tiny. Of course most of them will not go away overnight. It’s useless to tell “we’re doing completely wrong” and not to do anything about it. As one of my former colleagues would always say, “the s**t has to go away”. However, it only goes away if we found out which the s**ty parts were. Continue reading “Hey Ho, Let’s Go (Agile again)”

TDD avoidance – Top 10 reasons

I’m sad to see we somehow got way too far from agile coding, best practices and quality. It seems that TDD has its life cycle curve inside our organization (who knows, maybe we can generalize further). At the beginning everyone is excited about the new way of working. They seem to be adapting things, trying out TDD, mocking and the other technologies. After a while, however, people feel test driving feature development is a waste of time. So they stop writing test cases and get back to their old way of working. At the end, the organization is left with very few people committed to TDD.

And this is the strange part. Quality drops, because nobody cares about it, but when it gets noticeable everybody cries around. And that is the point when people start shouting louder: “This code is pretty much a mess, we’d rather rewrite the whole thing”. A friend of mine told me the other day “you cannot expect people to be writing test cases; they lack dedication”. (By the way, in this case I wouldn’t expect them to be complaining about quality… but anyway) And I guess this is the point here. Lack of dedication.

I tried to figure it out, so I started walking around in the landscape and ask people why they don’t write test cases. Here is my top ten answers I collected. Are you ready? Ok, here we go:

  1. I am so smart I can implement this without test driving it
  2. I don’t know how to write tests
  3. This is a really small change, no need for tests
  4. This cannot break anything
  5. I’m in a rush, no time for TDD
  6. I wanted to write tests, but I didn’t 🙂
  7. It’d be too hard to test this mess
  8. TDD’s not a silver bullet. With or without it, doesn’t matter
  9. I’m prototyping
  10. I’ll do the real work, then you can play around with your tests

The sad thing is that I didn’t make up any of these…

I’d like to emphasis this one: “I’m prototyping”. It seems to me that as soon as people get to know about prototyping they get an excuse not to do TDD. Tricky prototyping this is after all. People write a bunch of code, call it a prototype and -guess what- check it in! Ok, first they cross their fingers and say “I hope this works”. So we fall back to Hope Driven Development (thanks for the term, Marcell).

And finally, number ten. I really heard someone say that when I proposed we do test driven development. Some people don’t even consider writing tests real work.

Sadly enough, people who already had the OMG moment seem to forget about tests (I call OMG moment when someone discovers how useful TDD is. Usually it happens when they miss a bug, but their tests catch it for them). One idea we could come up with is a regular TDD group, with the committed ones (this would involve regular meet-ups where we could teach each other tricks, techniques and other stuff. Perhaps after a while everyone will be confident about their skills, so we get several TDD mentors). Maybe we can place them in different  teams so they can “infect” others with TDD (they can insist writing quality code at pairwork sessions). Maybe it helps, maybe not. Any comments welcome.

Code Kata Nr. 4

This week we got back to realistic programming. After last week’s fibo-emirp numbers (even if there were two almost perfect solutions) I found out that real life problems are somehow closer to the teams’ heart.

This week we had IBAN number checking as a kata (yeah, we are doing such exercises on purpose: I’m planning a great attack on World Bank 🙂 ). In order to check an IBAN number, one has to follow the steps below (note, I am using the following IBAN as test data: “IT60Q0123412345000000753XYZ”, taken from http://www.morfoedro.it/doc.php?n=219&lang=en ):

  1. An IBAN number is an alphanumeric literal of at least five, at most thirty-four characters
  2. The alphanumeric string can only contain uppercase letters and digits
  3. The first two characters have to be LETTERS ( trough which we can identify the country of origin, IT60Q0123412345000000753XYZ, we have Italy)
  4. characters three and four have to be digits (IT60Q0123412345000000753XYZ, we’re doing great)
  5. the rest of the characters can be either letters or digits
  6. the first four alphanumeric characters have to be moved to the end of the string (Q0123412345000000753XYZIT60)
  7. all the letters have to be converted to numbers, following the formula:  A=10, B=11, C=12 … (260123412345000000753333435182960)
  8. as a last step the following computation has to be carried out; resulting number MODULO 97. If the value of the modulo is 1, then we have a valid IBAN. (*)

(*) A possible way of  modulo computation: divide the number into parts of (let’s say) eight digits. Take the modulo of this smaller number and put the result of the next pack of digits. Let us break this numerical string into five parts: 26012341, 23450000, 00753333, 43518296 and 0. The remainder of the division of 26012341 by 97 is 45. The remainder of the division of 4523450000 by 97 is 15. The remainder of the division of 1500753333 by 97 is 82. The remainder of the division of 8243518296 by 97 is 68. The remainder of the division of 680 by 97 is 1. [http://www.morfoedro.it/doc.php?n=219&lang=en]

If you’re curious of my solution, you can find it here:  https://github.com/tamasgyorfi/Code-kata—IBAN-numbers

The kata is of two rounds, twenty-five minutes each. The exercise involves a constraint also, namely the one testcase one assert. This was needed because there were many cases when I saw testcases with 5-10 asserts. In my opinion that is not a very good practice.  Let’s consider the following situation: there is an algorithm of some kind that checks numbers against some criteria. Let’s say the algorithm is faulty and fails for 1, 11, 111 etc. If there is a single test case that contains a lot of asserts (positives and negatives alternatively) it’s gonna fail for one and the test runner will not go on. Which means that the method will not be checked for 11, 111 etc. So one tries to fix the algorithm for 1, and will not notice the pattern… I personally like to see how many test cases there were, how many of them passed, how many of them failed. I don’t like asserts that are not run at all. Comments on this are welcome.

Code Kata Nr. 2

Since after the first Kata we’ve completed I received quite good feedback, we went on with a second one. I thought this time we’d start from something simple, having the possibility to complicate the exercise as much as possible. The basis of the Kata was again a little quiz from www.rubyquiz.com, namely string equations. However, I modified the syntax a little bit  to better fit for Java and avoid frustration from teams side.

So the exercise itself sounds like this:

  1. Given a string in the form ‘word1’ & ‘word2’ & ‘…’ == ‘wordn’ & ‘wordn+1’ & …, called a string equation. The two sides are equal if and only if the left side (without the apostrophes and &s) is an anagram for the right side
  2. Words might contain asterisks (yeah, yeah. I know… Words usually don’t contain such characters. But anyway, let’s just stick to the exercise) . Words that contain an odd number of asterisks are invalid ones, so they should be removed. Such a way they don’t count at the final anagram check. (I reached this point in a two-round kata, you can see my solution on my github page: https://github.com/tamasgyorfi/Code-kata—string-equations)
  3. Words that are palindrome (are the same read from the beginning and end) don’t count either.

We had an hour resolved for the Kata; I asked the guys to take extra cares of two things:

  • Self explanatory names (classes, methods, variables etc)
  • Correct usage of assert functions of JUnit

The first round took 20 minutes, all the pairs opted to work on the basic version of the kata. After the first round we had two complete solutions. At the discussion after the first round I was glad to hear the guys talking about writing much more unit tests then a week before.

In the next round, the two pairs having completed the first version started working on the extended kata, while the others tarted over the basic one (of course everyone had to delete their work so far -not actually delete, but unload it from eclipse).At the end we had again a complete solution, and a halfway-completed one (I told the pairs the main goal was to write clean and tested code, and not to just have a working implementation of the exercise. I see that they still think the only measure of these kata sessions is completely working code. Hope this will change over time. Till then I’ll tell them every time.)

What I saw after looking at the codes the guys wrote, I can say that this kata was even more successful than the first one. More test cases, better collaboration, correct usage of asserts (yeah we have that action point completed! Nicely done guys, we can move on to another one). However, classes and variables have had kind of strange names (I even saw a class named WTF :-)), like p1, p2, k, c etc. I also saw quite many long functions, hard-to-understand logic and overcomplicated algorithms. I definitely think that we are going to need a refactoring workshop, where we can look at several widespread antipatterns, and have them corrected.

Maybe I can arrange it it a week or two.

The super TDD pen

Today I have introduced my colleagues the “Super TDD Pen”. As I’ve mentioned earlier, most of these guys have never met agile, test first, scrum, kanban etc. before, so they need to practice and practice and practice even more. The most important thing before we start implementing business logic, is to catch up a bit with test driven development. In order this to happen, I take different approaches: organize code katas, discuss agile design values, send them articles to read, and the newest: The super TDD pen. It is nothing particular, just an ordinary marker we use to annotate tasks solved in TDD. I also updated the DoD (definition of done) to contain a reference to the red pen.

I considered it important to present the pen at the time only GUI mocks and prototyping tasks are present on the whiteboard. Of course, one can argue there is not much TDD involved in this phase of the project, but anyway; I hope they get a bit frustrated by the lack of red pluses, so they start writing code test first.

On the other hand, it will be a good marker how widespread TDD is in our project. I also plan to analyze task PostIts on a regular basis, so we can see the progress we make. I hope to see we are getting better at it, so we can place more emphasis on other important things too.