maxheapsize.com test it. code it. ship it.

Lightweight Web Prototyping for the Framework Loving (Java) Developer

Posted on | Comments

A couple of month ago I had an idea for a small web app. But what does it take to do it ? Do you start with the back end or the front end (read server or client side) ? Typically I would start at the back end, get the domain right and then see how I can fit the UI in. If a programmer starts this way you end with the typical ‘the programmer did the GUI’ scenario. That’s not really what I wanted. Don’t think too much about the domain, just see what the needs of the end user are and get the UI done (right).

How We Switched From Subversion to Git

Posted on | Comments

So I heard about these strange distributed version control systems like over a year ago. I used it in my own little projects and everything went smoothly and I really liked it. The idea also caught on at work and my team started a using Git in a fresh project last summer. We did not had so much problems since you can use Git very much like a central vcs like Subversion if you want to.

Still, for all other code, we used Subversion. We believe in agile and feature branches, so that’s what we do a lot. Every story has its own branch. If one story touches multiple code bases, that means multiple merge down/copy up’s.
At some point, in preparation for a sprint review, we found that code had disappeared from the trunk. Everything seems to work perfectly, just this feature was missing. Usually you would think if code was deleted, there would be at least one test failing and telling you that something is missing. But no, typing one wrong version number during merge down/copy up cut out the story very cleanly. Once we found the problem we could merged it back in from the not yet deleted feature branch. Overall we managed to work with Subversion but it was a growing pain since we knew there was something better.

There are several advantages of distributed version control system which you all might have heard of already so I won’t go in to detail of this (of course there is also one major disadvantage: complexity). The main advantages for me are:

5 Code Metrics You Need to Watch

Posted on | Comments

Developing software ain’t easy.

How do you know how you are doing ?

You could start collecting metrics about your code. These can give you some indication how maintainable and reliable it is.

The metric which come to mind to the most people is code coverage. Some people say it must be near 100%, other say 80% is a good number. At the end it can’t tell you if you are doing great or good. The only thing you might read from it is that a low number indicates a potential problem.

Name Your Objects Right

Posted on | Comments

No Name

Whenever you create an object you have to find a meaningful name.

While renaming later in modern IDE’s is no problem at all you should not pick the first name which comes to your mind.

Imagine you have an external fraud detection web service and it will return a ‘hit’ or ‘miss’. How do you name this object? HitOrMiss maybe (since this is the representation you get from the webservice) ? It might describe the problem at hand. If you go with this name it will dripple down through all layers. The domain model, the dto’s, services and more will now reference to this object (and create their own derivates for it). Your colleagues which code up other parts of the system will refer to it and create their own variants of the name (like structure for web pages). The wrong name is now all over your code.

So much for refactoring in your IDE. You will never catch all the places automatically where the wrong name was used.

While it seemed lost time discussing the ‘right’ name for 5 minutes in the beginning it saves you much more time afterwards. Of course you might get also confused a couple of weeks later remembering what this thing really does and what it is used for.

Make sure you take time in naming your objects. A wrong decision can do some harm to your code. The later it turns out that the name was not correct the much more expensive it becomes to correct this mistake. If you are not really sure how to name it, talk to your colleagues and discuss the name. A second opinion can not hurt.

Maybe FraudDetectionResult would have been a better choice.

One Year of Blogging

Posted on | Comments

© Mrs Logic @ flickr

One year ago I started to blog again. Time for a little recap.

Why did I do it ?

I use this blog to write down my own thoughts about software and development. This is for my own reference but also it is a little way to give something back to the world wide community in return for all the useful stuff I do read on the net.

I noticed how this also made me a better programmer. Try it out by yourself. Having a professional blog is also a good way for Personal branding.

Stats for the last 12 months

I love number so here they are:

About 15.000 unique visitors About 20.000 pageviews

Traffic

20.64 % Direct Traffic 36.34 % Referring Sites 42.44 % Search Engines

Highest page views on one day: the Selenium 2 post, 620 pageviews (ok, this was big link of the day at dzone.com).

Countries

I had visitors from 120 countries.

