Learning Functional Programming in Go
上QQ阅读APP看书,第一时间看更新

Testing FP using test-driven development

Let's write some tests to verify each technique (simple recursive, memoized, and channeled) works properly. We'll use TDD to help us design and write better code.

TDD, a software development method where the developer starts with requirements and first writes a simple test that will fail. Then, it writes just enough code to make it pass. It continues this unit testing pattern repeatedly until there are no more reasonable tests that validate the code satisfies the requirements. The concept is to get something working now and perfect it later. After each test, refactoring is performed to implement a little more of the feature requirement.

The same or similar test(s) are performed again as well as introducing new test code to test the next piece of the feature. The process is iterated as many times as necessary until each unit is functioning according to the desired specifications:

TDD workflow diagram

We can start using a table of input values and their corresponding result values to verify that the function under test is working properly:

// File: chapter1/_01_fib/ex1_test.go
package fib

import "testing"

var fibTests = []struct {
a int
expected int
}{
{1, 1},
{2, 2},
{3, 3},
{4, 5},
{20, 10946},
{42, 433494437},
}

func TestSimple(t *testing.T) {
for _, ft := range fibTests {
if v := FibSimple(ft.a); v != ft.expected {
t.Errorf("FibSimple(%d) returned %d, expected %d", ft.a, v, ft.expected)
}
}
}

Recall that the Fibonacci sequence looks like this: 1 1 2 3 5 8 13 21 34. Here, the first element is 1 {1, 1}, the second element is 2 {2, 2}, and so on.

We use the range statement to iterate through the table, row by row, and check each calculated result (v := FibSimple(ft.a)) against the expected value (ft.expected) from that row.

Only if there is a mismatch do we report the error.

Later in the ex1_test.go file, we find the benchmark testing facility in action, which allows us to examine the performance of our Go code:

func BenchmarkFibSimple(b *testing.B) {
fn := FibSimple
for i := 0; i < b.N; i++ {
_ = fn(8)
}
}

Let's open a terminal window and write the cd command to the first set of Go code, our book's source code repository. For me, that directory is ~/clients/packt/dev/learn-fp-go/1-functional-fundamentals/ch01-pure-fp/01_fib.