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] 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! 🙂