Tag Archives: TDD

Pair Programming in Retrospect

I’ve been doing pair programming for two years now. During this period I gained a lot of experience, so it is time to do a little retrospective and organize these experiences. I hope that you find something useful here, or even better, you may start to do pair programming.

Basics

Pair programming is one of the 12 core practices of eXtreme Programming in which two participants sit together and do programming using one computer. One of them owns the keyboard, while the other one assists. They are continuously discussing how and what to do.

What Worked for Me

After trying out several different pair programming styles, I’ve come up with a list of things which worked out quite well for me:

  • Use the same development environment as the others
  • Close all applications except the development environment
  • Pick a pair for the whole day and do not switch pairs during the day
  • Do pair programming only the agreed amount of time
  • Work with different people during the week if possible
  • Change roles (keyboard owner and associate) frequently, at least once in every 30 minutes, but never in the middle of the TDD cycle
  • Be honest, communicate a lot and be cooperative and patient

Read more »

VN:F [1.9.17_1161]
Rating: 10.0/10 (1 vote cast)

The Currency Format Kata

A couple of days ago, I needed a function which is capable of printing out a certain amount in Hungarian currency format. At that time I found the implementation of this function challenging, so I decided to implement it on my own, without googling for an existing solution. It was fun – as I expected – and I also realized that it would be a great Coding Kata exercise, because:

  • The exercise is quite simple
  • It can be finished in a short period of time
  • There are multiple choices on how to do it

The definition of the exercise:

Implement a functionality which shall receive a double number as string input. It shall format its input according to the Hungarian currency format, and it shall return the formatted value as string. In this particular format, the thousands are separated with spaces, and the decimal mark is a comma. You can assume that the input is always in the right format.

For example:

  • 100 -> 100
  • 1000 -> 1 000
  • 1000000.01 -> 1 000 000,01

I did the pilot Kata with my friend and colleague Tamás Győrfi in a pair programming session with TDD. we had a great time, and learnt new things even though we were unable to finish our implementation due to our time limit on the kata session. The following code demonstrates how far we got:

public class HungarianCurrencyFormatter {
    public String format(String number) {
        if (isInteger(number)) {
            return insertThousandSeparator(number);
        } else {
            String integerValueOfTheNumber = number.split("\\.")[0];
            StringBuilder formattedNumber = new StringBuilder();
            formattedNumber.append(insertThousandSeparator(integerValueOfTheNumber));
            formattedNumber.append(",");
            formattedNumber.append(number.split("\\.")[1]);
            return formattedNumber.toString();
        }
    }
 
    private boolean isInteger(String number) {
        return !number.contains(".");
    }
 
    private String insertThousandSeparator(String number) {
        final StringBuilder formattedNumber = new StringBuilder(number);
        for (int i = 1; i <= (number.length() / 3); i++) {
            int position = number.length() - 3 * i;
            if (position != 0) {
                formattedNumber.insert(position, " ");
            }
        }
        return formattedNumber.toString();
    }
}

The code above could use some refactoring, because there are duplications in the code such as calling the String#split() method twice, and the inserThousandSeparator method is not self-explanatory.

I tried a different way using the NumberFormat.getCurrencyInstance(Locale) method. The returned formatted String had some extras in it like an “ Ft” suffix and a strange thousand separator:

public class HungarianCurrencyFormatter {
    private static Locale HUN = new Locale("hu", "HU");
 
    public String format(String number) {
        NumberFormat currencyFormatter =
            NumberFormat.getCurrencyInstance(HUN);
 
        String currencyFormattedNumber =
            currencyFormatter.format(Double.parseDouble(number));
 
        String formattedNumberWithProperGroupSeparator =
            replaceLocaleSpecificGroupSeparatorWithSpace(currencyFormattedNumber);
 
        return removeFtSuffix(formattedNumberWithProperGroupSeparator);
    }
 
    private String removeFtSuffix(String number) {
        return number.substring(0, number.indexOf(" Ft"));
    }
 
    private String replaceLocaleSpecificGroupSeparatorWithSpace(String number) {
        char separator = DecimalFormatSymbols.getInstance(HUN).getGroupingSeparator();
        return number.replace(separator, ' ');
    }
}