3362 visitors from United States 2090 visitors from Germany 776 visitors from United Kingdom

Top posts

GeoLocation with HTML5 2670 pageviews JSF 2 and maven 2607 pageviews Selenium 2 and Concordion vs. Cucumber each 1566 pageviews

I have 142 RSS subscribed readers.

All in all, not too shaby ;-).

Thanks

Thanks to everybody for reading my thoughts. Thanks for the comments and hints.

I’m looking forward to the next year. It is going to be a great one.

What’s Your Preferred Development Infrastructure Stack?

Posted on | Comments

In Response to Matt Raible’s question about my preferred development stack.

Source control

In my own development project I switched to Git some time ago. I was using svn and before that cvs for a couple of years. Git just makes it easy to try out small ideas very quickly without reverting the code. We will introduce Git at work pretty soon (I hope).

The Atlassian cloud

I was using Confluence as a Wiki in my open source project and my current employer Hypoport uses it as well. Bug tracking is pretty much a task of Jira. Those two integrate very nicely. You can have ping backs in your Jira Ticket from Confluence, so you see all related files. I would love to use FishEye but I’m not sure how to justify the costs and what the added value is in our case.

The Code

I’m pretty much sold to Jetbrains IntelliJ Idea. I’m using it for 5 years now. With it comes Teamcity. It’s a very nice continuous integration tool where the biggest plus (among other things) is the delayed (and pre tested) checkin. No more late night checkins which break the master. We just rolled out the latest version which has a much nicer Git integration (so we can make the switch).

So it comes down to:

The List

  • Source control: Git
  • Wiki: Atlassian Confluence
  • Continuous Integration: Jetbrains Teamcity
  • Bugtracker: Atlassian Jira

We are about to use Sonar for code analysis and development over time, but this is just in the beginning.

What’s yours ?

Using Selenium2 for Web Testing (and Not Selenium IDE)

Posted on | Comments

Selenium IDE

Selenium is well know for automatic testing web pages. It does support many browsers, operating systems and languages. A Selenium IDE exists to aid you creating automated tests.

Selenium

It is possible to write extensions in JavaScript to have data driven tests. If you organize your selenium tests in a way that you split the pages and forms in components, you can load up new data for the tests (written in xml) to fill out forms differently for each use case. The Selenium IDE will be of a great help here since you start develop the tests in the IDE and later ‘just’ parametrize the pages. With a couple of more javascript magic you can run these as well in Selenium Remote Control (Selenium RC for short). This even works for running the tests in continuous integration systems like Hudson or Teamcity.

Great Stuff.

The problem.

The drawback coding up your tests with the Selenium IDE is: HTML.

You will end up with some test suites including many test scenarios. It will be one big ball of

1
2
3
4
5
6
7
8
9
10
<tr>
  <td>type</td>
  <td>accountnumber:Value</td>
  <td>82892892811</td>
</tr>
<tr>
  <td>type</td>
  <td>accountAmount:Value</td>
  <td>2345.33</td>
</tr>

You will build components and you will end up with GotoIf and Label statements. Back to Basic programming from the 80ties. Without more javascript extensions you also can’t reuse combinations of scenarios.

While this works pretty ok: I’m a programmer and do have a problem with the quality of the produced code. It’s easy to mess up. It’s not safe for refactoring. To extend functionality you need to have javascript knowledge. Depending on your company profile (e.g. java shop) , this might be a problem. Having a dedicated tester on the team certainly helps to overcome these obstacles, but if everybody in the team just once in a while looks into the Selenium IDE tests, the quality and the reliability of the code will not improve. Not to mention all the copy and paste. Been there, done that.

Selenium 2

A much nicer approach for me would be something like this:

1
2
3
4
5
6
7
WebDriver driver  = new FirefoxDriver();
AppWebTest test = new AppWebTest(driver, "http://myapp.com/login");
LoggedInUser user = test.login("user", "password");
Account account = user.createNewAccount("DemoAccount");
account.addPerson(PersonFactory.createPersonWithNoIncome());
...
account.verify();

