TDD is like cooking (haha)

I want to make a comparison between my cooking, and my TDD. I started learning how to cook about the same time when I started learning TDD.

Let us discuss the leek soup I made loads of times :) The first time I made it I did not look at any recipes, I just followed my heart. It was awesome, tasted very good! The second time I made it, it was almost impossible to eat and I was wondering what happened. It was horrible. But I did everything almost exactly the same?
Then I started looking into the recipes and found that some things should be added to a leek soup and some not. Some spices are needed in a leek soup, some should be avoided. The ratio of water, leeks, butter was also a very important thing. Slight variations in those thing could make the soup very good or very bad. After following the recipe several times for couple of different soups I started to see the patterns. Even though I have still a lot to learn, I know a bit more how to make a good soup without a recipe. I just can see if it is going to be the kind of soup I like just by looking at the ingredients!

It more or less looks like I am in the third stage of competence when it comes to preparing a leek soup ;) haha

How did I get there? Using the tool called “recipes”!

How can you get to the next level of competence in software development? Using the tools and practicing as well. The best tool I have found so far is called TDD! Once you are competent you probably will not need the tool, you will just “feel” when something is good or not, you might find that it acctualy slows you down. But for beginners, TDD is in my opinion a very good way of working. Following the very simple rules of TDD allows you to unconsciously produce code that is more likely of high quality and compliant with the harder to understand rules of high cohesion and loose coupling. Following the very simple “red-green-refactor” and “test should be simple” rules is more likely to produce code that is compliant with the harder to understand (or easier misinterpret) SOLID rules, etc.

P.S.
The next tool I would recommend is pair-programming.

P.S. 2

I have just finished reading the new book by Robert C. Martin titled “The Clean Coder: A Code of Conduct for Professional Programmers”. Highly recommended! :)

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! :)

[Example] Top-down ATDD/TDD with acceptance tests covering third party API

What is ATDD?

ATDD is Acceptance Test Driven Development. In one short sentence: we start with an acceptance test that describes the functionality we want to implement from users point of view. Acceptance tests ideally should be “black box” tests. They should talk to the application only through the interfaces it exposes.

The story

We will implement a webservice that adds numbers and returns the result. Since we want to do the simplest thing possible we will use the Servlet API.

The acceptance test

We start with an acceptance test. It is an example expected behaviour of the system from users point of view. So in this case the user sends a request to our webservice to add two numbers and expects a result in return. Please notice we use Jetty embeded server to startup the application (the Application class and its start and stop methods):

We run the test. Since we don’t have any web app under that url we will get 404 NotFound response instead of 200 OK.
So we add a src/main/webapp directory with a web.xml file. That web.xml file should define a servlet so that we get a 200 response.

We create the servlet class as well:

We run the test. Now we get assertion error “Expected: ‘7’ Actual: ” “. So finally we can proceed to a unit test for our CalculatorServlet!

Start with a test:

Notice that we specyfy that the servlet class will be just an adapter. It extracts data from request, sends message to calculator and then stores the result in response. It does not do any calculations.
In this adapter we mock third party interfaces. The assumptions we made while mocking the method calls are verified in the end-to-end/acceptance test.

Notice that the tests uses “OPERANDS” constant that is defined in the production code. This is because the acceptance tests already test the paramater name. We do not want to have many test failed with the same reason. So we reduce the duplication in this case. Now the “operands” keyword is in the production class and in the acceptance test only.

No we can write the production code:

We run the unit test and it passes. But when we run the acceptance test it fails with RuntimeException on Calculator.add(). So we start with a test for it:

The test fails, so we implement the production code:

Now if we run the unit and acceptace test, ALL PASS!

Conclusions

We started with a black box acceptance test. We continued implementing the application parts only when we had a failing test with a clear error/assertion message. The third party API calls we mock in unit tests are testes also on acceptance level.

If you wish to get more from ATDD please take a look at acceptance test frameworks. There are many of them on the web. Recently I described one of them. Using those frameworks can save a lot of your time.

Please notice I was using totallylazy while implementing list operations. It is a functional library with lazy loading (cool math stuff, infinite sequences, fluent interface, …). For further information please look at totallylazy home page.

Please comment and subscribe to RSS! :)

[Example: Buy stocks] Yatspec quick start

New revisited version of example:

You can find a new revisited version of this example here.

Old version:

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 capturedInputAndOutputs. 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 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! :)

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.

Do not mock Value and Data Transfer Objects

Recommended reading before you read this article: Mockito basics

Mocking VOs and DTOs is harmful

When you write a test and need an instance of a Value Object or a Data Trasfer Object it is best to create a new instance of it instead of mocking it.

Mocking decreases readability and might cause more maintenance issues while refactoring. Mocking should be a way of learning about messages sent between objects. For further details please read Mocks Aren’t Stubs.

Please find an example below. Notice the huge difference in readability:

Your VOs and DTOs are probably immutable and some of them might even have no behaviour at all. There is no point in mocking them.