The full source code is available on github.

The extras made the code a bit complicated, and I don’t feel that the second solution is much better than the first one. So I’ll keep exercising, maybe I found one which is much better than the versions above.

If the exercise is no longer challenging for you, you can do the following:

  • Accept any kind of string, and do proper error handling
  • Do the Kata with different constraints, like
VN:F [1.9.17_1161]
Rating: 10.0/10 (2 votes cast)

The Refactoring only Constraint

Doing code kata is more fun with constraints. Once I heard about a very impressive one, but I was unable to find anything about it, so I decided to investigate and write about it on my own.

The constraint is simple: only refactoring can be done in the production code, in other words: any kind of new functionality shall be tested and implemented in test code and refactored to the production code.

Until now, I was unable to find any reasonable argument that favours this methodology in a production environment, however, doing code kata with this constraint really improves…

  • …knowledge about the refactoring capabilities of the tools being used
  • …the refactoring experience
  • …communication skills – if done in pairs
  • …craftsmanship and patience

My recommended steps for the first try:

  1. Find an easy code kata
  2. Write a small piece of functionality with TDD, but keep it in the test case
  3. Move that small piece of functionality to production code
  4. Write another small piece of functionality with TDD, but still keep the real and the test code in the test case
  5. If necessary, refactor the production code so that it can accept the new functionality
  6. Write an integration test case which tells how the production code shall behave after moving the new piece of code to the production
  7. Move that small piece of functionality to the production code
  8. Refactor the test cases, remove redundancy – for example, the test cases of steps 2 and 4
  9. Refactor the code and keep encapsulation in mind
  10. Continue with step 4, until everything is implemented

Of course, you can choose different ways, but pay attention to the importance of the integration test case. It makes sure that nothing is broken after the move operations.

While doing the refactoring, try to…

  • …use only the refactoring tools and assistance features of your IDE – this will help you learn the capabilities of your tool(s)
  • …use only documented refactoring techniques (Fowler – Refactoring, Kerievsky – Refactoring to Patterns) – this will help you gain lexical knowledge
  • …avoid adding new [helper] lines to the code, even if you know that you will remove them later – there is a good chance that these lines will remain in the code after all

As an example, I did Roy Osherove’s String Sum exercise, with some small changes:

  • The input is always one line and always valid
  • The separator is ‘,’

I’m using eclipse, and focusing on the most important parts of work, meaning that I’m covering only one angle in the following example: return the summary of an input such as “2,3,5″

The first functionality:

    @Test
    public void shouldSumAnArrayOfIntegers() {
        assertEquals(10, sumNumbers(new int[]{2, 3, 5}));
    }
 
    int sumNumbers(int[] numbers) {
        int sum = 0;
        for (int number : numbers) {
            sum += number;
        }
        return sum;
    }

Now I’m creating a stringSum private field with the type StringSum, and moving the sumNumbers there with right click on the method -> Refactor… -> Move…

Now comes the parsing:

    @Test
    public void shouldConvertStringToIntArray() {
        assertArrayEquals(new int[]{2, 3, 5}, convert("2,3,5"));
    }
 
    int[] convert(String string) {
        String[] items = string.split(",");
        int[] numbers = new int[items.length];
        for (int i = 0; i < items.length; i++) {
            numbers[i] = Integer.parseInt(items[i]);
        }
        return numbers;
    }

So far everything is green, now comes the integration test case:

    @Test
    public void shouldPerformTheSumOnTheInputString() {
        assertEquals(10, stringSum.sum("2,3,5"));
    }

The sum() method shows up, makes the test code red (compilation failure), but with the quick fix (CTRL + 1) on the method, I can create it, and now it’s just the test assertion itself that fails. In order to finish, the convert() method is required, but it is still in the test code, and until I have a green bar, I’m not really allowed to change the code base. I am ignoring the integration test case for a minute to have a green bar, and moving the convert() method to the production code. After having the test case on board again, the bar is red, but using the content assist (CTRL + space) I’m inserting the convert() and sumNumber() calls:

    public int sum(String string) {
    	return sumNumbers(convert(string));
    }

