Devs write tests, not testers

Tests should be written by developers not by testers. Period.

Why?

Basically developers seem to be better in writing test code then testers since they specialise in coding. Testers are better in other areas!
Developers are more likely to produce maintainable tests then testers. Developers are also more likely to be faster.

I noticed that testers produce lots of duplication in tests. Unfortunately in most cases they are not familiar with the best practices when it comes to coding (DRY, YAGNI, SOLID, LOD, etc…) and that might cause and in most cases causes maintenance problems.

What about producing acceptance test scenarios? Well, in that case I would recommend getting together and working on the scenario skeleton, for example a business person, a tester and a developer. Then the developer can implement the test based on the skeleton and consult the end result with business and testers once again.

So for example, who writes selenium tests that scrap the applications and test the whole business flows? Developers! What do testers do? They help when that test scenarios are sketched. Then they wait for the production code to be ready and test the performance (when there are no automatic performance tests) and the boundary conditions that the developers might not have thought about.

[Example revisited: Buy stocks] Yatspec quick start

This is a revisited version of an old example

This is a new implementation of the same example using yatspec but in a more clear (in my oppinion) way. The old post is located here.

Why clearer? We are not using unnecessary objects like StateExtractor, ActionUnderTest and hamcrest matchers which we do not like.

What is the story?

The story we will be implementing is “Buy the stocks when price drops by 10 units”. When we receive a notification through a web service that we expose, we will have to examine it and buy stocks when certain conditions are met.

What is Yatspec?

Yatspec is a new test framework that can meet your needs if Cucumber, Concordion and Fitnesse don’t. This example will focus on getting the story done using Yatspec. I will prepare other posts on using other acceptance test frameworks soon. There will be also another post that compares the frameworks. I will link to then as soon as I implement them.

Step 1: Start with an acceptance test skeleton

I came up with an acceptance test skeleton. This is how it looks like:

When I run it I see of course:

When I open the output HTML file I see:

Notice that the HTML file is generated from Java code. This makes it very easy to refactor all Java stuff and keep documentation always up to date, since the documentation is generated. You don’t have to edit any HTML files!

Step 2: Time to implement the acceptance tests

I implement the aceptance tests. I have never used Jersey before, but I decided to do it this time since it is said to be the leading solution when it comes to RESTful communication in Java. Please forgive me if my use of Jersey is not optimal. Please remember, in this article we focus on introducing Yatspec.

Please notice that we have an Application object that represents our application. We also have a StockMarketStubServer which is a stub of the real stock market that we will be sending requests to.

As you can see below the acceptance test sends a notification to the application and the verifies that the stock market received the expected bid request.

I also add information to interestingGivens and log(…). Those elements will be visible in the HTML output.

Step 3: Make the acceptance test pass

I implement the production code. I don’t include the listings in here since the purpose of this article is to focus on Yatspec. If you wish to see the end result please take a look at the attached sources.

Yatspec final HTML output

I run the test. Now we can take a look at the final Yatspec documentation/output, HTML!
You can click the headers “Interesting Givens”, “Received Notification” and “Request Received By Stock Market System” to expands those sections.

Notice that we can log the conversations with other systems. One can use the CapturedInputAndOutputs object, that is the log(…) method that will be automaticly added to the HTML output. Notice that we can highligt interesting stuff in the conversations without editing HTML, using IntegestingGives object! When you are doing ATDD in backend systems this “logging” might be very useful. I would say that in most cases the “captured inputs and outputs” are actually the acceptance criteria.

Conclusions

This post was just a simple quick introduction to Yatspec. I am working on comparing Yatspec with other test frameworks. I will update the posts as soon as I am ready. Please comment and subscribe to RSS! 🙂

Avoid argument captors

Why avoid argument captors?

They decrease readability of the tests. It is a code smell. It is very probable that if you use argument captor your class violates one of the SOLID rules. The most common violation in my experience is not sticking to SRP.

Example 1

I have found on the web an example of how to use argument captors. This is the test I found:

The author had probably in mind showing how argument captors work. I agree that it is a good thing to show stuff on the web. On the other hand if I was test driving implementation of inviteToParty method I would go for just a simple verify:

In my opinion it is far more readable. I don’t see the point in using argument captor in this case.

Example 2

I found another example usage of argument captor on the web.
The solution presented there looks like this:

This is a clean test. I like it. But If I was to write that test I would probably split that MailDeliverer. I would split the the creation of Email object and invoking external system. When you order a laptop you don’t have to assemble it yourself, it is assembled for you in a factory. Some may say that this is a bit over the top in this case, but this is just to stress the principle I have in mind. This is what I came up with:

And:

What do YOU think? 🙂 Please comment and subscribe to RSS! 🙂

Commit to SCM frequently

