My Testing and Code Analysis Toolbox

Last week we kicked of a “Testing Skill Group” at LINEAS, a group for exchanging knowledge about testing. One question that came up over and over again in various flavors was: What tools are there for testing and analyzing your code? So here is my personal answer for this, in the approximately order I tend to introduce them into projects:

JUnit: JUnit is pretty much the basis for everything else. Its THE unit testing framework for Java, with great integration in IDEs, build tools and CI Server. I don’t take the term ‘unit’ to seriously though. I use JUnit to execute all other kinds of tests as well.

Mockito: There are many Mocking Frameworks out there but I prefer this one. It has nice DSLish API and I find it nice to use. Only drawback is that in some special cases the standard API doesn’t work and one has to use an alternative syntax.

PowerMock: I actually try not to introduce this into projects. You need PowerMock if you want to mock constructors, static or final methods. If you need this, PowerMock gets the job done, but its better not to need it.

Jenkins: a free continuous integration server. Not exactly a work of beauty, but it works, is easy to setup and does everything I needed so far with the help of a couple of plugins.

CheckStyle: A static code analysis that finds lots of bad practices and can check lots of coding conventions too. Integrates in IDEs and CI server. There are other tools in this area which are worth considering: FindBugs and PMD. You can also use Checkstyle in order to gather simple metrics about your code.

JDepend: does static code analysis of the dependencies of your code. I use it to write tests against cycles between packages in the code and also in order to limit the dependencies to those I’m willing to accept in the code base. Some time ago I found out there are some limitations in JDepend resulting in dependencies that JDepend misses (I think it doesn’t consider classes in annotations or something). Therefore I’m looking at DependencyFinder, which seems to be way more powerful, but is certainly harder to use. I actually build a little tool for visualizing dependencies based on DependencyFinder.

Cobertura/EclEmma: Cobertura and Emma are code coverage tools. I use them both. Emma in the form of EclEmma as an eclipse plugin and Cobertura in Jenkins, because we couldn’t get Emma to work as we wanted on our Jenkins instance.

Sonar: It collects tons of metrics from your code and makes them available as a website. It actually to much numbers for my taste. In a serious project you can spend the whole day looking at numbers. What is really great about sonar is, that it tracks those numbers over time, so you can see if your average method length goes up or down over time. In some projects I configured a graph with the most important numbers plotted over time and added it to the main screen of Jenkins.

Three Types of Learning

My kids are playing chess. And they really eager to play it even better. Therefore I’m reading books about how to teach chess. Much of the advice in the book are really not that specialized on chess but are applicable for any kind of learning and training. One of those advices is: There are three kinds of training:

Theory: Here kids learn about different patterns (yes there are patterns in chess just as there are in software development). They learn when and how to apply them. Mostly by looking at examples and analyzing them. They also learn rules, like how to properly convert a pawn into a queen if no queen is available (Hint: turning a rook upside down doesn’t work)

Practice: In this kind of training the kids get isolated problems to solve. Puzzles basically. Like Mate in one. They also do games based on chess rules, but not actually chess. Like collecting gummy bear from the chess board with knights.

Play: Starting from a friendly game against family or other club members to tournament.

I think it maps 1:1 to what you should do if you want to improve your software development skills:

Theory: Read books, read blogs, go to conferences. Learn as much as you can about design, algorithms, network protocols and so on. 90% of all developers neglect this. But since you are already reading this blog, you are probably among the other 10%

Practice: Do Katas, Dojos, spikes, tracer bullets, prototypes. Write code. But not in order to have working code in the hand but in order to learn and explore. I’m afraid 90% of those doing the theory part completely neglect this part. You should not. The first couple of times you try to use something which you have read or heard about, you probably will do it wrong. To bad if this is in a real project with time pressure and lots of money at risk.

Work: If you take care of the first two parts work will still bring some surprises. Your agile approach runs into problems because the customer doesn’t like it. Your nicely normalized schema doesn’t happen because you have to use an old existing database, used by lots of other applications, what worked nicely in the kata fails flat on its face when applied to 1 million records … So there is still a lot of stuff you can learn at work, but for this you have to think about what you are doing at work. Chess players eager to improve their skills analyze games they played in order to understand which move was good and which wasn’t. Do you do that? Do you do a personal retrospective in the evening? Thinking what you did well? What you could have done better?

I think you should.

Posted in: Softwaredevelopment by Jens Schauder 4 Comments , , , ,

The Three Ways to Work with Code

Obviously you read code more often than you write it. Nothing new here. This fact is brought up often when the need for clean code is discussed. Or when the merits of different programming languages are weighed.

I think this two fold distinction is not sufficient. You write code. Thats fine. But when reading code, there are actually two different kinds of reading. Lets start with an example:

  1. val string = "Hello World"
  2. string should startWith ("Hello")

Even if you didn’t follow my articles about ScalaTest you can understand what this line of code is doing. In this sense reading this line of code is extremely easy. I call this ‘skimming’

But what if this line of code is not doing what you expected? Then you need to really understand the code. Then you want to understand what is going on. In the Scala example above you might consider the following options: Is startWith("Hello") a parameter to should? Or is "Hello" an argument passed to the result you get after passing startWith to should? What is should anyway? A method? An object? A function? An instance with apply method?

As you can see what was realy easy to skim now gets quite challenging to ‘understand’.

The same can be the case for libraries. Consider Hibernate. If you have setup Hibernate, CRUD operations on an entity are really easy to write and understand. But once you get one of the dreaded Hibernate exceptions (LazyInitializationException, NonUniqueObjectException, …) you want to really understand what is going on. And at that point many people realize they have no idea what is actually happening when they call session.update or just the getter of an Hibernate Proxy.

Obviously you want all three kinds of handling code to be as easy as possible, and writing might be the least important, because we read more code then we write. But how important is the ability to skim versus understanding?

With anything you use in an application you will do a lot of skimming. Thats why DSLs like the ScalaTest example above are such a great tool.

I suspect if you do complex things with a library or a language, understanding will always be hard. But in some cases it gets extra hard because non standard tricks are used. In Java a typical case of trick is Reflection and Byte Code Manipulation. Many of the more powerfull libraries use it to work around the limitations of ‘normal’ Java. The result is code that is easy to skimm but for many people next to impossible to understand. Examples are Mockito or Hibernate.

So when evaluating a library or writing one you might consider how much magic it is using.

The other way to limit the problem with ‘understanding’ code is to make it unessecary. I think Hibernate is an example where this failed. You have tons of places where you have to understand pretty exactly what Hibernate is doing in order to use it correctly.

Java itself is an example where this works pretty good. In many, many projects nobody has to actually understand how the JVM works. It just works. Only in rare cases you have to dive into the details of the garbage collector or the memory model.

The key here is a clean non leaky abstraction. If you have that it doesn’t matter what kind of magic you use to make it happen. But if your abstraction is leaky, parts of the magic you use inside will leak out with the risc of turning your project into something that acts like it is bewitched.