Working on a Roman Numerals Kata using Strong Style Pairing and Test Driven Development with Thomas Rinke
TESTING TOUR STOP # 2 ▪ HIRZA PIMENTEL ▪ 02/22/2020
For the second stop of my testing tour, I was lucky to have had the opportunity to pair with Thomas Rinke to practice test driven development. To prepare for this session, I’ve installed Intellij and the Mob Time timer on my Mac. I also started reading Test Driven Development by Kent Beck. And watched the YouTube video by Alan Richardson, where he implemented the FizzBuzz problem using TDD.
Quick Intro
Before we began pairing, Thomas and I went over our plan for the session. We worked on my Mac so we did a test run to see if he’s able to code on my IDE. He had a German keyboard; and he noticed some quirks — like he couldn’t type the curly braces. And so, he just copied and pasted that character as needed. Since we have both paired with Lisi Hocke using the strong style approach, we decided to use the same for this session — switching between the driver/navigator roles every four minutes. We also agreed to set time aside at the end of the session for a quick retro.
For this TDD session, we worked on the Roman Numerals kata, which was suggested by Thomas’ colleague. There were two options for this kata on the Coding Dojo website. The first was to convert arabic to roman numerals; and the second was to convert roman numerals to arabic. We decided to go with the first option. And with those decisions made ahead of time, we began our TDD session.
Implementing an Arabic to Roman Numerals Converter using Test-Driven Development
Our goal was to implement code that would convert Arabic numbers to Roman numerals. Thomas took the driver role first; and I took the navigator role. And so we created our test class and named it RomanNumeralsPart1Test. We then created our first test, and we asserted that when we pass in a “1”, we should get an “I”. Initially the run button for the test was not showing up, we forgot that our test method’s name cannot begin with a number.
After fixing that, we ran the test and got an error because our method did not have a return statement. We returned null and got a failing test, as expected. Now time to get the test to pass. We changed the return statement to return an “I”, and that was it.
We re-ran test_1_should_be_I and got our first green.
We added our second test, where we asserted that passing a “2” should return a “II”. Since we are just hardcoding “I” as the return value and ignoring the parameter passed in, we know that this test would fail. Now it’s time to implement the code that would make our two tests pass. We added an if statement that would check the argument and return an “I” when we pass in a “1” and “II” when we pass in a “2”.
We ran our tests and both tests were green. Now we hit the pause button on our mob timer and discussed if we would want to add an if condition for each of the different roman numeral letters or continue writing if statements for the first ten arabic numbers. We decided on the latter; and re-started our timer.
We created tests for numbers three to ten. Verified that the tests were red and then worked on updating our implementation. First, Thomas suggested that we rename our parameter from value to arabicValue. And then we added multiple if statements that maps the arabic number to their roman numeral counterparts. We re-ran our tests and they were all green.
Now, we paused our time again and discussed how we would want to support numbers greater than 10. We decided that we would need to refactor our code for converting one to ten to a separate method; and we can call that from convertToRoman. We started our timer and refactored our code as follows:
We re-ran our tests and they were all still passing. Good. Now, we added a test to check that “XI” is returned when we pass in “11”. This new test failed; and so we needed to update our implementation to get it to pass. Since we already have a method that covers the conversion of numbers one to ten, we just had to add a while loop that would append “X” to our roman numeral until remaining value is less than or equal to ten.
We added test_20_should_be_XX and test_21_should_be_XXI to verify that our code works for other numbers greater than ten. After seeing that both tests were green, Thomas suggested that we do not need to keep test_20_should_be_XX. And so, we removed test_20_should_be_XX and added test_40_should_be_XL test_41_should_be_XLI.
Now, it’s time to make the new tests pass. We added an if condition that would arabic values greater than or equal to 40; and then we use the existing algorithm for arabic values less than 40.
We know that our implementation would only work up until 49; but we wanted to spend time to discuss our learning; and so we decided that we would have to stop at this point.
Retro
One thing we realized was that we deviated from strong style pairing from time to time. We had to pause the timer to discuss what our next steps should be; and there were times when we talked through the code together. We agreed that in the end, it worked for us. This was our first time pairing with each other; and we were still learning how to work together. One instance, I had to confirm with Thomas if we should re-run the tests; and he noted that the confirmation was not necessary. Also, we ran into an issue with Zoom where even if he had control of my computer, his keyboard strokes were not getting reflected on my IDE. To work around that, I had to revoke remote control and he had to test his keyboard on an application on his local machine; and then I had to give him remote control again.
We did not check the solution for this problem ahead of time so we were creating our tests and implementation with no clear view of what the end result should be. We think this was okay because when you’re developing code, you would not always have the solution at hand. And so, helped us see how we can use TDD to get to our final code. However, one drawback to this is that it took us a longer time to arrive at a solution. Since we did not complete the solution in this session, we decided to schedule another pairing session to hopefully get to the final code. We wanted to try a different pairing style in the next session — where the first would write the failing test and the next would implement the solution to get it to pass; and vice versa.
Thankful to Thomas for carving time out of his schedule to share this testing tour stop with me. This session is so much fun. And I feel was effective in helping me be more comfortable with test-driven development. I’m looking forward to all the learning I can get from our next pairing session together. For those who are following my journey, please do not hesitate and reach out here or on Twitter if you would want to pair on anything testing related.