I hate writing unit tests. There, I've said it.
I want them in the project, telling me when I've broken something, and I would also quite like someone else to write them.
Writing the feature gives me something new to play with, writing its tests means arranging inputs, calling the thing and describing what I already think it should do. I can see why that work is useful, but getting myself to sit down and do it is another matter.
AI offers a rather convenient arrangement. It can produce the tests, I can read them, and I get to be the person with opinions about the tests, which is much easier than being the person who hasn't written them yet. A division of labour I can get behind.
Give me the cases first
Before asking for Go, I ask which cases to test for a method. The AI puts around ten bullet points in an issue comment. I review that list and edit the cases there before it starts writing the suite. That gives me something small enough to disagree with. I can cross one out, change what it expects or add something the list missed without reading through ten finished test functions to discover that I wanted a different set of questions.
For a little slug helper, the first suggestions might look like this:
- Turn
Hello Worldintohello-world. - Turn
Good Morningintogood-morning. - Turn
Nice Weatherintonice-weather.
All three check lowercase words joined by a hyphen. The list is growing but it hasn't yet asked what happens when there aren't two convenient words to join.
This has me tearing my hair out. I ask for more cases and get more examples of much the same case. The words change or a number gets larger. The assumption underneath stays put.
For the slug, I'd start asking about empty input. What about spaces at either end? Several spaces between the words? Those questions make me choose behaviour the first three examples never reached.
It's the imagination part I'm struggling to get from the AI. Once it has found a pattern, it will happily keep filling it, another greeting, another greeting.... Asking it to try harder doesn't reliably get me a different question. Sometimes I'm back to doing the thinking I was hoping it would help with, which is annoying when the list already looks so thorough.
I don't need ten for the sake of ten. I'd keep four cases that ask different things before padding the list with another six greetings. The number is useful for getting some suggestions in front of me. Only reading them tells me when I've finished.
Now do the typing
Once I've edited the list, I ask it to turn those cases into a table-driven test. Each row holds an input and its expected answer. One loop runs the same check for every row. Go's t.Run gives each case its own name in the test output.
I also seem to develop strong standards once somebody else is doing the typing. The generated file doesn't need banners and phase labels announcing each ordinary line.
A small assertion can arrive dressed for a conference keynote.
Here's a shortened table for the slug example, where I've chosen to trim spaces at the ends and turn a run of spaces into one separator:
func TestSlug(t *testing.T) {
cases := []struct {
name string
input string
want string
}{
{"words", "Hello World", "hello-world"},
{"empty", "", ""},
{"outer spaces", " Hello World ", "hello-world"},
{"repeated spaces", "Hello World", "hello-world"},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if got := Slug(tc.input); got != tc.want {
t.Fatalf("Slug(%q) = %q, want %q", tc.input, got, tc.want)
}
})
}
}
I'm happy to hand over the repetitive typing. I can read down the rows and check them against the list I agreed to. If I change my mind about one case, its input and answer are together. I haven't got a separate little arrangement of setup code to work through for every suggestion.
I'd like the next method to need less coaxing. For now, each still needs its own conversation. I can reuse the test format, but I have to read the suggestions before I know which question to ask next. I'm not ready to call this affection. But I am getting tests written and I can start by arguing with a list.
Apparently that is a much more appealing job than writing the tests myself.