Confitura 2013 afterthoughts

Confitura, the biggest free-of-charge Java conference in Europe, took place on the 6th of July in Warsaw. TouK’s presence was heavy, with 5 separate talks, all chosen in call for papers, no sponsored bullshit. We were sponsoring deck chairs during the…Confitura, the biggest free-of-charge Java conference in Europe, took place on the 6th of July in Warsaw. TouK’s presence was heavy, with 5 separate talks, all chosen in call for papers, no sponsored bullshit. We were sponsoring deck chairs during the…
Confitura, the biggest free-of-charge Java conference in Europe, took place on the 6th of July in Warsaw. TouK’s presence was heavy, with 5 separate talks, all chosen in call for papers, no sponsored bullshit. We were sponsoring deck chairs during the conference, and beer on the after-party, though. Both were quite popular. Oh, and we had Bartek Zdanowski with TouK Lab, doing funny things with lights, Jenkins, and raspberry-pi.

Last year, together with Tomasz Przybysz, I had a talk about Groovy and Grails. This year I had the pleasure of presenting revised Test Driven Traps.

Now, this wasn’t the same talk I had in Tallinn. In fact, I rewrote most of it, with three major changes.

While at first I was focused on three goals of TDD (security, design, feedback), I’ve noticed that I underestimate the value of communication. The funny thing is, I do use TDD in that manner frequently, it just didn’t appear to me as very important. Which, as an afterthought, was a big mistake.

Perhaps the reason for it, is how people distinguish between TDD, BDD (Behaviour Driven Development) and ATDD (Acceptance Test-Driven Development). I use Spock most of the time, and Spock mixes all three approaches very well. To be quite honest, I’ve been mixing all three of them in every testing tool I ever had. Whether my tests looks more like BDD or ATDD (that is, had more emphasis on communication and specification) depends on the nature of the project, and the nature of my client. Technology is not a problem here. It just used to be more awkward to write down user stories as a tests, in languages which were not as flexible as Groovy.

I had a lot of success using tests as a communication tool. Both internally, with developers, including myself while returning to an old code base, and with external clients. But I also had some failures.

A few months ago, while doing a mobile banking project, I had a session with a domain expert. We were trying to get to the bottom of fees and pricing in a specific payment scenario. While we were siting and talking, I wrote down a simple specification

static Closure fixed = {BigDecimal value -> new FixedFeeAddedCalculator(value: value)}
static Closure percentage = {BigDecimal value -> new PercentageFeeCalculator(value: value)}

def "should calculate fees"() {
    given:
        biller.feeCalculator = billerFeeType.call(billerFee)
        biller.feesForChannels = [new FeePerChannel(channel: Channel.USSD, feeCalculator: channelFeeType.call(feeForChannel))]
        biller.feesForPrefixes = [new FeePerPrefix(msisdnPrefix: "123", feeCalculator: prefixFeeType.call(feeForPrefix))]
    when:
        BillerFees billerFees = biller.calculateFees(productPrice, "1234", Channel.USSD)
    then:
        billerFees.total + productPrice == totalMoneyPaid
        billerFees.feeForChannel == feeForChannelPaid
        billerFees.feeForPrefix == feeForPrefixPaid
    where:
        productPrice | feeForChannel | channelFeeType | feeForPrefix | prefixFeeType | billerFee | billerFeeType || totalMoneyPaid | feeForChannelPaid | feeForPrefixPaid | feeForBillerPaid
        100          | 7             | fixed          | 3            | fixed         | 10        | fixed         || 120            | 7                 | 3                | 10
        100          | 7             | percentage     | 3            | percentage    | 10        | percentage    || 120            | 7                 | 3                | 10
        123.4        | 10            | percentage     | 10           | percentage    | 10        | percentage    || 160.42         | 12.34             | 12.34            | 12.34
        123.45       | 10            | percentage     | 10           | percentage    | 10        | percentage    || 160.47         | 12.34             | 12.34            | 12.34
        123.45       | 10.05         | percentage     | 10.05        | percentage    | 10.05     | percentage    || 160.68         | 12.41             | 12.41            | 12.41
        100.99       | 0.99          | percentage     | 9.99         | percentage    | 0.09      | percentage    || 112.17         | 1                 | 10.09            | 1
        100.99       | 0             | percentage     | 0            | fixed         | 0.01      | percentage    || 101.00         | 0                 | 0                | 0.01
        10           | 0             | fixed          | 0            | fixed         | 100       | fixed         || 110.00         | 0                 | 0                | 100
}

