Tuesday, November 19, 2019

Enemy of the state

Many moons ago, I worked for a bank. When you wanted to manually test something, your options were limited. Creating accounts in the big old mainframe needed a COBOL engineer to manually insert data into the db to create a test account. These accounts were shared around the team on a spreadsheet. The most useful of which … belonged to a non-existent person named `Sandra Brown`.

I’m sure you can imagine happens next, collisions, loads of them, people adding and removing accounts. It was not a pleasant experience. Our integration tests on the other hand, had no problems whatsoever, backed by an embedded MySql database, their state was completely predictable.

Enter end to end tests, sitting at or near the top of the test pyramid, they are often unreliable, one contributing factor to this instability? State. Similar to the `Sandra Brown` problem, we end up creating a series of entities and use them around tests, often causing collisions, leaving junk data behind. Let me ask a question to those who write E2E tests, if I truncated every table in your test db (excluding lookup tables, it’s only fair), how many of your E2E Tests would fail due to be depending on some sort of state in your database.

Running end to end often involves the introduction of unreliable state into out test systems. Let’s look at a common situation. I’m working on an eCommerce rest backend and I need to write an end to end test that verifies that the `/{userId}/orders` endpoint correctly returns a list of the users previous orders.

Poor solution

  • Manually create a user, or use one that’s lying around
  • Manually setup a collection of orders
  • E2E test reads orders via API and asserts on the retrieved data


We’ve introduced 3 `states` to the system and a change to any will break the test

  1. The user. Changes to the state of the user outside of your test can interfere with the orders endpoint
  2. The orders. Changes to the state of an order can interfere with the orders endpoint
  3. The test. The test knows about both the user and the orders it needs to assert against


We can drastically improve the stability of our tests by introducing a few changes.

  • Create or allocate a new user each time. 
  • Set the state you want to assert against in your test.
  • Scrub all data associated with the user. 


Our improved solution:

  • Create a new user
  • Insert order records into your system
  • Execute the test
  • Delete both the user and records from the system. 

One of the major complaints against this approach is that the setup stage where information is inserted into a running system is slow and error prone. A partial cause of this instability is the reliance on clients to do both the setup and the execution of our tests. What if we only used the client for execution of our tests, but not the setup. Getting the system into the correct state is not the aim of the test, only a prerequisite step.

Does this make E2E testing completely stable or perfect? Nope. It’s a step closer though.

Tuesday, February 7, 2017

Reason #23 your acceptance tests are rubbish : Chekovs Gun



No, not that Chekov


[Ripped straight from the wikipedia article]
Remove everything that has no relevance to the story. If you say in the first chapter that there is a rifle hanging on the wall, in the second or third chapter it absolutely must go off. If it's not going to be fired, it shouldn't be hanging there.






It speaks to including unnecessary detail in acceptance criteria. Lets look at a simple example:

Given a list with 5 items
When I add a new Item
Then the list size should increase by 1

When you read this it implies that something special happens when you move between 5 and 6 elements, and if it does, then this criteria is completely valid. If nothing special happens, then it is misleading information. A simpler and clearer criteria would be :

Given a list
When I add a new Item
Then the list size should increase by 1

We don't really care how many items are there at the beginning, only that it increases by 1 when an element is added, the list can start with 0, 1 or more items, it's not important, so it's never mentioned.

Wednesday, July 13, 2016

Dogfooding Contract to test our internal tools

Our testing framework wouldn't be of any use to anyone else if we weren't willing to use it ourselves .... so, we went about dogfooding contract to test one of our internal tools.

A quick recap on Contract
Contract is an open source testing tool aimed at simplifying the testing of HTTP clients and servers, late stage integration testing is a nightmare that Contract is the perfect solution to. Server facing tests are be driven using a contract that specifies how the server is to react given a HTTP request. Client facing tests are be driven by an identical contract specifying that when a client makes a specific request, they should receive a specific response. With both sides of a client server relationship available for testing at a significantly earlier stage, we can improve the feedback of our testing cycles, and hopefully deliver value that little bit quicker.

