Golang笔记-单元测试test初探

rundaisc · · 643 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

### 为什么需要单元测试 其实在很长一段时间,包括现在,我都很不喜欢写单元测试。因为维护单元测试的成本很高。只有接口做了一点变更,那么单元测试就必须做相同的变更,否则会导致测试不通过。 那么反过来,只要每次在提交代码都去运行一次单元测试。这样可以很快的检查到你对代码更改是否影响了正常的业务逻辑,当然很大一部分是可能是别人写的那部分代码。因为你不确定本次的修改是否会影响到别人的那部分。所以单元测试还是很有必要的。 ### 单元测试最基本的应用 go语言中单元测试是开箱即用的,官方提供了`test`包。不用像PHP中需要单独配置`unit`。 #### go test 最基本使用 `go test` 命令是`golang`单元测试的最基本使用 #### go test -v > `go test -v`是我们比较常用的一个测试命令,用于执行测试,并打印额外的输出。 新建一个项目用于示例 ``` test │ main.go │ main_test.go ``` 可以看到我在`main.go`的同级目录创建了一个`main_test.go`。`go`语言中,单元测试的代码必须跟需要测试的代码在同一个包里面。且命名必须遵循上面的那种结构规范,即:`文件名_test.go` 我在`main.go`中创建两个函数来分别得到字符串相加的结果。 ``` func JoinStrUseSprint(a,b string) string { return fmt.Sprintf("%s%s",a,b) } func JoinStrUseNor(a,b string) string { return a+b } ``` `main_test.go`中的测试代码 ``` import "testing" func TestJoinStrUseNor(t *testing.T) { c := JoinStrUseNor("aaa","bbb") t.Log(c) } func TestJoinStrUseSprint(t *testing.T) { c := JoinStrUseSprint("aaa","bbb") t.Log(c) } ``` 测试代码中使用了 `testing`包。而且每个测试函数必须是以`Test`开头,有且只有一个参数`t *testing.T`.`t.Log()`函数为输出一段`Log`日志 这样一个简单的单元测试就完成了。 这个时候我们运行`go test`,结果如下。 ``` test>go test PASS ok test 0.360s ``` 可以看到测试通过了。但是发现并没有我们期望的日志输出。如果我们要得到输出的结果,我们需要一个额外的参数,具体命令如下: ``` test>go test -v === RUN TestJoinStrUseNor --- PASS: TestJoinStrUseNor (0.00s) main_test.go:7: aaabbb === RUN TestJoinStrUseSprint --- PASS: TestJoinStrUseSprint (0.00s) main_test.go:12: aaabbb PASS ok test 0.480s ``` 这个时候就可以看到很详细的测试流程与输出的测试的`log`。 ##### go test -cover > 很多时间我们需要看单元测试的覆盖率,这个时候我们就需要`go test -cover`了。 我们同样使用上面的代码。 ``` test>go test -cover PASS coverage: 100.0% of statements ok test 0.440s ``` 可以看到单元代码覆盖率是`100%`。这个是我们在`main`文件里面在增加一个函数。 ``` func JoinStrUseSprint(a,b string) string { return fmt.Sprintf("%s%s",a,b) } func JoinStrUseNor(a,b string) string { return a+b } func Run() { fmt.Println("I'm run,and I'm happy!") } ``` 然后再执行`cover`,得到了覆盖率为`66.7`。 ``` test>go test -cover PASS coverage: 66.7% of statements ok test 0.398s ``` 当然`-v -cover`是可以同事使用的。 ``` test>go test -cover -v === RUN TestJoinStrUseNor --- PASS: TestJoinStrUseNor (0.00s) main_test.go:7: aaabbb === RUN TestJoinStrUseSprint --- PASS: TestJoinStrUseSprint (0.00s) main_test.go:12: aaabbb PASS coverage: 66.7% of statements ok test 0.429s ``` 很多时候我们需要将单元测试覆盖率写到一个文件中,这时候我们再`-cover`中增加一些额外的参数 ``` >go test -coverprofile test.cover >go tool cover -html=test.cover -o coverage.html ``` - 第一个命令:`-coverprofile filename`将覆盖率的`profile`写入指定文件中。 - 第二个命令:`go tool cover -html=test.cover -o coverage.html`将覆盖率的文件写入可视化的html文件中 打开`converage.html` 如下图: ![cover_01.png](https://image-static.segmentfault.com/227/670/227670883-5ebff014c2460) 其实这里可以借用一个很好的第三方包。 ``` go get github.com/smartystreets/goconvey ``` 安装完成,直接再项目目录下执行 ``` test>goconvey 2020/05/16 21:46:43 goconvey.go:61: Initial configuration: [host: 127.0.0.1] [port: 8080] [poll: 250ms] [cover: true] 2020/05/16 21:46:43 tester.go:19: Now configured to test 10 packages concurrently. 2020/05/16 21:46:43 goconvey.go:178: Serving HTTP at: http://127.0.0.1:8080 2020/05/16 21:46:43 integration.go:122: File system state modified, publishing current folders... 0 3179270049 2020/05/16 21:46:43 goconvey.go:118: Received request from watcher to execute tests... 2020/05/16 21:46:43 goconvey.go:105: Launching browser on 127.0.0.1:8080 2020/05/16 21:46:43 goconvey.go:111: exec: "start": executable file not found in %PATH% 2020/05/16 21:46:43 goconvey.go:113: 2020/05/16 21:46:44 executor.go:69: Executor status: 'executing' 2020/05/16 21:46:44 coordinator.go:46: Executing concurrent tests: test 2020/05/16 21:46:45 parser.go:24: [passed]: test ``` 按照提示打开`http://127.0.0.1:8080/`就会得到一个很炫酷的覆盖率界面 ![cover_02.png](https://image-static.segmentfault.com/227/779/2277798041-5ebff025ddeeb) `Golang`单元测试的基础今天就暂时到这里面,下面几个`testing`包的常用断言方法. ``` // 输出测试日志 t.Logf() t.Logf() // 标记错误,但仍然执行后面的语句 t.Fail() // 获取是否当前用例是执行错误的 t.Failed() // 错误输出,等于 t.Logf 再执行 t.Fail() t.Errorf("%s", "run ErrorF") // 标记函数错误,并中断后面的执行 t.FailNow() // 致命错误输出,等同于调用了 t.Logf 然后调用 t.FailNow() t.Fatalf("%s", "run Fatelf") ``` 下一篇我们会写到 `golang`中的一些基准测试,以及一些测试的工具。 更多学习内容,同步更新到公众号,期待与您一起交流 ![cover_02.png](https://image-static.segmentfault.com/343/059/3430599076-5ebff21575454)

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

643 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传