Chapter 14 - Automated Testing

Exercise 1: Testing a Package

Here is code for an `ordinals` package, with an `Ordinal` function that converts the integer `1` to the string `1st`, `2` to `2nd`, and so on. We have intentionally left out the code that converts `3` to `3rd`, so that we have a case where tests should fail.

You can either create this file manually, or install it automatically with:

``````\$ go get github.com/jaymcgavren/ordinals
``````

`\$GOPATH/src/github.com/jaymcgavren/ordinals/ordinals.go`

Your goal is to create automated tests with the following expectations:

Ordinal Parameter Expected Return Value
`1` `"1st"`
`2` `"2nd"`
`3` `"3rd"` (this test should fail)
`4` `"4th"`
`11` `"11th"`
`21` `"21st"`

For now, you can use a failure message of `"didn't match expected value"` for every test.

Output:

``````\$ go test github.com/jaymcgavren/ordinals
--- FAIL: TestThree (0.00s)
ordinals_test.go:19: didn't match expected value
FAIL
FAIL	github.com/jaymcgavren/ordinals	0.006s
``````

When you’re ready, have a look at our solution.

Exercise 2: Test Helper Methods

Write a helper function for your tests that accepts these parameters:

• The argument passed to `Ordinal`.
• The actual return value from `Ordinal`.
• The expected return value.

It should return a string in this format (without square brackets):

``````Ordinal([input]) = "[actual]", want "[expected]"
``````

Update your tests for the calls `Ordinal(1)`, `Ordinal(2)`, and `Ordinal(3)` to use this helper function.

Output:

``````\$ go test github.com/jaymcgavren/ordinals
--- FAIL: TestThree (0.00s)
ordinals_test.go:31: Ordinal(3) = "3th", want "3rd"
FAIL
FAIL	github.com/jaymcgavren/ordinals	0.007s
``````

Here’s our solution.

Exercise 3: Table-Driven Tests

Replace all your tests with a table-driven test:

• Create a `testData` type with fields for the argument to pass to `Ordinal` and the return value you want.
• Create a slice of `testData` values representing the various arguments you want to pass and the return values you expect to see.
• Loop over each `testData` value in the slice:
• Pass the argument field from the `testData` to `Ordinal`, and record the return value you got.
• If the return value you got doesn’t match the expected return value field from the `testData`, call `t.Errorf`.
• Use the same format for the test failure string that you used for your helper function from the previous exercise. (Once you’re done, the helper function will be redundant, so you can delete it.)

Output:

``````\$ go test github.com/jaymcgavren/ordinals
--- FAIL: TestThree (0.00s)
ordinals_test.go:31: Ordinal(3) = "3th", want "3rd"
FAIL
FAIL	github.com/jaymcgavren/ordinals	0.007s
``````

Here’s our solution.

Play around! We encourage you to try changing the code in `Ordinal` to fix the broken test or to intentionally break other tests, and to add tests for additional arguments. You can also try creating your own package from scratch, and write tests for all its functions!