Now everything is green, but the code is a bit ugly. The test code does not need the shouldSumAnArrayOfIntegers() and shouldConvertStringToIntArray() test cases, so I’m removing them, and making every method in the StringSum class private except the sum().

After using Refactor -> Inline…, and moving around some lines (ALT + up/down arrow) the StringSum has only one method, which looks like this:

    public int sum(String string) {
        int sum = 0;
        String[] items = string.split(",");
        for (int i = 0; i < items.length; i++) {
            sum += Integer.parseInt(items[i]);
        }
        return sum;
    }

The example above is very simple. After adding more functionality – like supporting more separators and having proper error handling -, the task became harder. It took me hours to finish it, but on the bright side, I’ve learnt new refactoring techniques.

VN:F [1.9.17_1161]
Rating: 0.0/10 (0 votes cast)

Testing the Stack Implementation

I’ve created my own version of the exercise used during my first agile job interview in order to compare it to the result of the pair programming session of the job interview. The exercise was quite simple: implement a stack, and store the values in an array. The implementation is pretty straightforward, the code is available on github. One can ask: why an array, why not using the collection framework? The answer is simple: just for fun, and just for the exercise :-)

In order to store the necessary amount of values, the internal array needs to be enlarged from time to time. There is nothing wrong with this so far. But in order to avoid unnecessary memory loss, that internal array needs to be shrunk as well. The first version of my Stack implementation lacked this functionality. The user stories of the functionality request can be:

  • As a developer, I don’t want to reserve more memory for my stack implementation than necessary
  • As a customer, I don’t want to lose values after shrinking the internal container

The second user story is very straightforward, so let’s focus on the first one. User stories and previous test cases are available, so far so good, but how to test the user story? An even better question: how to write a test case first? I consider my Stack implementation as an end product, and as such, I believe that it should follow the encapsulation object oriented programming principle, and it shouldn’t be difficult to use. An obvious choice would be a reflection-based solution, but since I’m not a great fan of reflection, I started to test the code from different angles.

For better understanding, here comes the code being tested:

    private void shrinkContainerCapacity() {
        int[] extentedContainer = new int[container.length - 10];
        System.arraycopy(container, 0, extentedContainer, 0, container.length - 10);
        container = extentedContainer;
    }

The first user story suggests memory handling, so first let’s try out this angle. Memory usage can be checked with the following methods:

Using those methods I wrote this test case sketch:

    @Test
    public void shouldUseLessMemoryAfterShrinkingInternalContainer() {
 
        for (int attempts = 0; attempts < 15; attempts++) {
            for (int i = 0; i < 10000; i++) {
                stack.push(i);
            }
 
            long availableMemoryBefore = getAvailableMemory();
            for (int i = 0; i < 10000; i++) {
                stack.pop();
            }
 
            long availableMemoryAfter = getAvailableMemory();
            assertTrue(availableMemoryBefore < availableMemoryAfter);
        }
    }
 
    private long getAvailableMemory() {
        System.gc();
        System.runFinalization();
        System.gc();
        System.runFinalization();
        long totalMemory = Runtime.getRuntime().totalMemory();
        long freeMemory = Runtime.getRuntime().freeMemory();
        return totalMemory - freeMemory;
    }

I’ve executed the test case several times and it never turned red. I was curious why, because it supposed to be work, isn’t it?

The javaDoc of System.gc() and System.runFinalization() states that: “…the Java Virtual Machine has made a best effort…“. Additionally Java Virtual Machine implementations may differ on operation system level: “…The aim is binary compatibility. Each particular host operating system needs its own implementation of the JVM and runtime. These JVMs interpret the bytecode semantically the same way, but the actual implementation may be different.” (source: Wikipedia).

Adding these statements up makes me nervous. The whole situation – using memory measurements for testing – starts looking black for me, so I did some measurements using the test code from above with different Java Virtual Machine implementations on different operating systems:

  • Running with eclipse 1.6 jre on Ubuntu Linux
  • Running with oracle’s 1.6 jre on Ubuntu Linux
  • Running with jrockit 1.6 jre on Ubuntu Linux
  • Running with oracle’s 1.6 jre on Windows XP