What are we trying to test?
We have an application called Autodoc that we're eventually going to deploy to a servlet container. It exposes back end services via a REST API. We've a simple front end that acts as a UI to the back end services. We want the back end to be as stand alone as possible and maintain as high a degree of separation as possible from the front end. To that end, we will be doing no actual end to end testing of the application, we'll be leveraging Contract to test both halves of the application independently.  We use maven as a build tool and will be chaining together a few plugins to do the heavy lifting of our tests.

Step 1 : We use the maven cargo plugin to deploy our application, we override the connection details between the front and back end so we can introduce the contract server & client

Step 2 : Bring up a contract server for the front end to test against. This is the server the front end will actually be communicating with.




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<plugin>
    <artifactId>contract-maven-plugin</artifactId>
    <groupId>org.seekay</groupId>
    <version>${contract.version}</version>
    <executions>
        <execution>
            <id>client_facing_tests</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start-server</goal>
            </goals>
            <configuration>
                <gitSource>${git.url}</gitSource>
                <port>${back-end-port}</port>
                <username>${git.username}</username>
                <password>${git.password}</password>
            </configuration>
        </execution>
    </executions>
</plugin>

We're using our new 'start-server' maven goal to bring up a contract server that'll remain active until the maven build finishes.

Step 3 : Execute the front end tests. We're using Cucumber & selenium to test our front end backed by our Contract server. We're executing the tests with the surefire plugin, nothing special to see here. 

Step 4 : Execute the back end tests. We'll be using the Contract client to execute tests against the actual back end. 


<plugin>
    <artifactId>contract-maven-plugin</artifactId>
    <groupId>org.seekay</groupId>
    <version>${contract.version}</version>
    <executions>
        <execution>
            <id>server_facing_tests</id>
            <phase>integration-test</phase>
            <goals>
                <goal>run-client</goal>
            </goals>
            <configuration>
                <gitSource>
                    ${git.url}
                </gitSource>
                <target>http://localhost:${front-end-port}</target>
                <username>${git.username}</username>
                <password>${git.password}</password>
            </configuration>
        </execution>
    </executions>
</plugin>



And we end up with completely independent symmetrical testing of a client server application with Contract.  

Contract is available from Maven Central and docs from github pages  here
Contract is open source 


Monday, June 27, 2016

Behavioral testing with Contract 0.0.6

A single stateless contract is never going to go very far in testing a HTTP system, which is why with version 0.0.6 of Contact, we're very pleased to announce 2 game changing new features to our framework.

A quick recap on Contract
Contract is an open source testing tool aimed at replacing a companion system in a HTTP client or server relationship so that shared specifications can be used to unit, integration or acceptance level test to ensure that both systems are on the same page. Server facing tests can be driven using a contract that specifies how the server is to react given a HTTP request. Client facing tests can be driven by an identical contract specifying that when a client makes a specific request, they should receive a specific response. With both sides of a client server relationship available for testing at a significantly earlier stage, we can improve the feedback of our testing cycles, and hopefully deliver value that little bit quicker.

Setup 
Being able to specify a single request response as part of a contract can only test so much of a system. Multiple requests are often required to get the system into a state where assertions can be made. For example, to test read functionality of a system, something must be there to be read. In 0.0.6 we've introduced a setup block to our contract. This allows for specification of any number of setup calls to be made to ensure the system is in the correct state before the contract is actually verified.

The JSON below is an example of the create then read contract applied to our key value example system.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
{
  "info" : {
    "details": "The server should return a key-value pair for a valid get request"
  },
  "setup": [
    {
      "request": {
        "method": "POST",
        "path": "/kv/pair",
        "headers": {
          "content-type": "application/json"
        },
        "body": {
          "key": "weight",
          "value": "220lbs"
        }
      },
      "response": {
        "status": 201,
        "body": {
          "key": "weight",
          "value": "220lbs"
        }
      }
    }
  ],
  "request" : {
    "method" : "GET",
    "path" : "/kv/pair/weight"
  },
  "response" : {
    "status" : 200,
    "body" : {
     "key": "weight",
      "value": "220lbs"
   }
  }
}

This allows us to specify the creation of a key value pair before verifying the read functionality of the system