I try to commit and update as frequent as possible. The ideal scenario is to commit and update after we have finished a small chunk of work. That might be even each 10 minutes! This approach encourages thinking in small steps. If an unexpected test fails we can revert without much cost. If the refactor we are doing goes not as we expected we can revert and try once again. It some cases it will be cheaper to revert than keep doing something that looks not pleasent form the beginning. It worked for me many times.

Please comment and subscribe to RSS! 🙂

How NOT to test drive time dependant functionalities

Recommended reading before you read this article: Fest assertions, Testing time dependant functionalities .

Do NOT do this!

I would like to present an example of an attempt to test time dependant functionality in a not very nice in my opinion way. Please see testing time dependant functionalities for the recommended way.

Below I present two very similar ways of trying to test drive time dependant functionalities. Please remember that the recommended way it to introduce a clock class.

Approach by extending Fest (DO NOT DO THIS)

Approach by extending Hamcrest (DO NOT DO THIS)

Why avoid this approach?

Think about it. Is “is within one second” actually what you are looking for? Probably not. You are looking for “is now”.
The other argument is that is reduces readability.

JUnit vs Fest by example

I assume you know what a Junit assertion is (assertEquals, assertSame, …). Fest assertions is a mini framework that increases readability of our assertions. Some people still use Hamcrest, but it has many disadvantages when you compare it to fest. (I was using Hamcrest for 6 months, then switched to Fest. Now I use Hamcrest only when I have to. For example when I work on an old codebase, etc.)

Please find a simple and quick comparison of pure Junit asserions and Fest assertions below.

Junit

Fest

The most important things I would say about Fest is:

  1. you don’t have to think about the order of parameters (which one is expected, which one is the actual one)
  2. is has a fluent interface, eg. assertThat(obj).hasSomething(a).hasSomethingElse(b).doesNotContain(b)
  3. when you use it for some time you realize that hamcrest and pure junit offer very poor usability
  4. the assertions are a lot more readable then junit and hamcrest ones

Mockito basics by example

What is a mock object?

Mock is an object that simulates the behavior of a real object. We very often use those objects in tests.

When doing TDD we try to find the messages that are being send between objects that we create. Mocks are an easy way to simulate sending a message or checking if a message was received.

How does Mockito help do that?

Mockito helps us. We don’t have to write mock objects on our own. We can ask Mockito to create a mock object for us. Then we can program the mock object to behave in certain ways using Mockito helper methods. Please find a basic mockito instruction set demonstration below:

Recommended further reading: Mocks Aren’t Stubs

Testing logging to log files

Recommended reading before you read this article: Mockito basics

How do we test logging to logs?

We should not do that in general. The solution might be to test if notifications are being sent to support or diagnostic teams though. The implementation of those notifications might go to logs. For example:

A sample implementation of SupportTeam interface might look like this:

The examples above hide logging behind a SupportTeam interface. This seems to be a good modelling example of the real world scenarios. Who looks at the production logs in the real world? Support team in most cases. Then we should notify support team when exception occurs instead of logging to logs. The implementation of SupportTeam interface can log to logs though. Modelling the real world scenarios is in my opinion one of the key OO principles that people often forget about.

Please comment!

[Removing duplication in tests] (Part 1) Move wiring of objects to class attributes

Recommended reading before you read this article: Mockito basics

Hot to get rid of duplicated code in tests

When we have multiple tests and all of them have similar givens we are tempted to extract those common givens to setup method or the field declarations. This might be a good idea when those givens are just wiring of dependencies. In most other cases it might be not a good idea.
Below I include an example for correct removing duplication of “givens” for multiple tests. Moving wiring of objects in field declarations. This way we do not test the wiring in the test, just the business functionality. The wiring should be tested in acceptance or end to end tests, not on unit level.

The example below also replaces string constants with variable names. For example in the tests we don’t care that the username is “john”. We only care that the username passed around is the same object. So we can move the definition of username out of the test to increase readability.

Please note that all fields are marked as final. This ensures that all wiring was done before we start testing the user object.

Before refactor

After refactor

I have not found any other scenarios for removing duplication in tests by moving common code into set up methods or class attributes. All other scenarios where duplication occurs pointed to problems in production code and design issues. Please take a look at all other parts for further details (coming soon).

Please comment! 🙂

Testing time dependant functionalities

Recommended reading before you read this article: Mockito basics, Fest assertions.

How do we test time dependent operations?

Let us assume we have a report and it may me marked as complete. When it is marked as complete the “completed on” date should be set. The easiest approach would be to do a “new Date()” and assign it to “completed on” attribute.

But how do we test it? We have to take an other approach.
The solution is to introduce a Clock object that can be asked for the current time and which we will be able to mock in tests:

Recommended further reading: How NOT to test drive time dependant functionalities