I’m interested how the assertTrue(availableMemoryBefore < availableMemoryAfter) will turn out in the different scenarios, so I’m measuring the availableMemoryBefore and availableMemoryAfter values, and calculate the SIGN of their difference: if the availableMemoryAfter is greater than availableMemoryBefore the SIGN will return 1, which is equal to a true test case and a green bar. In other words, after shrinking the array, the Stack uses less memory. Mission accomplished sort of say.

Before evaluating the results I have to note two things.  I’ve executed the test cases several times and I didn’t find any difference in their outputs, that’s the reason why I have only one measurement sheet for each case. Additionally I sometimes have the feeling that there is a slight difference when I’m running a java application/test case from eclipse and from command line using oracle’s jre, therefore I did the measurements with both of them separately. The detailed measurement values are available in this spreadsheet. Now the result:

Now my red bar is understandable. I’m using eclipse under Ubuntu Linux (and oracle’s jre), and according to the diagram above, there is less available memory after the first execution of the shrinking (again, I executed this particular measurement more than twenty times, and I always got the same result). If I had used jrockit, the problem above never would have turned out (the orange bars are always at 1, meaning that there is more available memory after shrinking in every case).

I would have stopped with the measurements here, unless my friend had asked me this: “Why did you have to call the System.gc() and System.runFinalization() twice?” It is a very good question. The more I call the System.gc() the more feasible is that the Java Virtual Machine will do garbage collection, which means that my application will use less memory, at least on paper.

Unfortunately experience shows otherwise. Have a look again at the javaDoc of System.gc(). In layman’s terms the System.gc() call is just a request to the Java Virtual Machine, and there is no guarantee that it will consider the call at all. According to my measurements below, the Java Virtual Machine considered it, but I had participated in a project several years ago, in which we had memory issues and no matter how often we called the System.gc() nothing really happened. The Java Virtual Machine felt that the time for garbage collection had not come yet, so it ignored our request.

So SIGN (before – after) looks this, when I’m calling the System.gc() and System.runFinalization() only once:

 

In this case I would still see a red bar with my setup, in several cases (7, 9, 11, 13 and 15) the SIGN is 0, meaning that the amount of available memory is the same before and after the shrinking. After having a close look there isn’t any option, which would make my bar green. I feel like I’m getting somewhere: checking memory usage as validation is not that promising as it was before I started measuring it. Let’s see the result without any System.gc() and System.runFinalization() calls in order to finish my measurements and provide more data for evaluation:

 

The result is not deterministic at all. Now I’m 100% sure that checking the memory is a dead end for me. I cannot garantee that my shouldUseLessMemoryAfterShrinkingInternalContainer() test case will produce the same output every time. Someone can use a different kind of machine for test case execution – for example Solaris, on which I didn’t do any measurement at all -, or can change my getAvailableMemory() helper method and execute less or more System.gc() calls. Unfortunately I need a different approach.

The next thing worth having a look at is injecting the array copy functionality. Unfortunately, the System.arraycopy() method is static, so I have to wrap it up, and inject the wrapper class into my Stack. The Stack is considered an end product, I cannot let the user take care of the dependency injection by herself, so I need a factory to do that:

public class StackFactory {
	public Stack create() {
		return new Stack(new ArrayCopyWrapper());
	}
}
// ...
public class ArrayCopyWrapper {
    public void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
        System.arraycopy(src, srcPos, dest, destPos, length);
    }
}

First let’s see the effect of this modification on the test code:

    @Test
    public void shouldShrinkInternalCapacity() {
        FakeArrayCopyWrapper arrayCopyWrapper = new FakeArrayCopyWrapper();
        stack = new Stack(arrayCopyWrapper);
 
        arrayCopyWrapper.setExpectations(0, 0, 10);
        for (int i = 0; i &lt; 20; i++) {
             stack.push(i);
        } 
 
        // Had to cut the for() loop in half
        // In order to be able to set two expectations
        arrayCopyWrapper.setExpectations(0, 0, 20);
        stack.push(20);
 
        // The same reason here
        arrayCopyWrapper.setExpectations(20, 10, 1);
        stack.pop();
 
        arrayCopyWrapper.setExpectations(20, 10, 15);
        for (int i = 20; i &gt;= 5; i--) {
           stack.pop();
        }
    }

