Archive for Top 5

Five unit testing tips #4: Don’t mock your way into accidental complexity

I’ve all but stopped using mock objects in my tests. The reason is that mocking have had a detrimental effect on the design of my systems. I’ve often ended up having the mocks trick me into adding a needless layer of indirection that does nothing except delegate to the next layer, just to satisfy the mocks.

For a while, I was wondering whether I was the only one with this problem, but then I saw this tutorial on JBehave, which so perfectly illustrates the problem I saw myself doing. Now, I don’t mean to pick on JBehave, or the author of this tutorial. Furthermore, this is not a particularly extreme example of the problem. Rather, the point of this posting is to show that even expert developers run into this trap.

Here is the test from the JBehave tutorial:

@Test
public void shouldProvideNotesToBePlayedInOrder() {
    TabParser parser = mock(TabParser.class);
    String asciiTab = "e|--------A3-B6-";
 
    List<Note> notes = asList(A(3), B(6));
    stub(parser.parse(asciiTab)).toReturn(notes);
 
    Tab tab = new Tab(asciiTab, parser);
 
    List<Note> actualNotes = tab.notesToBePlayed();
 
    ensureThat(notes, equalTo(actualNotes));
}

In other words, the tab’s notes to be played should be equal to the parsed notes.

Here’s the implementation:

public class Tab {
 
    private final List<Note> notes;
 
    public Tab(String asciiTab,
               TabParser parser) {
        notes = parser.parse(asciiTab);
    }
 
    public List<Note> notesToBePlayed() {
        return notes;
    }
}

Whoops! We just introduced a layer in the design that does nothing. As a matter of fact, removing the Tab class from the whole example leaves us with a design that’s easier to understand.

Mocks can be great when you really, really need them. And I’m extremely impressed by the power of mockito. But used inappropriately, mocking can trick you into creating accidental complexity and extra layers of code that does nothing.

Comments

Five Unit Tests Tips #3: Parametrized test methods

The following is a trick I don’t use very often, but when I do need it, it comes in very handy. It’s a trick that many developers aren’t aware of, even though it’s been possible to do with JUnit at least since version 3.

Sometimes you want to have a lot of tests that are almost the same, but that contain different arguments. For example, for a yahtzee calculator, you might want to have the following tests:

checkRollScoredAsCategoryGives(1, 2, 3, 4, 5, "straight", 15);
checkRollScoredAsCategoryGives(1, 2, 3, 4, 4, "straight", 0);
checkRollScoredAsCategoryGives(3, 3, 3, 4, 4, "full house", 17);
checkRollScoredAsCategoryGives(1, 2, 3, 4, 4, "full house", 0);
checkRollScoredAsCategoryGives(4, 4, 4, 4, 4, "full house", 0);

This is possible with JUnit, but a little trick. You have to construct a test suite manually and add special subclasses of TestCase to it:

 
 
public static Test suite() {
    TestSuite suite = new TestSuite(
          YahtzeeScoreTest.class.getName());
    suite.addTest(checkRollScoredAsCategoryGives(
            1, 2, 3, 4, 5, "small straight", 15));
    suite.addTest(checkRollScoredAsCategoryGives(
            1, 2, 3, 4, 4, "small straight", 0));
    suite.addTest(checkRollScoredAsCategoryGives(
            3, 3, 3, 4, 4, "full house", 17));
    suite.addTest(checkRollScoredAsCategoryGives(
            1, 2, 3, 4, 4, "full house", 0));
    suite.addTest(checkRollScoredAsCategoryGives(
            4, 4, 4, 4, 4, "full house", 0));
    return suite;
}
 
private static Test checkRollScoredAsCategoryGives(
        int die1, int die2, int die3, int die4, int die5,
        final String category, final int expectedResult) {
    final int[] dice = new int[] { die1, die2, die3, die4, die5 };
    return new TestCase("Rolling for " + category) {
        @Override
        public void runTest() throws Throwable {
            YahtzeeScoreboard board = new YahtzeeScoreboard();
            board.scoreRoll(category, dice);
            assertEquals(expectedResult, board.getTotalScore());
        }
    };
}

The code creates an anonymous inner subclass of TestCase that instead of calling all methods annotated with @Test just executes our specific test. These tests are collected in a normal JUnit TestSuite.

The test is plain JUnit and will run in Maven or your favorite IDE, just as any other tests. The fact that the suite is named after the test class will let Eclipse know where to go when you double click on the test from the test runner.

This trick can be very useful for tests of logic that calculates a results or validates input.

Comments

Low hanging fruit for presenters