This would log in a user, creates an account and assigns a person to it. Everybody could read and understand it. Furthermore you can easily reuse components and logic. I would imagine that creating a DSL, matchers and finders is everything one would need to have a very nice test scenario.

All that is already possible with Selenium 1 and the language bindings (more or less).

Just with the release of the first alpha of Selenium 2 mid december 2009 it became just a little bit easier.

Selenium 2 is the combined effort of Google’s Webdriver and Selenium. Webdriver tries to tackle Seleniums problems with Javascript and the security model as well as the complex Selenium RC API.

Selenium is written in JavaScript which causes a significant weakness: browsers impose a pretty strict security model on any JavaScript that they execute in order to protect a user from malicious scripts. … Additionally, being a mature product, the API for Selenium RC has grown over time, and as it has done so it has become harder to understand how best to use it. For example, it’s not immediately obvious whether you should be using “type” instead of “typeKeys” to enter text into a form control. Although it’s a question of aesthetics, some find the large API intimidating and difficult to navigate.

Webdriver does not use JavaScript to control the web browser but uses native controls, e.g. an extension for Firefox or the native automation extensions of IE. Furthermore it introduces an object based API instead of following Seleniums directory based approach.

So given the above example the login method would look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
 public LoggedInUser login(String userName, String password) {
    driver.get(url);
    driver.findElement(By.id("user")).sendKeys(userName);
    driver.findElement(By.id("password")).sendKeys(password);
    driver.findElement(By.id("login")).click();

    LoggedInUser user = new LoggedInUser(driver);

    WebElement startPage = driver.findElement(By.id("startPage"));

    assertThat(startPage().getText()).isEqualTo("Start");
    return user;
  }

You can take this to any level. It took me just a few hours to model the above use case with componentized input elements.

With a bit more abstraction addPerson looks something like the following code. Whatever is needed to add a person to an account will be replayed. This is what Selenium IDE would normally do.