Those static fields/closures are a little hack, so that I’m able to use something more readable in the ‘where’ clause, than a ‘new’ with the name of the class. After we confirmed, that it looks OK, but we don’t really know whether this is accurate, I just copied the ‘where’ part with a little description, and sent it to the bank for confirmation. It looked pretty much like what the bank likes to send with their requirements. The expert was happy with this, I was happy with this, we’ve had that working for us before.

No word about fees and pricing has been heard from them since. And that’s about six months now.
Which shows, that no matter how good your tools are, no matter how smart domain experts are, if you have a fundamental problem with communication with your client, you are doomed anyway. And working through a proxy with clients from another continent, all I have are problems in communication. The technology is simple and easy, compared to that.

But I digress, I do encourage you to think of tests as a communication tool. It’s a blast when it works. And it does help a lot with keeping our domain knowledge up to date. Something requirement documents fail miserably to do.

The thing I do not know, is whether it is better to keep specifications and user stories separate from the rest of your tests or not. I’ve tried both approaches, but I don’t have any conclusion yet.

I also added a few simple thought on domain setup, to my presentation. Most systems need some domain objects before even unit tests will run. You can create that step by step, calling each constructor in every test, but this soon becomes a DRY violation, and a pain in the ass, as the domain gets more complex. Not to mention refactoring problems. A simple factory helps, but doesn’t change that much, so in my experience, the best way it to have your aggregate roots built in a single class, preferably using the same builders you use in production code (if you use any). This kind of setup definitely simplifies writing new tests, and is trivial to refactor.

But that’s most useful for unit tests. For integration tests, there are three approaches I’m aware of. The first one is the ‘go crazy, copy data from production’. Fortunately, this is possible only if you join an existing project, that had no tests before, so I’ll just skip that, as I am inherently incompatible with such situations. The other two are more practical.

You can have an empty database (you can even create it on the fly), where every test has to provide the data (domain objects) required for itself, or you can have a prepopulated database, with a precise set of data, representing some sample domain objects, and have that reflected in your test code in form of static finals. In both approaches, a rollback (for transactional Dbs) or a manual clean-up (for everything else) keeps the database at the initial state.

Everybody seems to prefer an empty database. But a prepopulated database has two great advantages: it usually simplifies test setups, and may have big impact on test performance. Just a few weeks ago I switched one of our projects to use the prepopulated database, and saved 15 seconds of test time.
15 seconds may not look like much, but our integration tests run now in 1m30s. I’ve saved another 2 seconds, by removing an ugly sleep in one test, and I can save a few more seconds, by just not being wasteful.

And that brings me to the next change in my presentation. I’ve pointed out the importance of performance in TDD. You have 30 seconds for unit tests, before you loose the patience of a developer. Make your tests run more than 3 minutes, and devs will only run them before push to the repo. Make them even longer, and nobody’s gonna care about tests anymore.

This is a single reason, why I thing GORM (Grails object-relational mapping) is not good enough for bigger projects. Grails use Active Record pattern, with a nifty mocking of database access methods via @Mock annotation, for unit tests. But with a complex domain and large aggregate roots, you get a heavy performance hit because of those annotations, and you end up with unit tests having half the speed of integration tests.

And that’s pretty bad. I have ~900 unit tests running in about 2.5 minutes, on i7. And most of that is due to @Mock annotations. I could bring it down to less than 30 seconds, if I could mock those bastard database calls the normal way, but with active record, I would either have to do meta-programming, or go into mixins and categories. The first option is error-prone, the second very cumbersome. Both are probably inefficient. Comparing the amount of work required to make those unit tests fast, with mocking a simple repository interface, puts all the other benefits of Grails active record into question. My conclusion is to not use GORM, if I’m going for anything more than 300 man-days. Or not use Grails altogether.

Those conclusions are kind of obvious, I suppose. The reason why I don’t see them used too often, is because people do not treat tests as a normal object (or functional) oriented code. That at least was my excuse for years and years, till I finally found out, this approach ends up in unmaintainable test code, that keeps you production code from ever being refactored as well.

And that’s pretty much all of my presentation changes.

Confitura 2013 was a fantastic experience. I am usually scared shitless, when giving a talk at a conference. Somehow, maybe because I know a lot of people on the audience personally, I’m less scared in here. During the first half of this year, I gave 6 talks, led two workshops, helped organize Warsaw Java User Group, and wrote a book. Confitura was a great finish for that marathon. Now I need a summer break.

You May Also Like

Spock basics

Spock (homepage) is like its authors say 'testing and specification framework'. Spock combines very elegant and natural syntax with the powerful capabilities. And what is most important it is easy to use.

