Archive for the ‘tips’ Category

Test Driven Tortoise vs Hackey Hare …

Sunday, August 8th, 2010

hare-n-tortoise

Said the Test Driven Tortoise one day to the Hackey Hare:
“I’ll run you a code race if you dare.
I’ll bet you cannot
Arrive at that production spot
As quickly as I can get there.”

Quoth the Hackey Hare: “You are surely insane.
Pray, what has affected your brain?
You seem pretty sick.
Call a doctor in–quick,
And let him prescribe for your pain.”

“Never mind,” said the Test Driven Tortoise. “Let’s run!
Will you bet me?” “Why, certainly.” “Done!”
While the Test Driven Tortoise creeps,
with Tests, Continuous Integration and
customer speaks, Hackey Hare makes four leaps,
And then tells all how soon he’ll be done.

It seemed such a one-sided race,
To win was almost a disgrace.
So he hackily coded about
until the bugs inevitably came out –
As the Tortoise was nearing the place.

Too late! Though he sped like a dart,
the bugs hard to start
The Tortoise was first. She was smart:
“You can surely code fast,”
She remarked. “Yet you’re last.
It is better to get a good start.”

Adapted from Jean de La Fontaine’s poem: Hare And The Tortoise

A corollary to this fable is another version http://www.jobcyclone.com/articles/haretortoise.php related more to business that sees the hare winning, however, the key to this version is “fast and consistent”. It is rare to find someone that is both fast and consistent without using techniques like Test Driven Development and Continuous Integration which support going as fast as you can as consistently as you can.

If you want to win the race you should start with TDD and CI.

Coding Secret …

Saturday, July 31st, 2010

 I’m sitting at a cafe at 8am sipping a nice coffee while I write this. You may not find this very exciting but for me is it quite out of the ordinary as I usually spend this time with my wife and twin sons. Would you find it exciting if I was to tell you that I would reveal a single little thing you can do to your code that will improve it for you and for everyone else that uses it?

With the one piece of advice I’m going to tell you how to reduce the amount of code you write so you can keep your code dry’er , do things quicker because you are doing less, and make  your code more readable and a better match for your domain. Does this sound too good to be true?

The advice is to never use a primitive collection as a domain object. To be clear this advice also means that a primitive collection cannot be exposed outside of the containing Class.

What I usually see in code is the use of a primitive collection to represent a domain model concept or in place of a proper class. I guess this is usually done because it is thought to save time or that this is what these types are for. The code looks like this (in Java for the masses):

List<Account> accounts;

for (Account account : accounts) { do something with account } 

The key point of the advice is the use of “List<Account>” should only appear in the definition of a Class called Accounts. Try this advice and see positive benefits for yourself.

 

After this advice is applied the Accounts class then represents a concrete concept in the domain which was missing before, although it was implied. Accounts can now have methods that represent domain concepts and they will exist in a single place, not scattered or duplicated throughout the code.  Want to know what business happens with a collection of Accounts, just look at Accounts.

 

The advice applies to more than just primitive collections but I thought I would start there as they represent a common usage. The advice can also be applied to less obvious collection types like File. For example, don’t just use a File object but subclass it and name the class to represent what is in the file, giving more meaning to “File” and the things that you want to do with that file.

 

This advice is not just for Java programmers, although most of the code examples around promote this primitive approach. Many non-Java languages like Ruby have great support for collections but these too should not be used in place of a concrete class.

 

When I apply this advice to my own code (in Ruby, Smalltalk and Java) the result is more meaning in the model and less code.  Please give it a try and let me know your experiences.

How To Program: Requirements …

Thursday, March 18th, 2010

 questions

This is the second in a series of posts about how to program, and before I begin I should say that this series is probably more about how to be a Software Developer but I used the tag line ‘How To Program’ to catch the interest of the intended audience, School or University Students.