1
2
3
4
5
6
7
8
9
public void addPerson(Person person) {
    jumpToAccountOverView();
    clickOnLink("menu:Overview");
    clickOnLink("table_personTable:link_newPerson");

    inputGuiElement(person.getTitle());
    inputGuiElement(person.getLastName());
...
    clickSave();

And now for the best part. You don’t really need a real web browser. Selenium 2 supports 4 WebDriver:

  • Firefox
  • Chrome
  • Internet Explorer (on Windows)
  • HtmlUnit

HtmlUnit

With enabled JavaScript on HtmlUnit (it uses Rhino, so not all JavaScript tricks might work, could be a drawback depending on your scenario) I can run my test as TestNG or JUnit test case. No need for a Selenium RC anymore. No browsers running locally or on remote machine listing to ports to execute tests and transmitting results back.

It is very useful to have the Selenium RC take screen shots during it’s run. Selenium 2 can’t do this right now (and with HtmlUnit never can). But by simply integrating some logging in the components and elements and you know right away where things went wrong. Developing with the Selenium IDE might seem like a must, but during the work on my prototype all I needed was Firebug and a XPath Searcher. I did not miss it at all. To do integration tests you could test all components independently and one at a time. Once these work, chain them together and let them run as unit tests. Did I mention HtmlUnit is fast ?

Conclusion

I barely dug into the webdriver code, I played around with it for a couple of hours and I’m sure there more is stuff (and bugs) to find. Given that Selenium 2 is in alpha 1 stage right now I expect very nice things coming out of it. It certainly looks like the way to go.

Another strong contender is Canoo WebTest. I will have a look at this one in another post.

Update Ajax and HtmlUnit 1/5/2010

It does not seem to work. You need a real browser to get dynamically content re-rendered through Ajax.

A method waiting for an id to be rendered (or timeout after x seconds) could look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  public void waitForElementOrTimeout(String idToWaitFor, int timeout) {
    long end = System.currentTimeMillis() + timeout * 1000;
    RenderedWebElement resultsDiv = null;
    while (System.currentTimeMillis() < end) {
      try {
        resultsDiv = (RenderedWebElement) driver.findElement(By.id(idToWaitFor));
      }
      catch (NoSuchElementException e) {
        // 
      }
      if (resultsDiv != null &amp;&amp; resultsDiv.isDisplayed()) {
        break;
      }
    }
    assertThat(resultsDiv).isNotNull();
  }

This will either find the element specified or throw an assertion (updated example from the selenium 2 page).

Story Based Daily Stand-up Meeting

Posted on | Comments

© royskeane@flickr

We are agile. We do Scrum. We do daily Stand-ups.

A couple of weeks ago we changed our daily stand-up meeting. Our Scrum master came up with the idea to not go around the whole team and everybody talks about what he has done, what he will do and what the impediments are but to make it story based.

Usually after a break down everybody was working on one story, saw the task cards and made sure he did the things he was supposed to do. But this is not enough. You need to have an overview of the whole story (and the sprint). Only with that knowledge you can make sure you will meet the commitment.

So what we started to do is a stand-up meeting based on stories. Every story has a story owner. This is either the person who first started on this story or somebody who is expert in the field worked on. Every morning he is giving a review of how ‘his’ story is progressing, where the problems are and how he could need help. Depending on the priority he gets everything he needs. After presenting the status to the whole team every team member involved gives a smiley on how he feels about the story and the sprint. This way everybody knows what the situation is and how the sprint is progressing.

We found this very effective and it gives every team member a much better feeling about our commitment.

You should try it too.

Integrate Early, Integrate Often

Posted on | Comments

gears.jpg

You are doing scrum, your story is big, you really don’t know much about it and the feature does not get implemented in time.

Sounds familiar ?

I had this a couple of times.

What turned out to be a real problem is that, tech nerds as we are, we spent most of the time coding up a nice solution (and we were almost always convinced that this was the minimum we should have done). What we underestimated was the time we would need to integrate it with the rest of the system. When we broke new ground integrating new technologies it turned out is is very easy to miss that point.

In theory ‘just’ code against a defined interface and you are all set up. In practice you will find the interface not working as intended or web services returning everything wrapped in CDATA. This is the point where you start to panic. This integration was supposed to be easy. Everything else is already working and only a couple of hours where allocated to integrate the new functionality (and sprint review is tomorrow). So it is crunch time, again.

What did we learn ?

If possible (and this is not always the case) start implementing one small feature from top to bottom all the way through your application, e.g. selling green cars through you web site. If this works you can go on and sell blue and red cars. It also helps to organize teams along user stories. This way everybody is responsible for the story.

If you have teams organized along responsibilities like database or GUI, the communication between the team members will suffer (since they usually sit in different rooms). Everybody tries to code up against the defined interface and the integration usually happens pretty late in the sprint. Each team claims that his stuff works against the agreed contract (but still some things do not function as they should). Just hours before the integration should be finished, it turns out the specification was not correct and other things are needed. Back to the drawing board. Overtime. Feature not implemented.

After you got the integration running make sure an automated test is covering it. These need to be expanded over time and you make sure from the beginning that it will always work. It would be very nice to have the integration test running before writing any actual code (read: test driven development) but this never went to well for me since the two sides are very fuzzy in the beginning.

My hope is that next time we come to a situation like this I remember a couple of things I wrote down here :-).

Concordion vs. Cucumber and Java Based Acceptance Testing

Posted on | Comments

If you want your Business Analyst to provide some acceptance tests for your implementation it would be best to make sure you get it in some form your tests can read. That way you can make sure your code does really do that what the customers wants.

Two tools to achieve that are Concordion and Cucumber (and cuke4duke). Both taking the approach of Fit a step further. You can find very good documentation for the tools on their web pages or as examples along with the code.

Concordion

Concordion let’s you write the specifications in html. You can instrument them with some Concordion code. Since the instrumentation code is in html, it is hidden when you render it.

1
2
3
4
5
6
7
8
9
10
11
12
<html xmlns:concordion="http://www.concordion.org/2007/concordion"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.concordion.org/2007/concordion ">
<body>
<p>
  <span concordion:execute="setCurrentTime(#TEXT)">09:00AM</span>
  The greeting for user <span concordion:set="#firstName">Bob</span>
  will be:
  <span concordion:assertEquals="greetingFor(#firstName)">Hello Bob!</span>