One note at the very beginning: I assume that you are already familiar with principles of Test Driven Development and you know how to use testing framework like for example JUnit.

So how can I start?


Writing spock specifications is very easy. We need basic configuration of Spock and Groovy dependencies (if you are using mavenized project with Eclipse look to my previous post: Spock, Java and Maven). Once we have everything set up and running smooth we can write our first specs (spec or specification is equivalent for test class in other frameworks like JUnit of TestNG).

What is great with Spock is fact that we can use it to test both Groovy projects and pure Java projects or even mixed projects.


Let's go!


Every spec class must inherit from spock.lang.Specification class. Only then test runner will recognize it as test class and start tests. We will write few specs for this simple class: User class and few tests not connected with this particular class.

We start with defining our class:
import spock.lang.*

class UserSpec extends Specification {

}
Now we can proceed to defining test fixtures and test methods.

All activites we want to perform before each test method, are to be put in def setup() {...} method and everything we want to be run after each test should be put in def cleanup() {...} method (they are equivalents for JUnit methods with @Before and @After annotations).

It can look like this:
class UserSpec extends Specification {
User user
Document document

def setup() {
user = new User()
document = DocumentTestFactory.createDocumentWithTitle("doc1")
}

def cleanup() {

}
}
Of course we can use field initialization for instantiating test objects:
class UserSpec extends Specification {
User user = new User()
Document document = DocumentTestFactory.createDocumentWithTitle("doc1")

def setup() {

}

def cleanup() {

}
}

What is more readable or preferred? It is just a matter of taste because according to Spock docs behaviour is the same in these two cases.

It is worth mentioning that JUnit @BeforeClass/@AfterClass are also present in Spock as def setupSpec() {...} and def cleanupSpec() {...}. They will be runned before first test and after last test method.


First tests


In Spock every method in specification class, expect setup/cleanup, is treated by runner as a test method (unless you annotate it with @Ignore).

Very interesting feature of Spock and Groovy is ability to name methods with full sentences just like regular strings:
class UserSpec extends Specification {
// ...

def "should assign coment to user"() {
// ...
}
}
With such naming convention we can write real specification and include details about specified behaviour in method name, what is very convenient when reading test reports and analyzing errors.

Test method (also called feature method) is logically divided into few blocks, each with its own purpose. Blocks are defined like labels in Java (but they are transformed with Groovy AST transform features) and some of them must be put in code in specific order.

Most basic and common schema for Spock test is:
class UserSpec extends Specification {
// ...

def "should assign coment to user"() {
given:
// do initialization of test objects
when:
// perform actions to be tested
then:
// collect and analyze results
}
}

But there are more blocks like:
  • setup
  • expect
  • where
  • cleanup
In next section I am going to describe each block shortly with little examples.

given block

This block is used to setup test objects and their state. It has to be first block in test and cannot be repeated. Below is little example how can it be used:
class UserSpec extends Specification {
// ...

def "should add project to user and mark user as project's owner"() {
given:
User user = new User()
Project project = ProjectTestFactory.createProjectWithName("simple project")
// ...
}
}

In this code given block contains initialization of test objects and nothing more. We create simple user without any specified attributes and project with given name. In case when some of these objects could be reused in more feature methods, it could be worth putting initialization in setup method.

when and then blocks

When block contains action we want to test (Spock documentation calls it 'stimulus'). This block always occurs in pair with then block, where we are verifying response for satisfying certain conditions. Assume we have this simple test case:
class UserSpec extends Specification {
// ...

def "should assign user to comment when adding comment to user"() {
given:
User user = new User()
Comment comment = new Comment()
when:
user.addComment(comment)
then:
comment.getUserWhoCreatedComment().equals(user)
}

// ...
}

In when block there is a call of tested method and nothing more. After we are sure our action was performed, we can check for desired conditions in then block.

Then block is very well structured and its every line is treated by Spock as boolean statement. That means, Spock expects that we write instructions containing comparisons and expressions returning true or false, so we can create then block with such statements:
user.getName() == "John"
user.getAge() == 40
!user.isEnabled()
Each of lines will be treated as single assertion and will be evaluated by Spock.

Sometimes we expect that our method throws an exception under given circumstances. We can write test for it with use of thrown method:
class CommentSpec extends Specification {
def "should throw exception when adding null document to comment"() {
given:
Comment comment = new Comment()
when:
comment.setCommentedDocument(null)
then:
thrown(RuntimeException)
}
}