I didn’t want to spend too much time on setting up and using mock libraries. I had the strange feeling that I didn’t have to put too much effort into this angle. A simple fake object will be just fine:

public class FakeArrayCopyWrapper extends ArrayCopyWrapper {
    private int srcPos;
    private int destPos;
    private int length;
 
    public void setExpectations(int srcPos, int destPos, int length) {
        this.srcPos = srcPos;
        this.destPos = destPos;
        this.length = length;
    }
 
    public void arraycopy(int srcPos, Object dest, int destPos, int length) {
        assertEquals(this.srcPos, srcPos);
        assertEquals(this.destPos, destPos);
        assertEquals(this.length, length);
    }
}

Although I wrote the shouldShrinkInternalCapacity() and FakeArrayCopyWrapper class, I don’t like them too much. The test case is complicated and the Fake is strange.

Additionally, when someone wants to instantiate my Stack she must do this:

Stack stack = new StackFactory().create()

But, this version seems to be more user friendly:

Stack stack = new Stack()

The first version is good for internal classes, but personally I don’t want my users to do complicated things like using wrapper factories for creating an object, when there is an easier way.

However there is one more thing. The ArrayCopyWrapper wraps only the System.arraycopy() call. If I executed a code coverage measurement using the shouldShrinkInternalCapacity() test case, the measurement would indicate that the shrinkContainerCapacity() method is 100% covered with shouldShrinkInternalCapacity() test case. This is not true. The current version of shouldShrinkInternalCapacity() does not test the command below, because it focuses only on the arraycopy:

    private void shrinkContainerCapacity() {
        //...
        //...
        container = extentedContainer;
    }

One can argue that the line above is indirectly tested by the other test cases.  This is true, but I would like to have focused test cases and correct coverage data.

This solution is not user friendly and I had to do things in testing which I don’t really like. This approach is another dead end for me, at least.

The last thing I can think of is checking the size of the internal container. I have the following options:

  • make it protected
  • create a protected method for getting its size
  • use reflection

The first two options harm encapsulation, which I have no intention to do, so another dead end.

I had no other option but to do the testing with reflection. I don’t like the current state of the test cases, but I have no other ideas. So I’m going to leave this post open, feel free to submit other ideas on how this feature can be tested. The code is available on github, and any suggestions and comments are welcome.

VN:F [1.9.17_1161]
Rating: 0.0/10 (0 votes cast)

Measuring TDD

I was cleaning up my old files and came across an old whiteboard shot, which reminded me an old small technique on measuring the amount of done Test Driven Development (TDD) work.

In case of a less advance agile team, a usual discussion topic during a retrospective is TDD. Team members are talking about whether they shall do it, how well are they doing it, how much are they doing it and the list goes on. In most of the cases the discussion is based on memories, and the longer the iteration is,  less accurate these memories are. I introduced a very easy way of TDD measurement, which helped my team handling the problems related to the TDD discussions. Have a small part on the whiteboard, with two columns:

Scrum board with TDD measure

How to use it:

  • TDD : draw one strike into this column, if your task was implemented using TDD
  • NO TDD: draw one strike into this column, if your task wasn’t implemented using TDD

At the end of the iteration or implementation cycle, the team had a clear picture on how much TDD they did. For the example let’s have 10 done implementation tasks, 4 strikes in the TDD and 5 strikes in the NO TDD column. One task was not categorized, let’s count it to the NO TDD column. 4 against 6 means that almost half of the tasks ware implemented by TDD. It is not bad at all.

Based on my experience a less advance team cannot do 100% of the implementation in TDD. Having it as a goal will make the team less productive and more frustrated. It is much healthier to pick a goal, which is realistic, but isn’t easy to achieve. If the team decides that they will use TDD in 75% of the implementation tasks, they can easily measure their progress with the way described above. If the measurement shows different result than the goal was – in this case 75% against 40% -, it is easier to talk about it when some data is available. For example they can discuss those tasks, which were supposed to implemented using TDD, but finally no TDD was involved.

From the psychological perspective, people feel better when they can accomplish a hard task, and this feeling is even better when they can show it to others – in this case drawing a strike into the TDD column.

VN:F [1.9.17_1161]
Rating: 0.0/10 (0 votes cast)