Variables and state
We introduced wildcards a few releases ago, allowing for specification of values when we didn't know exactly what they were going to be. With this release we're going a step further.

A common use case for testing a HTTP system is creation of a resource and then verification that said resource exists. Up until now, if that resource was assigned a unique id at creation time, we had no way of referring to this id and using it later. We're introducing variables to provide this exact functionality. 

Below is an example similar to the one above, its a contract for the creation of an entity on a server representing an unsecured git repository. The repository will be assigned a unique id at creation time and the id will then be used to verify that the repository information can be read. 



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
  "info" : {
    "details": "The server should accept the details of an unsecured repo and store them"
  },
  "setup" : [
    {
      "request": {
        "method": "POST",
        "path": "/services/repositories",
        "body": {
          "name": "kvServerContracts",
          "url": "https://github.com/harmingcola/kvServerContracts.git"
        }
      },
      "response": {
        "status": 201,
        "body": {
          "id": "${contract.var.positiveNumber.repoId}",
          "name": "kvServerContracts",
          "url": "https://github.com/harmingcola/kvServerContracts.git"
        }
      }
    }
  ],
  "request": {
    "method": "GET",
    "path": "/services/repositories/${contract.var.positiveNumber.repoId}"
  },
  "response": {
    "status": 200,
    "body": {
      "id": "${contract.var.positiveNumber.repoId}",
      "name": "kvServerContracts",
      "url": "https://github.com/harmingcola/kvServerContracts.git"
    }
  }
}

For more information on our variables expressions, have a look at our documentation here. Contract is available from Maven Central

Contract source

Thursday, May 19, 2016

Parameterising contracts for interaction driven development



This is a follow on post about Contract, if you've not read any of the previous posts, this should serve as a good introduction. 

Having to specify single contract per file is a little painful, especially if you have a few scenarios to be tested. Lets look at a simple example, imagine I want a contract to verify that an endpoint exists and the correct status code will be returned. 





 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "info" : {
    "details": "The server should return the correct status for an endpoint"
  },
  "request" : {
    "method" : "GET",
    "path" : "/service/car"
  },
  "response" : {
    "status" : 200
  }
}

If we wanted to expand on this to include multiple endpoints, we would need to duplicate a lot of configuration. With parameters, we can reuse the same contract multiple times.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "info" : {
    "details": "The server should return the correct status for an endpoint"
  },
  "parameters" : [
    {
      "endpointName" : "car",
      "expectedStatus": 200
    },
    {
      "endpointName" : "jeep",
      "expectedStatus": 200
    },
    {
      "endpointName" : "bicycle",
      "expectedStatus": 404
    },
    {
      "endpointName" : "pedestrian",
      "expectedStatus": 404
    }
  ],
  "request" : {
    "method" : "GET",
    "path" : "/service/${contract.parameters.endpointName}"
  },
  "response" : {
    "status" : "${contract.parameters.expectedStatus}"
  }
}


A client, fed this contract will execute 4 requests, one for each parameter group. A server, fed this contract, will expand it into 4 contracts.

Links:

Tuesday, May 10, 2016

Contract 0.0.4, delivering expressions

This week saw the release of Contract 0.0.4 and the first months stats from maven central. About 30 unique downloads, I'm chuffed if even half of those people who downloaded it actually used it. Ok, on to what we did this week.

Wildcard expressions:

Having to hard code absolutely everything is never going to be very good for testing systems. People don't want to have to fill out contracts in that level of detail. There are also times when people cant predict what will be returned when a request is made to a server. With that in mind, we added the wildcard expression functionality.

We'd dipped our toes into this functionality 2 releases ago with the ${contract.timestamp} in a limited amount. We've expanded on that in our 0.0.4 release to include strings and numbers. We've limited its use to within string fields within JSON bodies for now.

These wildcards can be used to replace parts of the path, query parameters, headers and body. Looking at an example, lets use an online streaming service, and an API endpoint that is used to register new content. Lets write the contract for creating a new TV show.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "request" : {
    "method" : "POST",
    "path" : "/webmovies/library/tvshow",
    "body" : {
     "name" : "Imprisioned Construction",
     "year" : "2005",
     "productionCompany" : "BOX"
    }
  },
  "response" : {
    "status" : 201,
    "body" : {
     "id" : "${contract.anyNumber}",
     "name" : "Imprisioned Construction",
     "year" : "2005",
     "productionCompany" : "BOX",
     "addedOn" : "${contract.timestamp}"
    }
  }
}

