go test 命令是好的,支持去像一个真正的现代语言,内置支持测试。但是它的输出明显不友好。
$ go test
PASS
ok pragprog.com/rggo/interacting/todo 0.100s
我们可以用以下方法让它变得更漂亮一些-v
$ go test -v
=== RUN TestAdd
--- PASS: TestAdd (0.00s)
=== RUN TestComplete
--- PASS: TestComplete (0.00s)
=== RUN TestDelete
--- PASS: TestDelete (0.00s)
=== RUN TestSaveGet
--- PASS: TestSaveGet (0.00s)
PASS
ok pragprog.com/rggo/interacting/todo 0.211s
但仍不太适合人类使用。
有一个gotestfmt 的工具,它的效果相当不错!只要你把json的输出传给它go test
$ go test -v -json | gotestfmt
📦 pragprog.com/rggo/interacting/todo
✅ TestAdd (0s)
✅ TestComplete (0s)
✅ TestDelete (0s)
✅ TestSaveGet (0s)
但是,如果你有来自测试的stderr输出作为设置/删除过程的一部分,那么gotestfmt 会让你失望。由于某些原因,它在任何测试结果之前输出所有这些输出。
$ go test -v -json | gotestfmt
📦 pragprog.com/rggo/interacting/todo/cmd/todo
Building tool...
Running tests...
Cleaning up...
✅ TestTodoCLI (240ms)
✅ TestTodoCLI/AddNewTaskFromArguments (220ms)
✅ TestTodoCLI/AddNewTaskFromSTDIN (10ms)
✅ TestTodoCLI/CompleteTask (10ms)
✅ TestTodoCLI/ListTasks (0s)
vs
$ go test -v
Building tool...
Running tests...
=== RUN TestTodoCLI
=== RUN TestTodoCLI/AddNewTaskFromArguments
=== RUN TestTodoCLI/AddNewTaskFromSTDIN
=== RUN TestTodoCLI/ListTasks
=== RUN TestTodoCLI/CompleteTask
--- PASS: TestTodoCLI (0.08s)
--- PASS: TestTodoCLI/AddNewTaskFromArguments (0.07s)
--- PASS: TestTodoCLI/AddNewTaskFromSTDIN (0.00s)
--- PASS: TestTodoCLI/ListTasks (0.00s)
--- PASS: TestTodoCLI/CompleteTask (0.00s)
PASS
Cleaning up...
ok pragprog.com/rggo/interacting/todo/cmd/todo 0.314s
这绝对是个小问题;但它让我很恼火,以至于想做点什么。
既然go test 很好地提供了json输出,那么直接使用它呢?
$ go test -v -json
{"Time":"2022-03-16T13:50:18.170841-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Output":"Building tool...\n"}
{"Time":"2022-03-16T13:50:18.334313-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Output":"Running tests...\n"}
{"Time":"2022-03-16T13:50:18.334414-04:00","Action":"run","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI"}
{"Time":"2022-03-16T13:50:18.334422-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI","Output":"=== RUN TestTodoCLI\n"}
{"Time":"2022-03-16T13:50:18.334473-04:00","Action":"run","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromArguments"}
{"Time":"2022-03-16T13:50:18.33448-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromArguments","Output":"=== RUN TestTodoCLI/AddNewTaskFromArguments\n"}
{"Time":"2022-03-16T13:50:18.495296-04:00","Action":"run","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromSTDIN"}
{"Time":"2022-03-16T13:50:18.495322-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromSTDIN","Output":"=== RUN TestTodoCLI/AddNewTaskFromSTDIN\n"}
{"Time":"2022-03-16T13:50:18.499036-04:00","Action":"run","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/ListTasks"}
{"Time":"2022-03-16T13:50:18.499055-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/ListTasks","Output":"=== RUN TestTodoCLI/ListTasks\n"}
{"Time":"2022-03-16T13:50:18.50366-04:00","Action":"run","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/CompleteTask"}
{"Time":"2022-03-16T13:50:18.503676-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/CompleteTask","Output":"=== RUN TestTodoCLI/CompleteTask\n"}
{"Time":"2022-03-16T13:50:18.513055-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI","Output":"--- PASS: TestTodoCLI (0.18s)\n"}
{"Time":"2022-03-16T13:50:18.513088-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromArguments","Output":" --- PASS: TestTodoCLI/AddNewTaskFromArguments (0.16s)\n"}
{"Time":"2022-03-16T13:50:18.513097-04:00","Action":"pass","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromArguments","Elapsed":0.16}
{"Time":"2022-03-16T13:50:18.513105-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromSTDIN","Output":" --- PASS: TestTodoCLI/AddNewTaskFromSTDIN (0.00s)\n"}
{"Time":"2022-03-16T13:50:18.513109-04:00","Action":"pass","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/AddNewTaskFromSTDIN","Elapsed":0}
{"Time":"2022-03-16T13:50:18.513113-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/ListTasks","Output":" --- PASS: TestTodoCLI/ListTasks (0.00s)\n"}
{"Time":"2022-03-16T13:50:18.51313-04:00","Action":"pass","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/ListTasks","Elapsed":0}
{"Time":"2022-03-16T13:50:18.513134-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/CompleteTask","Output":" --- PASS: TestTodoCLI/CompleteTask (0.01s)\n"}
{"Time":"2022-03-16T13:50:18.513139-04:00","Action":"pass","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI/CompleteTask","Elapsed":0.01}
{"Time":"2022-03-16T13:50:18.513142-04:00","Action":"pass","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Test":"TestTodoCLI","Elapsed":0.18}
{"Time":"2022-03-16T13:50:18.513146-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Output":"PASS\n"}
{"Time":"2022-03-16T13:50:18.51315-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Output":"Cleaning up...\n"}
{"Time":"2022-03-16T13:50:18.513938-04:00","Action":"output","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Output":"ok \tpragprog.com/rggo/interacting/todo/cmd/todo\t0.696s\n"}
{"Time":"2022-03-16T13:50:18.513983-04:00","Action":"pass","Package":"pragprog.com/rggo/interacting/todo/cmd/todo","Elapsed":0.696}
肯定是可以使用的!而且输出的顺序是正确的,所以gotestfmt 把它们分组就更奇怪了。
一个gotestfmt 替换使用jq
jq-go-tests是一个gotestfmt ,使用jq 和sed ,以获得一些人类友好的东西,但仍然正确排序。它不像gotestfmt 那样花哨地拉出包和格式化,但对我来说已经足够好了:
$ go test -v -json | jq-go-tests
Building tool...
Running tests...
✅ TestTodoCLI (0.24s)
✅ TestTodoCLI/AddNewTaskFromArguments (0.22s)
✅ TestTodoCLI/AddNewTaskFromSTDIN (0.00s)
✅ TestTodoCLI/ListTasks (0.00s)
✅ TestTodoCLI/CompleteTask (0.01s)
PASS
Cleaning up...
ok pragprog.com/rggo/interacting/todo/cmd/todo 0.822s
如果你不想点击进入代码,jq-go-tests 是简单的: mn
#!/usr/bin/env bash
jq -r '.Output // ""' | rg -v "=== RUN" | sed -e '/^$/d' -e "s/--- PASS/✅/" -e "s/--- FAIL/❌/"
我可以花一些时间让jq 做更多的工作和格式化,但这绝对已经足够好了,我已经用它作为我的默认测试输出。