In this test we want to make sure that passing incorrect parameters is correctly handled by tested method and that method throws an exception in response. In case you want to be certain that method does not throw particular exception, simply use notThrown method.


expect block

Expect block is primarily used when we do not want to separate when and then blocks because it is unnatural. It is especially useful for simple test (and according to TDD rules all test should be simple and short) with only one condition to check, like in this example (it is simple but should show the idea):
def "should create user with given name"() {
given:
User user = UserTestFactory.createUser("john doe")
expect:
user.getName() == "john doe"
}



More blocks!


That were very simple tests with standard Spock test layout and canonical divide into given/when/then parts. But Spock offers more possibilities in writing tests and provides more blocks.


setup/cleanup blocks

These two blocks have the very same functionality as the def setup and def cleanup methods in specification. They allow to perform some actions before test and after test. But unlike these methods (which are shared between all tests) blocks work only in methods they are defined in. 


where - easy way to create readable parameterized tests

Very often when we create unit tests there is a need to "feed" them with sample data to test various cases and border values. With Spock this task is very easy and straighforward. To provide test data to feature method, we need to use where block. Let's take a look at little the piece of code:

def "should successfully validate emails with valid syntax"() {
expect:
emailValidator.validate(email) == true
where:
email }

In this example, Spock creates variable called email which is used when calling method being tested. Internally feature method is called once, but framework iterates over given values and calls expect/when block as many times as there are values (however, if we use @Unroll annotation Spock can create separate run for each of given values, more about it in one of next examples).

Now, lets assume that we want our feature method to test both successful and failure validations. To achieve that goal we can create few 
parameterized variables for both input parameter and expected result. Here is a little example:

def "should perform validation of email addresses"() {
expect:
emailValidator.validate(email) == result
where:
email result }
Well, it looks nice, but Spock can do much better. It offers tabular format of defining parameters for test what is much more readable and natural. Lets take a look:
def "should perform validation of email addresses"() {
expect:
emailValidator.validate(email) == result
where:
email | result
"WTF" | false
"@domain" | false
"foo@bar.com" | true
"a@test" | false
}
In this code, each column of our "table" is treated as a separate variable and rows are values for subsequent test iterations.

Another useful feature of Spock during parameterizing test is its ability to "unroll" each parameterized test. Feature method from previous example could be defined as (the body stays the same, so I do not repeat it):
@Unroll("should validate email #email")
def "should perform validation of email addresses"() {
// ...
}
With that annotation, Spock generate few methods each with its own name and run them separately. We can use symbols from where blocks in @Unroll argument by preceding it with '#' sign what is a signal to Spock to use it in generated method name.


What next?


Well, that was just quick and short journey  through Spock and its capabilities. However, with that basic tutorial you are ready to write many unit tests. In one of my future posts I am going to describe more features of Spock focusing especially on its mocking abilities.

Private fields and methods are not private in groovy

I used to code in Java before I met groovy. Like most of you, groovy attracted me with many enhancements. This was to my surprise to discover that method visibility in groovy is handled different than Java!

Consider this example:

class Person {
private String name
public String surname

private Person() {}

private String signature() { "${name?.substring(0, 1)}. $surname" }

public String toString() { "I am $name $surname" }
}

How is this class interpreted with Java?

  1. Person has private constructor that cannot be accessed
  2. Field "name" is private and cannot be accessed
  3. Method signature() is private and cannot be accessed

Let's see how groovy interpretes Person:

public static void main(String[] args) {
def person = new Person() // constructor is private - compilation error in Java
println(person.toString())

person.@name = 'Mike' // access name field directly - compilation error in Java
println(person.toString())

person.name = 'John' // there is a setter generated by groovy
println(person.toString())

person.@surname = 'Foo' // access surname field directly
println(person.toString())

person.surname = 'Bar' // access auto-generated setter
println(person.toString())

println(person.signature()) // call private method - compilation error in Java
}

I was really astonished by its output:

I am null null
I am Mike null
I am John null
I am John Foo
I am John Bar
J. Bar

As you can see, groovy does not follow visibility directives at all! It treats them as non-existing. Code compiles and executes fine. It's contrary to Java. In Java this code has several errors, pointed out in comments.

I've searched a bit on this topic and it seems that this behaviour is known since version 1.1 and there is a bug report on that: http://jira.codehaus.org/browse/GROOVY-1875. It is not resolved even with groovy 2 release. As Tim Yates mentioned in this Stackoverflow question: "It's not clear if it is a bug or by design". Groovy treats visibility keywords as a hint for a programmer.

I need to keep that lesson in mind next time I want to make some field or method private!