</p>
</body>
</html>

Concordion can instrument free text as well as tables to have some sort of data provider for tests. It integrates directly with JUnit (no TestNG support yet).

Concordion Specification/Fixture/System

The idea is that your specifications is stable. This will not change as much as maybe your code to fulfill the requirements of the customer. Your fixture bridges these two together.

1
2
3
4
5
6
7
8
9
10
11
12
package com.maxheapsize.concordion;
import org.concordion.integration.junit3.ConcordionTestCase;
public class DemoTest extends ConcordionTestCase {

    public String greetingFor(String firstName) {
        return "Hello " + firstName + "!";
    }

    public void setCurrentTime(String time) {
        System.out.println(time);
    }
}

Your java code provides the methods which are called from the specification. At that point you are most likely to use a DSL to build up your business logic. Concordion will assert the expected values.

After you run the unit test you will get a nice looking html page.

Concordion output

Passed tests will be green, failed red, pretty easy.

Pro Concordion:

  • Instrumention of free text
  • The final report is nice looking
  • JUnit support
  • Easy setup
  • Pure Java

Con Concordion:

  • The business analyst needs to know a little bit of html
  • Usually the programmer needs to change the specification to instrument it
  • You program parts in html, refactoring support is missing
  • No TestNG support

Cucumber

Cucumber is a ruby based behaviour driven development tool. Since you can run Ruby code inside the JVM with the help of JRuby it is possible to use it for your Java code. The usually way so far is that you use maven or ant to startup JRuby and the Cucumber ruby code.

In Cucumber you write your specification (or feature) in plain english (or russian, german,lolcode or 36 or so more supported languages). No instrumentation is necessary but your customer has to stick to a certain layout (or better: structure). It follows the well known given-when-then pattern.

  Feature: Demo

  Scenario: A Car with 4 wheels
    Given I have a car
    When I add 4 wheels
    Then I should be able to drive the car

You can write your step definitions (like the fixture in Concordion) with the help of annotations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.maxheapsize.cucumber;

import cuke4duke.Given;
import cuke4duke.Then;
import cuke4duke.When;
import org.junit.Assert;

public class CarFeature {
  private Car car;
  @Given("I have a car")
  public void iHaveACar() {
    car = new Car();
  }

  @When("I add (\\d+) wheels")
  public void iAddWheels(int numberOfWheels) {
    car.setWheels(numberOfWheels);
  }

  @Then("I should be able to drive the car")
  public void iShouldBeAbleToDriveTheCar() {
    Assert.assertTrue(car.canDrive());
  }
}

The regular expressions defined in the annotations must match the feature definitions.

Cucumber results

You can define information in a table like structure as well to provide more data in an easy way. The given when then structure can be used to have multiple when’s or then’s. So it is very flexible that way.

Pro Cucumber

  • Feature can be described in plain language
  • No extra programmer work on he feature required
  • Instrumentation is directly on the Java code via annotations

Con Cucumber

  • More complex due to the Ruby/JRuby/Java chain
  • Business analyst needs to stick to predefined format
  • The only way (without extra work to write a runner) to run it seems to be within ant or maven, for rapid turn around and TDD I would like to have JUnit/TestNG support of some kind

Verdict

It is easy to get started with both tools. I spent about a couple of hours with each of them and was able to get simple and a bit more complex examples running. They get you going with BDD and acceptance based testing.

I like parts of both concepts. I want to be able to write a feature like in Cucumber. The instrumentation should be directly on my code and not in the part of the customer. The easy setup and integration of Concordion with JUnit (need TestNG here) and the output of it is very nice. So where is the tool which has these features ;-).

So which tools will I use?

I have yet to see the use case where the business analyst writes the (and updates) the acceptance tests. I don’t mind add some extra code to the specification and I know html. I might get started with Concordion for now.

You might also check my post about Behavior driven development with EasyB (and vs. TestNG).

Do you use any of these tools? Or a different one? What’s your expierence?

Update

The next-gen cuke4duke was released: Cucumber-jvm. Check out my post on that one.