10 rules of (unit) testing

January 31, 2008

There you go, those are my 10 rules of (unit) testing. It’s nothing exciting, really. Everyone is so agile these days. Are you agile? I bet you’d say: I was born agile.

10c

Here I come with my own 10 commandments. I came up with those while doing research on mock frameworks (haven’t you heard about Mockito, yet? it’s the ultimate tdd climax with java mocks). I browsed so much of our project’s test code that I feel violated now (codebase is nice, though).

  1. If a class is difficult to test, refactor the class. Precisely, split the class if it’s too big or if has too many dependencies.
  2. It’s not only about test code but I need to say that anyway: Best improvements are those that remove code. Be budget-driven. Improve by removing. The only thing better than simple code is no code.
  3. Having 100% line/branch/statement/whatever coverage is not an excuse to write dodgy, duplicated application code.
  4. Again, not only about test code: Enjoy, praise and present decent test code to others. Discuss, refactor and show dodgy test code to others.
  5. Never forget that test code is production code. Test code also loves refactoring.
  6. Hierarchies are difficult to test. Avoid hierarchies to keep things simple and testable. Reuse-by-composition over reuse-by-inheritance.
  7. One assert per test method is a bit fanatical. However, be reasonable and keep test methods small and focused around behavior.
  8. Regardless of what mock framework you use, don’t be afraid of creating hand crafted stubs/mocks. Sometimes it’s just simpler and the output test code is clearer.
  9. If you have to test private method – you’ve just promoted her to be public method, potentially on different object.
  10. Budget your tests not only in terms of lines of code but also in terms of execution time. Know how long your test run. Keep it fast.

Number #1 is my personal pet. Everybody is so test-driven but so little really care about #1 in practice. Best classes, frameworks or systems offer painless testing because they’re designed & refactored to be testable. Let the code serve the test and you will produce delightful system.

Number #7 is a funny one (‘Cos we need a little controversy). The whole world rolls in the opposite direction. Maybe I just don’t get it… yet. Or maybe it’s because I paired with young one-assert-per-test guy once. He cunningly kept writing test methods to check if constructor returns not-null value. If I had to play this game and chose my one-something-per-test philosophy I’d steal MarkB’s idea: one-behaviour-per-test. After all, It’s all about behavior…


Mockito

January 14, 2008

I’m a mockist but existing mock frameworks just don’t appeal to me. They spoil my TDD experience. They harm code readability. I needed something better. That’s why I came up with Mockito.

Syntax

Here is a what I think about mocking syntax:

  • Let’s keep it simple: interactions are method calls. There is no point in building sophisticated mocking language for method calls in Java. There is already a language for that. It’s called Java.
  • The less DSL the better. Interactions are just method calls. Method calls are simple, DSL is complex.
  • No Strings for methods. I spent more time reading code than writing it. Therefore I want the code to be readable. String literals pretending to be methods cannot compete with actual method calls. Even IDEs decorate literals differently so my mind will always adopt the real method call quicker than any literal trying to impersonate a method.
  • No anonymous inner classes. They bring more indentation, more curly brackets, more code, more noise. Did I mention that I spent more time reading code?
  • Painless refactoring. Renaming a method should not break my tests.

That’s why I really like the syntax of EasyMock.

Long journey from EasyMock to Mockito

I was brought up on EasyMock. Normal kids got milk I got classes to test. Over the years on different projects I saw idyllic world of hand crafted stubs being overthrown by EasyMocks. On other project, jmock was doing fine until he got a Chuck’s roundhouse kick to the face by EasyMock. Finally, I saw resentment to EasyMock and triumphatic comeback of hand crafted stubs… Sometimes the resentment to EasyMock was a bit naive (“My class has 10 dependencies and is difficult to test. Therefore EasyMock sucks”). Sometimes it was clearly righteous…

Here is what I wanted to achieve with Mockito so that it suits me better in test-driving code the way I like:

tdd

Focused testing. Should let me focus test methods on specific behavior/interaction. Should minimize distractions like expecting/recording irrelevant interactions.

Separation of stubbing and verification. Should let me code in line with intuition: stub before execution, selectively verify interactions afterwards. I don’t want any verification-related code before execution.

Explicit language. Verification and stubbing code should be easy to discern, should distinguish from ordinary method calls / from any supporting code / assertions.

Simple stubbing model. Should bring the simplicity of good old hand crafted stubs without the burden of actually implementing a class. Rather than verifying stubs I want to focus on testing if stubbed value is used correctly.

Only one type of mock, one way of creating mocks. So that it’s easy to share setup.

No framework-supporting code. No record(), replay() methods, no alien control/context objects. These don’t bring any value to the game.

Slim API. So that anyone can use it efficiently and produce clean code. API should push back if someone is trying to do something too smart: if the class is difficult to test – refactor the class.

Explicit errors. Verification errors should always point stack trace to failed interaction. I want to click on first stack element and navigate to failed interaction.

Clean stack trace. Part of TDDing is reading stack traces. It’s Red-Green-Refactor after all – I’ve got stack trace when it’s red. Stack trace should always be clean and hide irrelevant internals of a library. Although modern IDE can help here, I’d rather not depend on IDE neither on competence in using IDE…

road split

EasyMock is a decent piece of software, credits go to kick-ass people who wrote it. Initial hacks on Mockito were done on top of the EasyMock code but since then I rewrote most of the codebase. Enjoy.


is private method an antipattern

January 5, 2008

After a conversation with my friend and after a cursory google search, here are my thoughts:

Private method a smell’ seemed to be ignited with the birth of TDD. Test-infected people wanted to know how to test their private methods. Gee… it’s not easy so the question evolved from ‘how‘ into ‘why‘: Why to test private method? Most of TDDers would answer instantly: don’t do it. Yet again TDD changed the way we craft software and re-evaluated the private methods :)

Clean SpringTest-driven software tends to have less private methods. Shouldn’t we have a metric like: private methods to public methods ratio? I wonder what would be the output for some open source projects (like spring – famous for its clean code).

So, is private method an antipattern or not!?

If the class is so complex that it needs private methods, shouldn’t we aim to pull some of that complexity into its own class?

The code never lies: We looked at several distinctly big classes and put their private methods under magnifying glass. Guess what… Some of the private methods where clear candidates to refactor out to separate class. In one case we even moved whole private method, without a single change, into separate class ;)

Privacy may be an antipattern. Look at your private methods – I bet some of them should be public methods of different objects.