If you ever talk to a group of people, you know that the art of presentation is one that requires a lifetime to master. But there are some dirt simple things you can do that will have a positive impact on your presentations. Here is my list of low hanging fruit for presenters:

  • If you’re using a computer, use a presentation remote. This is a cheap and easy way to make your presentation style look a little more professional.
  • If you’re using visuals, try and place yourself to the left of the visuals from the point of view of the audience. In the western culture, people scan scenes from left to right. By standing to the left, they will look at you first.
  • If your using visuals, place a laptop (or a monitor) between you and the audience with your slides on them. Turning to look at the slides over your shoulder seems uncertain, looking down at the monitor seems thoughtful.
  • Before you start speaking, take a few good breaths. Don’t rush. And whatever you say first, “ummm…” and “yes….” should not be it.
  • When you’re done speaking say “thank you for your attention”. This will trigger the primate clapping response. An uncertain ending leaves the audience wondering when they should applaud.
  • Find the friendly faces. Every audience contains those few people that smile when you look at them. Use them whenever you’re uncertain an need a kick of positive energy.

There are many hard and time consuming skills required to give good presentations. The list above is full of no brainers. These things you can do with no practice and no preparations.

Comments

You might not be Agile if…

Top five signs that you might not be working on an agile project:

  • 5. Your iterations do not produce anything that could be put into production
  • 4. You’re not testing your work
  • 3. You tasks are called “code the UI for the foo”, “update the bar component” and “test the work done in the previous iteration”
  • 2. Your iterations are called “specification”, “testing”, and “preproduction”
  • 1. And the top sign that you might not be working on an agile project: You might not be working on an agile project if your iterations are three months long

Happy Holidays, Merry Christmas and Happy Monkey, everybody.

Comments

Five Unit Test Tips: #2: Change your code to make testing easier

It’s been a while since I promised to write top five unit testing tips, so I guess I should better start writing #2. As with my first example this one is based on a real-life story.

Your code is worth nothing if it can’t be tested. Change your code to make it more testable.

In my last project, we used a pipes and filter architecture, with messages being passed forward through a chain of services. Most services refined the messages or broke them up in smaller services and passed them on to the next service. When they refined the message, they often stored new messages to the data layer as a side effect. To test the results, we read the generated objects back from the data layer. I had code like this:

Before

@Test
public void fileShouldCreateTransactionObject() {
    Reader simulatedFile = new StringReader(createFileContents());
    FileRequest file = new FileRequest(filename, simulatedFile);
 
    TransactionRepository repo = new TestTransactionRepository();
 
    FileService fileService = new FileService();
    TransactionService transService = new TransactionService();
    fileService.setNextStep(transService);
    fileService.setTransactionRepo(repo);
 
    fileService.process(simulatedFile);
 
    Collection<Transaction> transactions = repo.findAll();
    assertEquals(1, transactions.size());
    Transaction transaction = transactions.iterator().next(); // Bleh!
 
    // Here is the real code I wanted
    assertEquals("foo", transaction.getTransactionType()); // Whatever
}

The solution was to change the design away from the pipes-and-filters design. Instead, the process() method returns the newly created Transaction object:

After

@Test
public void fileShouldCreateRequestObject() {
    Reader simulatedFile = new StringReader(createFileContents());
    FileRequest file = new FileRequest(filename, simulatedFile);
 
    FileService fileService = new FileService();
    Transaction transaction = fileService.transform(simulatedFile);
 
    // Here is the real code I wanted
    assertEquals("foo", transaction.getTransactionType()); // Whatever
}

This new design totally violated our architecture, but it’s clearer, it keeps the infrastructure away from the code, and it’s much less brittle. Our test transaction repository used to be vulnerable to being polluted with test data from a previous run. As we no longer use this sort of infrastructure objects, we don’t have to worry about interaction between tests.

If you don’t know how to test your architecture, the problem is not with the testing, but with the architecture.

Until next time: Happy testing.

Comments

Five Unit Test Tips: #1: Use the data store

I’ve looked over some of my code lately, and found ways that I often improve my tests. I’m planning on writing a blog post for each of my five favorites.

First out: Using the data storage. I upgraded our API for billing customers. I had a few compilation errors in my code, as the API had changed somewhat. After fixing these errors, I was left with a test that broke mysteriously with a MethodNotFoundException. I located the test and found that it was close to unreadable. After examining it further, I found that it was trying to do was simple, but hidden in technical code.

Read the rest of this entry »

Comments

Letters from Egypt: Top Five surprises

Honking

Cars in Egypt, especially Cairo honk all the time. Day and night. If we woke up at 4 am in the hotel room, there would be cars honking outside. The honk to wake up pedestrians or other cars, taxis honk to attract the attention of potential customers, and often, it seems like they honk just for the fun of it.

Security

There’s a ton of policemen in Cairo, easily recognizable by their white uniforms. Most are in their early twenties. All have mustaches. Any ATM, bank or hotel will have stationed at least two policemen, usually with guns and a metal detector. Major tourist attractions will have much more (we saw a lot of policemen on the street, pluss five cars on standby by Midan Hussein). There will usually be assault shields (manned by black-uniformed police). Five-star hotels will have bomb dogs. Busy intersections have police officers directing the traffic.

