[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.

Do not mock third party classes

Recommended reading before you read this article: Mockito basics

Mock only your classes. Do not ever mock external third party classes.

When you create a mock object and tell it to behave in a certain way you make assumptions about the class you are mocking. If you are going to implement the class that you just mocked, that is perfect, it is what you need. You have a set of requirements for the new class.

If you mock a third party class you make those assumptions about an already existing class that is not yours. Your assumptions may be wrong. Yours assumptions can be right but the class might change and your assumptions can get out of date. These are the main reasons you should never mock an external class.

The right way to solve this issue is to have end-to-end and/or acceptance tests that cover critical paths through the system. Those tests should use those third party classes/jars/… In that case you can get fair coverage and tell if the third party software behaves in the way you expect it to.

EDIT 3 Sep 2011:
Please take a look at my example of how to do end to end testing on unit-mocked third party APIs.

Start from the end

Recommended reading before you read this article: Fest assertions.

Lets assume we want to create a calculator. That calculator will be able to add numbers, so the result of 3+4 should be 7. Please notice that we just expressed an expectation from our calculator.

In most cases I found that starting writing tests from the end is the best way to go. Start from what you expect.

For example:

Stage 1, specify the output, start with the expectation (will not compile)

Stage 2, express what actually has to happen to get to the expectation

Stage 3, make the test pass.

Try to always start with writing one or more assertThat() or verify(). Then proceed to the other parts of the test.This forces you to think about what you actually want to achieve rather then concentrate on implementation and other distractions. I know this example might be too simple to see the benefits clearly unfortunately. It was just to demonstrate the process. Try to implement this process in your projects and you will see the benefits.

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