This contact specifies that when a POST request is made to the 'webmovies/library/tvshow' url with the body specified. Then the server will respond with the CREATED response code, the same body as was in the request enriched with id and addedOn fields.

We can create a contract for reading a TV show from the service where we know effectively nothing and the test server will fill in the blanks.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "request" : {
    "method" : "GET",
    "path" : "/webmovies/library/tvshow/${contract.anyString}"
  },
  "response" : {
    "status" : 200,
    "body" : {
     "id" : "${contract.anyNumber}",
     "name" : "${contract.anyString}",
     "year" : "${contract.anyNumber}",
     "productionCompany" : "${contract.anyString}",
     "addedOn" : "${contract.timestamp}"
    }
  }
}

Here any request valid request sent to the server will be given a valid response. 


Want to give it a try? Download our fat runnable jar from here and run it with :

1
java -jar contract-all-0.0.4.jar -s -p 9005 -g https://github.com/harmingcola/webmoviesContracts

Make a GET request to http://localhost:9005/__configure and the contracts loaded into that server will be listed.

Links:
Contract source
Contract docs
Webmovies contracts

Monday, May 2, 2016

Taking contract for a field test with Jenkins and Dashing

I've been working on Contract for a while now, and I'm starting to get that feeling that things are going a little too well on the build front ...... I want to take the project for a field test and see what happens.

The plan
I've been wanting to build a Dashing dashboard for my contract Jenkins builds. And instead of using and out of the box dashboard, I'd develop one myself. So, here our build pipeline :


Our code needs to pass through 5 stages before we're happy with it. However, to alert us to a problem, we want our dashboard to be red for any failure per project.

The Requirements
  • I want a Dashing dashboard for my Jenkins builds.
  • I want to display one tile per group of jobs.
    • Groups should be defined in the dashboard config.
    • If any job in the group is red, the group is red.
    • If all are green, the group is green.

The rules
  • Once i've the contract set, I cant go back to Jenkins. I can only develop the dashboard against the ContractServer. 

The Implementation

Before I can start with the dashboard I need to write my contracts. I have no idea what Jenkins payloads look like or what URLS to get them on. After having a look around I've decided to go with this endpoint /job/contract_build/lastBuild/api/json where 'contract_build' is the name of the job. 



Contracts have been written, one for each of my 5 build jobs for Contract, and another one to prove that the failure case works too. Because my builds are absolutely never never ever red.


Dashing projects aren't maven based, As part of Contract 0.0.3, well be releasing a fat runnable jar for running servers from the command line. Running the jar looks like :



I'm off to develop the dashboard, wish me luck ..... My ability to misspell 'Contract' as 'Contact' knows no bounds. Dashboard didn't take long to write. I know neither ruby nor coffeescript, so I've got that going for me. With the dashboard completed, I've got something that looks like the image below. This is exactly what we expect, all jobs in the contract group are green, and the 'interceptor_build' job in the interceptor group is failing.


Lets plug the dashboard into our real Jenkins and see what clicks.


Perfect!! Our contract group stays green because all the jobs are actually green. The interceptor group turns orange because it doesn't exist on our real Jenkins server. I think this can definitely be marked as a successful field test.

Contract docs are here and contract source is here.
Contract 0.0.3 has just been released to maven central. The stars of this release are certainly the maven plugins and fat jar. And by stars, I mean the only thing in the release

Thursday, April 28, 2016

I'm not the first person to have this problem

I'm going to try to post once a week to document what I'm doing with contract and anything else that happens to cross my mind ...... 

And because these blog posts look better with at least one photo.

Surely I'm not the first person to have this problem ???

