28 December 2015

Testing Koans

Koans
Koans have been proposed as an effective way to learn a new programming language. But what exactly are Koans? According to Wikipedia a Koan (where the o has a macron, a straight bar placed above it - which my text editor refuses to produce) is a "case, story, dialogue, question or statement in the history and lore of Zen Buddhism". Huh? Reading the Wikipedia article did not help me at all. All I understand is that a Koan is something the Buddhist monks would work with, a mystical sentence or maybe a kind of poem, which does not make any sense, but somehow helps them on their way to enlightenment. It seems the metaphor has been transferred from Buddhism to software, e.g. Hacker Koans and Koans are related to the TAO of Programming. (Again no idea what TAO is supposed to mean here. This is like a recursive definition.)

Ruby Koans
As far as I know, the first Programming Koans were available in Ruby, created by the late Jim Weirich, a popular Ruby hacker. Ruby Koans consists of several little exercises, starting with basic things and building on each other to move to more advanced topics in the end. The goal is to learn Ruby, to walk the "path to enlightenment" as Jim put it. He also wanted to teach the Ruby culture. The Ruby community has a strong focus on testing, which is considered essential to "do great things in the language". In fact the exercises are a list of failing test cases, where tiny pieces of code have to be filled in to make them pass. For example, here is the exercise to learn accessing array elements,
def test_accessing_array_elements
  array = [:peanut, :butter, :and, :jelly]

  assert_equal __(:peanut), array[0]
  assert_equal __(:peanut), array.first
  assert_equal __(:jelly), array[3]
  assert_equal __(:jelly), array.last
  assert_equal __(:jelly), array[-1]
  assert_equal __(:butter), array[-3]
end
Doyle Spiral + InversionThe double underscore marks the place where the code has to be changed to make it work and pass the test. These tests are very simple and there is not much explanation. Maybe this is the connection to the Zen Koans: The Language Koans are a list of exercises to work through, to master the language (i.e. reach enlightenment). Each one is very small (i.e. a sentence) but does not make much sense on its own. The exercises are sorted by increasing difficulty (i.e. the path to walk). Following Jim's example, Koans are usually based on unit tests which you make succeed. Language Koans are available for many programming languages, see a list of Koans by Laura Diane Hamilton.

Testing Koans
I took the idea for Testing Koans from Carlos Blé's training JavaScript for Testers. He created some Koans for JavaScript with inverted work-flow. The code was already in place, but the assertions were missing. That was reasonable as the training was created for tester.

xUnit Koans
Earlier this year I ran an introductory unit testing workshop for the local PHP community. I expected a junior audience and aimed for the most basic exercise for xUnit assertions and life cycle methods. I wanted the participants to focus on PHPUnit alone. I created some sample code, together with unit tests, and then deleted the assertion statements. The first test looked similar to the following Java code:
import org.junit.Test;

public class Session1_GreeterTest {

  @Test
  public void shouldReturnHelloName() {
    Greeter greeter = new Greeter();
    // TODO check that "Hello Peter" is greeter.greet("Peter")
  }

  @Test
  public void shouldReturnHelloForNull() {
    Greeter greeter = new Greeter();
    // TODO check that "Hello" is greeter.greet(null)
  }

  // more tests skipped...

}
The participants went through the tests one by one, adding assertions or fixing incomplete statements, making the tests pass. While this looked like a very basic and short exercise, developers unfamiliar to PHPUnit (and xUnit in general) needed several hours to complete all my PHPUnit Testing Koans.

Due to the uniform nature of all xUnit ports, the style and structure of the exercise can be used for other programming languages. I ported the exercise to Java using JUnit, creating Java/JUnit Koans. Both Koans cover the basic functionality of PHPUnit and JUnit, e.g. assertions, testing for exceptions and before- and after-methods. More advanced features could be added. I will port the Koans to C#/NUnit and Ruby/minitest as soon as I will need them.

Conclusion
Koans are a great way to partition the process of knowledge acquisition into a series of little exercises. They verify themselves, giving you fast feedback but you can still learn at your own pace. Language Koans are established and available for many languages. These can be extended to any library or public API you want to master. Testing Koans work similar, just inverted. They are available for PHPUnit and JUnit for now. I would love to see more ports and also Koans for different testing styles, e.g. RSpec or Jasmine Testing Koans.

2 comments:

Carlos Ble said...

Thanks for the mention mate! I'll use your koans, thanks for sharing;-)

Peter Kofler said...

Thank you Carlos for introducing me to the idea. I would love to see a translation to C#/NUnit - afaik that is the platform you are using right now.