去测试输出d的实例

62 阅读3分钟

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 ,使用jqsed ,以获得一些人类友好的东西,但仍然正确排序。它不像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 做更多的工作和格式化,但这绝对已经足够好了,我已经用它作为我的默认测试输出。