This question has saved me more wasted effort and wheel re-inventing than any other. The ability to sit back, look at a problem and acknowledge the fact that people have come before us and that there is something to be learned from them. There's no place were this is truer than the software development industry. So, the next time you go to put finger to keyboard say to yourself "Am I the first person to have this problem??"  Often the answer is no. There's something we can reuse to make our lives a little easier. Then we can concentrate on the truly cool stuff we can build. 

How did we end up like this?? I can only speak for myself. I blame my college education. I'm not speaking ill of the Dublin Institute of Technology, they did a fantastic job of educating me. In college we were taught to do everything from scratch. You need something sorted, you wrote quick sort yourself, arrays we're used for everything and an IDE was the work of the devil. You leave college and you're presented with Java Collections and wonder why you were never taught about them. But that old mentality of 'Do everything yourself' was still there. So every chance you get. Ask yourself that one simple question and see where it leads you. 

Hows contract going?
Grand, ticking over nicely. I spent the weekend hardening my Jenkins pipeline to maven central (it was a little flaky, still is, the kvServer tests are a nightmare to run well), added the ability to handle current timestamps (it was an early feature request for servers that return the time a request was processed at). Allowing for bodies to be specified in native json as opposed to escaped strings. 

I'm going to aim to release once a week, lets see how that goes. 

Thursday, April 21, 2016

Introducing, Contract 0.0.1

Two years ago, I started asking myself that question "surely, I'm not the first person to have had this problem". I was working on a green field project and was looking for a better way to test the interaction between services that communicate over HTTP. I ended up using a project called Wiremock to replace one of the systems for testing and everything worked quite well. But it wasn't perfect.

A year ago, I found myself in the same position again. This time I stumbled across consumer driven contracts and pact-jvm. We were developing the server at the time and the client was being developed in another department we couldn't dictate their test approach. We build our own contract driven frame work on top of Wiremock and again, it worked quite well. But it wasn't perfect.

I started working on 'Contract' a few months ago. Replacing Wiremock with a embedded tomcat and using the lessons learned from both stalled attempts to build this tool. Contract will provide a contract-server that will respond based on the supplied contracts to a client system and a contract-client that will send requests and validate the responses from a server under development. Combine the two and you've got test symmetry.

After battling with Jenkins for the last 2 days, 'Contract' is now up in maven central. What it currently lacks in features, it makes up for in simplicity.


And now that the basics are in place, its feature time. Watch this spot for more features!!!

Wednesday, April 13, 2016

Testing the test tool

Going back to working on my HTTP contract testing tool, I've basically realized for the most part that I'm done!! Well, the minimal viable version is done. No bells and whistles just yet. So, why the lack of confidence in releasing it?

I've nothing in the region of acceptance tests. Over the last couple of years I've gotten exceedingly comfortable with this safety net to catch my numerous fuck-ups. My project is unit tested to an inch of its life. I'm comfortable that my coverage of 95% is exactly that, and worthwhile at the same time (maybe i'll add some mutation testing at some stage to see how accurate that 95% actually is).

In order to give myself that safety net and feel comfortable releasing my project I went about testing a test tool. Something I've never done before. A bit of background. Contract is a JVM testing tool designed to replace mocks and test clients in HTTP client server tests and provide identical yet separate test suites for both.

If I were testing a web-app, the first port of call would be to try to think like a user and use the system. Why not the same for a test library. I gave myself 2 users. A client and a server. I designed the simplest server I could think of, a server side map, send a key value pair it saves it for later retrieval. Paired with a client to provide java based access to the same server. I wrote the contracts to define expected behaviours. To follow my own best practices, I put the contracts in a third location so they were accessible to both.

The results: things didn't work exactly as i'd expected. My confident lack of confidence paid off again. Time to fix me some bugs!!!!

What went wrong exactly: when I left out the 'Content-Type' header the server responded with a 415. In the contract that defines this behaviour I left the body blank, I wasn't really concerned with what the body sent back, its usually garbage anyway. NullPointerException, bodies in the response of a contract are mandatory apparently.

Some links:
Contract: https://github.com/harmingcola/contract/
KvServer: https://github.com/harmingcola/kvServer
KvClient: https://github.com/harmingcola/kvClient
KvContracts: https://github.com/harmingcola/kvContracts
Docs: http://harmingcola.github.io/contract/index.html