And it does make you feel safer, I think. I was never afraid of being pickpocketed or mugged in Cairo. But I am not sure about the metal detectors. Nobody asks to to empty you pockets and try again when you beep. They just kinda glance up at you and resume their… watchfulness.

Curbs

The curbs to the sidewalks in Egypt are about 20 centimeters tall. I imagine this is the only reason taxi drivers don’t use sidewalks as shortcuts when the traffic is bad. The result if there are a lot of side streets is that pedestrians will constantly have to step on and off the sidewalk. Since people are lazy, most places, they walk in the street instead.

Abandoned buildings

All over Egypt, but especially on the Giza-side of the Nile, there are a huge number of what looks like buildings where they abandoned the construction before they were done. In many cases, this doesn’t stop people from living there. But the phenomenon is not limited to Giza. Alexandria, and even Dahab has a lot of these buildings. We tried asking a few locals what was up with these, but we didn’t manage to make anyone understand the question. I imagine this is the way it’s always been in Egypt.

Pedestrians

The thickness of pedestrians on streets like Sharia Talaat Harb, Corniche el-Nil (during Eid) og Sharia 26th of July was extreme. And pedestrians in Egypt are very aggressive. With the slow moving traffic of the inner city streets, they weave in and out between the honking cars without considering pedestrian crossings. Usually cars swerve organically around the flood of pedestrians if there is enough room.

There were also things I expected would be very different, but really didn’t live up to my fantasies:

Prayers

The minarets call out for prayer five times every day. You can hear the prayer calls anywhere in Cairo, and probably most other places in Egypt, too. However, I expected more people to stop up or more things to slow down during these times. In general, it seems like it’s just a backdrop for most egyptians most of the time.

Women’s clothing

Most women in Cairo, even in the central parts, seem to be wearing head scarfs. Beside this, however, most young women wear almost the same kind of clothes as in the west. We noticed a lot of tight-fitting clothing, for example. But most women cover up most of their skin.

Finally, there were a few minor surprises:

Cats

There are almost as many cats in Egypt as there are police officers. When we were sitting in the small outdoors lounge in our hotel, we saw five different cats within the same hour. In the breakfast balcony on our Dahab hotel, there were about ten. The cats don’t seem to belong to anyone, but people don’t mistreat them, either. They are usually tame, and will come up to you for bits of food or pets.

There are also many dogs that are … strays? no…. wild? .. no… independent, maybe. Most of these seem to be pretty healthy and wholesome, and they seem to like to stick around people.

Taxis

Taxis proved very useful for both long and short trips in Egypt. Usually, if you’re a westerner and you walk along a street, taxis will honk at you, slow down and say “taxi?” If you need a taxi, you just pop you head in the window and state you destination: “Midan Ramsees”. We have found it most useful to negotiate the fare before we get in. And whatever you do: You should always state the price first. So he nods and I say: “ten?” If the driver doesn’t agree, just say “maalesh” (never mind) and walk away. If your initial price was right, this often will have the driver change his price.

Comments

Some words

Here are some of my favorite words.

Signs of danger

  • ‘Just’: bad word, as in “can’t we just develop the greatest application ever”, “can’t we just replace the database with JavaSpaces”, “can’t we just expose the functionality to the world as a web service”.
  • ‘Should’: bad word, as in “it shouldn’t take more than a few days to do that, should it,” “integrating two systems should be easy.” Listen for use of this word from people who … should know better.

Signs of thought

  • ‘Awkward’: good word as in “It’s awkward to talk to your boss (who has way more experience than you do) about teaching her agile programming.”
  • ‘Why’: good word, as in “why do you need to pass two parameters to this function?”, “why are we developing a login screen”, or “why did my change cause troubles for my colleague?”

Comments

Tips for Developers

Update: Rewrote several sections

“Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it.” – Alan Perlis

This article contains some things I have learned that has made me into a better developer than I was before I learned them. There are nine tips. These are not necessarily the only, or the best things I have learned, but I like the number nine.

Becoming a better developer is a complex path. What I have found to be the most important attitude is to be versatile. Digging yourself down in one kind of activity, one “phase” of a project, one technology is a sure way to stagnate. I try to balance technical knowledge with “softer” skills. Developing software is about communicating, thinking, and programming. In order to be effective, you have to master all of these areas.

Read the rest of this entry »

Comments

Why I Hate SOA: Bad Ideas that Just won’t Die

When I see people after they have read about SOA or attended a conference with SOA, there are a few ideas that seem to pop up repeatedly. I have even been guilty of using these ideas myself. These ideas were proven to be bad before SOA came around, and (some) SOA evangelists seem to think that SOA solved these problems. It did not. It just refused to learn from history. Some of these ideas work under some circumstances, but recent SOA-itis has caused them to be used in inappropriate contexts.

Read the rest of this entry »

Comments

Creative Commons Attribution 3.0 Unported
This work is licensed under a Creative Commons Attribution 3.0 Unported.