This post is about what is arguably the most important part of being a Software Developer, Requirements. A good Developer helps solve the problems that the Customer is trying to solve and gives you an experience-based opinion of all the risks along the way so the Customer can make informed choices, and none of this is possible if you don’t know what the Customer wants. After you know what the Customer wants you can then go through a process of getting as close to that as possible. When I say Customer, I mean anyone who interacts with you, as how well you interact with a Customer will shape your work life.

Whole careers are built around obtaining and understanding Customer requirements and I don’t profess to be the best person to provide information on how to get requirements, but I can tell you the techniques I have used with success.

Keep in mind that almost always a Customer will say what they want in terms of a solution they have in mind. For example, the School Teacher Customer may say “I want a web application that allows me to take attendance/roll-call.”, but do they really need a web application? Do they really need to take attendance/roll-call? How would you know, how would they know? Your task is to get to the bottom or most basic needs and problems of the Customer. Maybe they have the right solution in mind, but you won’t know if you don’t know the problems they are trying to solve. Maybe a barcode on each students forehead that is automatically scanned when they walk through the school gates is the solution? To make things more complicated the initial Customer may not be the only Customer and the solution may need to take others into account as well.

Ask “Why?” until you get to what is the root problem or need that is to be addressed. This is usually about five (5) Whys or when the Customer can’t reduce the need any further. Asking “why” needs to be done with tact and sympathy or asking why repeatedly could cause friction and then getting to the real need may become impossible.

Ask “How will having the requirement benefit them?” to find out what is required from another angle, the angle of satisfaction. This will help you understand the scope of the requirement and possibly the quality required in the solution. Sometimes finding out the benefit the Customer perceives they will get from a requirement can also bring out the real requirement or need. For example, a Customer who wants a faster Web Site might actually want a faster graphics card or faster Internet connection. The other advantage of asking how the Customer will be benefit from the requirement is that it can also bring out that the Customer isn’t the actual Customer for the requirement, in which case you need to find the other Customer. For example, we had the School Teacher who wanted a Web Application to take attendance/roll-call but it probably didn’t benefit them directly but is required as part of the process the School follows. So maybe the School Teacher isn’t the Customer, but the School Administrators?

I’m probably going to be a little controversial with this next statement, but it is something I feel strongly about and have had success by maintaining. If you can’t find a Customer who needs the requirement then it shouldn’t be a requirement. Every requirement should have a Customer who needs it and can define the satisfaction criteria for the requirement. You may have to look hard to find them but you know you have found them when you can say that requirement X benefits Customer Y directly because of Z.

In summary:

Ask why to uncover the real need or problem.

Identify the benefit(s) of meeting the requirement.

I recommend reading Jonathan Babcocks Blog http://practicalanalyst.com/ and Liz Keogh’s Blog http://lizkeogh.com/ for informative insights into Requirements.

The next instalment is Analysis.

Java Cucumber (cuke4duke) Spring 3 and Selenium Test Jump Start …

Sunday, March 7th, 2010

jumpstart

Recently I worked on a Ruby On Rails Project using rake, rspec, cucumber and celerity and I really enjoyed this suite of tools. More recently I started a side-side Project that is Java based but I wanted a similar set of tools, especially Cucumber as this allows the other people involved to write scenarios that are then progressively implemented by others. Cucumber support for Java (and other languages) is available through the Cuke4Duke Project.

The out of the box examples from the Cuke4Duke project get you started but I wanted more, I wanted a Project that:

  • Was automated, with unit-test, integration-tests and Web Based interaction tests.
  • Was able to run against different Web Browsers through simple configuration.
  • Was able to run without using a browser when this type of interaction took too long.
  • Was able to be added simply and quickly to a Continuous Integration Server.
  • Was a small initial download and didn’t require a lot of configuration or knowledge to get running.

I took the out of the box examples for spring and web driver from cuke4duke and combined them together with some Maven magic and produced a simple Hello World Web Application with almost all of the attributes I wanted.  I also added some placeholder classes, unit tests, integration tests and a cucumber scenario.  The Page Object pattern and the excellent PageFactory tools are also used to provide an example of driving the Web Application through Scenario Steps.