Thursday, September 24, 2015

JPact, trundling towards an MVP

Simply put, consumer driven contracts are awesome. The ability to specify, control and version their interactions between a client and server is nothing less than godly. My only real problem is with the current implementations.

I'm not a big fan of them being client driven, mostly because I'm happiest in a collaborative setting. Lets agree a contract and work from there. If both client and server stick to the contract then happy days.

Which is why I started writing jPact. jPact is pretty close to a client driven contract framework without the client driven part. Everything starts with the contract, a JSON file specifying an interaction between client and server. If everyone does their job, both client and server behave exactly as laid out in the pact file.

The code isn't in a massively working state. but its slowly trundling towards a minimal viable testing product. I suppose i'd better do some more work.

Anywho : heres the source so far if anyone's interested

Thursday, May 7, 2015

How to setup docker as a development tool OSX

  • Install Virtualbox
  • Assuming you have Brew installed, install boot2docker
  • If you use a proxy to connect to the internet, Implement transparent proxying (this'll be a bit of work, and worthy of a blog post of its own)
  • Setup your internal networking to allow direct access to containers
    • In the Global settings of Virtual box, add a second 'host-only-network', and give it these settings:
      • ipv4 address : 172.16.0.1
      • ipv4 network mask : 255.255.255.0
      • ipv6 address : blank
      • ipv6 network mask length  : 0
      • Uncheck DHCP server
    • In the settings of the boot2docker vm, add the host only adapter we created in the last step as 'Adapter 3'
    • Start the boot2docker vm, adding the environment variables as instructed
    • Remote onto the boot2docker vm and run the following
      • sudo ifconfig eth2 172.16.0.11
      • sudo ifconfig eth1 netmask 255.255.0.0
    • On your mac, run the following
      • sudo route -n add 172.17.0.0/16 $(boot2docker ip)
    • Bring up a test container :
      • docker run -t -i ubuntu /bin/bash
    • The containers should now be network accessible, to test this, in another terminal run
      • docker inspect
      • There'll be an IP address in the output, it should be ping-able
  • We'll use skydock / skydns to provide accessible host names for the containers
    • docker run -d -p 53:53/udp --name skydns crosbymichael/skydns -domain docker
    • docker run -d -v /var/run/docker.sock:/docker.sock --name skydock crosbymichael/skydock -ttl 30 -environment dev -s /docker.sock -domain docker -name skydns
  • To route all dns requests for the docker domain to a skydock/skydns server, run the following
    • sudo echo "nameserver 192.168.59.103" > /etc/resolver/docker
  • Docker containers should now be available at addresses in the form of, . .dev.docker i.e. rabbitmq01.rabbitmq.dev.docker
  • If multiple containers are running with the same image, they can be loadbalanced with .dev.docker i.e.  rabbitmq.dev.docker

Friday, February 27, 2015

Groovy closures and Awaitility are a match made in heaven

The awaitility pattern for waiting for a condition to be true has always irked me, it's always seemed like something that should be shorter and simpler. If you want to implement a wait in awaitility, you implement a callable interface and hand that off to awaitility to call repeatedly until its satisfied or times out. Giving you code that looks something like this …
Steps.java
@Then("a payload is sent to the destination")
public void aPayloadIsSentToTheDestination() throws Exception {
   PayloadIsSentChecker aPayloadIsSent = new PayloadIsSentChecker(acceptanceTestAmqpClient, Destination.EXAMPLE);
   await().atMost(FIVE_SECONDS).until(aPayloadIsSent);
}
PayloadIsSentChecker.java
public PayloadIsSentChecker(AcceptanceTestAmqpClient acceptanceTestAmqpClient, Destination destination) {
   this.acceptanceTestAmqpClient = acceptanceTestAmqpClient;
   this.destination = destination;
}

@Override
public Boolean call() throws Exception {
   Message message = acceptanceTestAmqpClient.lastMessageFromAcceptanceOutbound(destination);
   if (message == null) {
      return false;
   }
   return true;
}
However, if we bypass the callable interface entirely and use a groovy closure, with a mixin [AwaitilitySupport] from awaitility instead, we get
def thePayloadArrivesAt(Destination destination) {
   await().atMost(FIVE_SECONDS).until {
      assertThat(acceptanceTestAmqpClient.lastEventFromAcceptanceOutbound(destination), notNullValue())
   }
}
And voila, a significant reduction in boiler plate code.

Monday, November 4, 2013

A handy hack for getting around Java type erasure

Once a Java class is compiled, any generic information is lost. Meaning that an ArrayList of Cars at runtime becomes an ArrayList and the fact that it stores Cars is lost.

There is a way around it, if you have access to the class or object that contains that ArrayList.

Lets take a simple domain object that contains a list : 
public class Domain {

 private List myList = new ArrayList();

 // Access methods removed
 
}
This class contains the list we want to inspect, the maguffin we're searching for. If we run that class through this inspector :
public class TypeInspector {

 public void inspect(Class clazz) {
  for(Field field : clazz.getDeclaredFields()) {
   if(isCollection(field)) {
    inspectType(field);
   } 
  }
 }
 
 private void inspectType(Field field) {
  String rawType = field.getGenericType().toString();
         rawType = rawType.substring(rawType.indexOf('<') + 1);
         rawType = rawType.substring(0, rawType.length() - 1);
           
         try {
   System.out.println(Class.forName(rawType));
  } catch (ClassNotFoundException e) {
   System.out.println("Couldnt find "+ rawType);
  }
 }

 private boolean isCollection(Field field) {
  return Collection.class.isAssignableFrom(field.getType());
 }
}

This inspector can retrieve the generic type from the field in the class that contains it. Parse the String description of the generic type to remove the ArrayList details which will give us our Maguffin.

Monday, July 22, 2013

A simple way to avoid a lot of null pointers

This is something I see all the time and a slight code change can remove a lot of null pointer exceptions.

public class NullExample {

 private static final Integer ZERO = 0;
 
 public static void main(String args[]) {
  
  //Bad Way
  System.out.println("1 -> " + checkEqualToZeroPoor(1));
  System.out.println("0 -> " + checkEqualToZeroPoor(0));
  try {
   checkEqualToZeroPoor(null);
  } catch(NullPointerException e) {
   System.out.println("Null throws an exception");
  }
  
  // Good Way
  System.out.println("1 -> " + checkEqualToZeroGood(1));
  System.out.println("0 -> " + checkEqualToZeroGood(0));
  try {
   System.out.println("Null -> " + checkEqualToZeroGood(null));
  } catch(NullPointerException e) {
   System.out.println("This should never be reached");
  }
 }
 
 public static boolean checkEqualToZeroPoor(Integer value) {
  // A null pointer exception will be thrown
  return value.equals(ZERO);
 }
 
 public static boolean checkEqualToZeroGood(Integer value) {
  // Should return false on null
  return ZERO.equals(value);
 }
}

In the 'poor' example, the parameter's .equals method is being used to check equality with our static value. By switching these two we can ensure that the object on which the .equals method is always initialized and never null.

Granted, this example ignores the third case, which gives the same result as the better method but is not advisable.


// Worse way
System.out.println("1 -> " + (1 == ZERO));
System.out.println("0 -> " + (0 == ZERO));
System.out.println("null -> " + (null == ZERO));

While this might seem incredibly basic, it still happens on a daily basis




Monday, July 15, 2013

The Broken Window Theory

The 'Broken Window' is a theory in criminology regarding urban disorder and vandalism

Quoted from wikipedia :
Consider a building with a few broken windows. If the windows are not repaired, the tendency is for vandals to break a few more windows. Eventually, they may even break into the building, and if it's unoccupied, perhaps become squatters or light fires inside.
This translates very well to  software development, as soon as minor smells are introduced, these 'Broken Windows' start to multiply until there is massive backlog of neglect that need to be fixed. 

Quoted from Coding Horror:
Don't leave "broken windows" (bad designs, wrong decisions, or poor code) unrepaired. Fix each one as soon as it is discovered. If there is insufficient time to fix it properly, then board it up. Perhaps you can comment out the offending code, or display a "Not Implemented" message, or substitute dummy data instead. Take some action to prevent further damage and to show that you're on top of the situation.We've seen clean, functional systems deteriorate pretty quickly once windows start breaking. There are other factors that can contribute to software rot, and we'll touch on some of them elsewhere, but neglect accelerates the rot faster than any other factor.
 Places I stole the quotes from :
http://www.codinghorror.com/blog/2005/06/the-broken-window-theory.html
http://en.wikipedia.org/wiki/Broken_windows_theory

Friday, July 12, 2013

How clean is your code?

A big part of programming anything is that its readable to the next person who comes along and reads it. Remember that code is read far more times than its written.

Lets take a fairly well known problem as an example. The FizzBuzz problem :

Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz".

And a basic implementation of the solution :

public class FizzBangDirty {

public static void main(String[] args) {
for(int i=1; i< 101; i++) {
System.out.print(i + " ");
if(i % 3 == 0){
System.out.print("Fizz");
}
if(i % 5 == 0){
System.out.print("Buzz");
}
System.out.print("\n");
}
}
}

The solution in it self doesn't  read particularly well. 

  • The main method is 9 lines long, arguably too long
  • At no point does the method state what its doing, only how it's doing it. 

How about a cleaner solution :

public class FizzBangDirty {

private static final int START_VALUE = 1;
private static final int END_VALUE = 100;
public static void main(String[] args) {
for(int i=START_VALUE; i<= END_VALUE; i++) {
printCurrentValue(i);
printFizzBang(i);
}
}

private static void printFizzBang(int i) {
printFizz(i);
printBang(i);
printNewLine();
}

private static void printBang(int i) {
if(multipleOfFive(i)){
System.out.print("Buzz");
}
}
private static void printFizz(int i) {
if(multipleOfThree(i)){
System.out.print("Fizz");
}
}
private static void printCurrentValue(int i) {
System.out.print(i + " ");
}

private static void printNewLine() {
System.out.print("\n");
}

private static boolean multipleOfThree(int i) {
return i % 3 == 0;
}

private static boolean multipleOfFive(int i) {
return i % 5 == 0;
}
}

The cleaner solution has a few downsides :
  • Its twice as long.
  • Throws reuse out the window.

What it lacks in brevity, its makes up for in explicitly explaining what its intention is for each line of code, not just what its trying to accomplish.

Noteworthy points :
  • The for loop explicitly states what is being done on each value in the loop
  • The conditions in every if() are a method call, it allows the line to read like an English sentence, giving it far more meaning. So 'if(multipleOfFive(i))' reads simply as 'if multiple by 5' . It also allows the code to be written in the language that descrbed it in the first place.
  • No method is longer than 3 lines long.
  • There is only 1 public method. Implying that there is only 1 important part of this solution. The rest are just supporting, and can be ignored until necessary to pay closer attention to them.




Wednesday, December 12, 2012

Creating a Fat Executable Jar with the maven Shade Plugin

So here's a quick walk through of a Maven project that will assemble into a runnable fat jar. A Simple Class with a 'public static main' will be our Main-Class.

The Main-Class


package org.seekay.main;

import com.sun.jersey.api.core.ApplicationAdapter;

public class TestMain {

public static void main(String[] args) {
for(int i=0; i< 100; i++) {
System.err.println("Line "+ i);
}
ApplicationAdapter adapter = new ApplicationAdapter(null);
}
}

I've chosen a class at random from the Jersey-Server jar to be our external dependency to ensure that the external code is being packaged correctly.


The Pom

Including the 'maven-shade-plugin will cause all the dependencies listed in the pom to be unpacked into  our fat jar.


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>


package

shade



implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>org.seekay.main.TestMain</mainClass>






<finalName>${artifactId}-${version}</finalName>

</plugin>

To use a different main class, simply change the 'mainClass' attribute in the example above to be the fully qualified name of whichever class you'd like to use.

When you run 'maven clean install' your package will be built containing all the dependencies required by your project. Running 'java -jar UberJarTestProject-0.0.1-SNAPSHOT.jar' will invoke the main class and start the application. In our example a null pointer is thrown in the construction of the 'ApplicationAdapter' class, showing that it has been included.

Download Project