The goal of the Skeleton is to jump start my own and possibly your own projects using BDD and TDD and lots of automation to get you from A-to-B quicker and with more confidence in the result.

You can get the skeleton project from gitHub or download it here: maven-cuke4duke-jump-start
Or just do these commands:

git clone http://github.com/jamesladd/maven-cuke4duke-jump-start.git
cd maven-cuke4duke-jump-start
mvn -Dcucumber.installGems=true cuke4duke:cucumber
mvn clean integration-test

To start the project building and see it in action check the README file.

*NOTE* When building the maven project for the first time there is a *LOT* of cuke4duke dependencies downloaded, but just the first time. It takes a while, but only the first time.

And now the weird part, if on the first run the Cucumber steps fail, run mvn clean integration-test again. This also only has to be done once and from then on all work without error.

UPDATE: I have added maven profiles to the project so you can now choose which Web Browser to use to drive the web site, for example, -P chrome will use the Chrome browser. This is documented in the README.  With this feature you can configure your Continuous Integration server to run the build for each browser you support.

UPDATE: Added database setup and migration support using Liquibase and HSQL.

UPDATE: Added support for Cuke4Duke V0.3.0

MAVEN: Tuning which tests to run …

Thursday, November 26th, 2009

On a recent project we needed to tune MAVEN to run unit tests and integration tests separately.

When we execute “mvn test” we want just our unit tests to run, and when we execute  “mvn integration-test” we want integration tests to run. Of course the unit tests will run as well because they are a dependency.

This is not as simple as it could be in MAVEN so I’m sharing the working plugin configuration with you.  Here it is:

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*ITest.java</exclude>
</excludes>
</configuration>
<executions>
<execution>
<id>integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<skip>${integration.test.skip}</skip>
<includes>
<include>**/*ITest.java</include>
</includes>
<excludes>
<!– Ensure Maven inhierits exclude –>
<exclude>must-be-here-for-maven</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>

TDD: Where to start ?

Saturday, August 8th, 2009

birds-eye *

When I do Test Driven Development and I have the choice of doing it how I like then I start from the Top-Down. I choose Top-Down because it keeps me focused on the goal and what the Business/User wants. With Top-Down I go down fewer rabbit holes looking for an elusive bug or wrestling with a tricky implementation.

I start by writing down what it is I am building and what tests must pass before I accept the work as done. For example, I am working on a Smalltalk compiler for the Java Virtual Machine and one of the deliverables is the compiler, so this is how I started the acceptance tests:

The compiler will be done when …

  • Compiling Statements made up of a single Expression
  • Compiling Methods with a Message Pattern followed by Statements

I try to write all the criteria down before starting any implementation. I do this so I can prioritize and see the scope of what I am doing. I then convert these sentences into the syntax of the language I am developing in, sometimes this makes the test method names more uniform but I try not to loose important information:

compilingStatementsWithAnExpression()
compilingMethodsWithMessagePatternAndTemporariesAndStatements()

The next and probably most important step is writing the line of code that will prove or disprove that the criteria has been met. I write this before any implementation. If I can’t form a hypothesis in code before writing implementation code then I’m usually not sure of what I am doing and I should step back and become sure with a spike. I follow the same process of writing the verification or assert statement in English and converting it to the target language.  Here are the verification steps for the above tests, assuming the use of the Java Mockito Testing framework (in my case the compiler is done when it can call the code generator with a valid abstract syntax tree):

verify(generate).receive(statementWith(expression()))
verify(generate).receive(methodWith(messagePattern(), temporaries(), statements()))

I use the features of the language or the testing framework to facilitate code that is descriptive, even if this means a little more work since the test also serves as documentation. In my case I can tick off each test against the Smalltalk grammar shown in the back of the book Smalltalk-80: The Language and its Implementation.

When I have all the tests ready I sometimes comment out all but the one I want to implement first and make a start on implementing it.  Commenting out the others means I won’t get swamped and disheartened by a flood of red-bars (failing tests). As I implement each test I leave it uncommented and move onto the next test. Eventually all the code is uncommented and passing (green-bar).

The test I implement first is driven by the Business as it is typically the feature they want first or the one that shows them or me the most important information to make decisions on moving forward.

When implementing I fake-it-until-i-make it, that is, I hard code the results output from the code under test to ensure the test passes, then I go back an remove the hard coding and implement the real logic. I do this because it provides an opportunity to see more of the requirements to get the test to pass and an opportunity to see the test is correct. There have been a few times when the test was incorrect and passing and therefore the code was not correct and I was none the wiser.  Not happy times.  While using fakes I output a message to let me know a fake is in use, so I remember to remove them all.

The above approach is the one that works best for me and I suggest you try it as I find it yields less code overall.

ADDENDUM:

I received some feedback that suggested I may not be following the failing-test-implement-pass-refactor’ cycle and the approach I use does, as I start with a test that fails because I have not yet faked it. I then implement the fake and the test passes. I then continue to fake more tests to show two important things, 1. The tests work and, 2. The commonality in tests and the potential implementation. At some point in the process I will have no fake code at all and the actual implementation will have been done after a failing test. I have seen the false-positives scenario too many times so I stop and test the test just a little more. YMMV

*  The image used here is by Cannboys and you can see his portfolio here: http://www.istockphoto.com/cannboys

East: Clean and DRY …

Saturday, August 1st, 2009

towels

Some friends of mine like to meet up regularly and discuss code and on Friday I caught up with Fredy and we discussed keeping Ruby code clean and dry by orienting it East. Fredy showed me the following Cucumber steps from his project as a starting point for a discussion:

1 Given /the Customer results table is sorted by Address/ do
2   @customer_page.results.header.address.click
3 end
4
5 Given /the Customer results table is sorted by Surname/ do
6   @customer_page.results.header.surname.click
7 end

We both liked the use of the page fixture “@customer_page” as it encapsulated the page being worked with and kept the steps focused on the business logic rather than how to interact with classes that manipulate web pages or swing apps. However, the rest of the lines were not good in my opinion, as they exposed too much information on the ‘how’.

This is how the discussion went:

James: What is line 2 meant to do ?
Fredy: It sorts the customer page results by address by clicking on the address column in the header row.
James: So why not have a method like ’sort_by_address’ and let it take care of the how by getting the results, it would be more readable* ?
Fredy: But what is there (on line 2) is readable.

James: Which of them ‘results.header.address.click’ or ’sort_by_address’ conveys the business intent?
Fredy: I guess ’sort_by_address’ does, but it is only one line and it is done.
James: Sure but it isn’t East Oriented and therefore you are missing opportunities to keep the code clean and dry. See line 6, where you repeat yourself.
Fredy: You and your East thing. (In a sarcastic tone) Ok, tell me how East will help as Im dying to know?

James: For a start you are asking the object with the information for that information rather than telling the object with the information to do the work.
Fredy: But I am using ‘Tell Don’t Ask’, I’m telling the customer_page to give me the results.
James: That isn’t ‘Tell Don’t Ask’ as I understand it, which is also why I call it East and have rules to ensure code is East Oriented. With East you can’t have a public method that returns a value like results, so you would have to ask the customer_page to do something else, maybe ’sort_by_address’ ?
Fredy: Some code has to get the results and sort them !
James: Yes, but it should not be a public method, since this leads to duplicate code like you have (lines 2 & 6) because when you ask for an object then manipulate it the chances that more than one piece of code will do the same manipulation is made higher since most people wont look through the codebase to find the same manipulation and make it common. By going East you greatly reduce this possibility and put the functionality in an Object where it can be refactored to remove duplication.
Fredy: Lets assume line 2 and 6 are East as you suggest, how is that removing duplication and besides now I have an explosion of methods on my page fixture object ?

10 Given /the Customer results table is sorted by Address/ do
11   @customer_page.sort_by_address
12 end
13
14 Given /the Customer results table is sorted by Surname/ do
15   @customer_page.sort_by_surname
16 end

James: Now the methods are all on the same object and not spread across lots of other objects making the opportunity to refactor them into a single method more obvious. For example, ’sort_by_address’ can become ’sort_by’ and take an argument indicating the sort criteria. So your code can now look like this:

20 Given /the Customer results table is sorted by (.*?)/ do |criteria|
21   @customer_page.sort_by criteria
22 end

James: Which is East, reveals the business intent and provides a generic step that can be reused wherever a Customer results table needs sorting without you adding more code. If you follow these changes through the code you should see that going East made the code more DRY and reduced the count of public methods on several objects. As a bonus if the Business decide they want to sort using a keystroke rather than a click you only have to change the code in one spot.

Fredy: I guess I could give the ‘East’ thing a try. Would you help me ?
James: Sure.

*I made a mistake here in the discussion by using a value word like ‘more’ since what is actually more readable to one person may be less readable to another. I need to remind myself not to use ‘value’ words like ‘more’ or ‘better’ in these sorts of discussions.

The PageObjects web driver …

Wednesday, May 13th, 2009

After my post on Cucumber Salad a colleague Tal pointed out a more formal description of the approach I was describing.

gmock, gtest, ubuntu and C/C++

Sunday, March 29th, 2009

 puzzle

There are a few projects that I have wanted to do for a very long time, some of which are products and some of which are tools. Over the weekend I thought I would use some very rare free time from looking after my twin son’s to look at using C/C++, google gtest and gmock to assess the “cost” to me of using them for one of these projects. I remember a time when testing in the C/C++ world was somewhat of a very manual task and one that didn’t get a lot of attention so I’m excited to be using gtest and gmock in with this language, but I’m not sure when my next free time is likely to be.

I downloaded gtest and followed the build instructions but the didn’t work but this may have just been my reading of the instructions, however, what follows are the steps I used to get gtest and gmock installed. What I have left to do now is create a C/C++ project and drive the first class forward with tests and mocks.

For Ubuntu 8.10 and gcc 4.3.2

  1. download gtest and unzip into a folder
  2. cd to that folder
  3. cd into the ’src’ folder
  4. make a ‘build’ folder
  5. cd into the ‘build’ folder
  6. run the command ‘../../configure
  7. run the command ‘make’
  8. run the command ‘make check’
  9. run ’sudo make install’ which will put the libraries, headers and executables in ‘/usr/local’
  10. add ‘/usr/local/lib’ to your LD_LIBRARY_PATH and optionally add ‘usr/local/bin’ to the PATH
  11. download gmock and unzip into a folder
  12. cd to that folder
  13. make a ‘build’ folder
  14. cd into the ‘build’ folder
  15. run the command ‘../configure CC=gcc-4 CXX=g++-4′
  16. run the command ‘make’
  17. run the command ‘make check’
  18. run ’sudo make install’ which will put the libraries, headers and executables in ‘/usr/local’

The above worked for me and all the tests ran (make check) without error.  Note that I have added the ‘ CC=gcc-4 CXX=g++-4′ arguments to the configure step for gmock which are required in the latest cygwin release to ensure gcc version 4 is used. I don’t use these flags under linux and I don’t use them for gtest.

If you are wondering what it is I am building with C/C++, gtest and gmock then drop me an email or catch up with me at the next Melbourne Patterns group where I will be presenting.

Ubuntu 8.10 and IDEA IntelliJ, no longer slow …

Sunday, March 22nd, 2009

For a while I have had an excruciatingly slow IntelliJ 8.1 under Ubuntu 8.10 with Java 1.6.0_10 and I was considering downgrading until the performance was fixed. Seriously, it was bad with page-down visibly scrolling the screen at about 1 second a line. Not usable at all. Recently I looked again for a fix and the issue is apparently due to Java and is fixed in Java 1.6.0_12, but you can also add the following entry in your /etc/X11/xorg.conf file just under the device section, and it works.

Option “AccelMethod” “XAA”