「Golang」使用GoConvey测试框架的完全指南

发表时间: 2021-07-29 16:51

为什么要使用goconvey测试程序

goconvey 集成go test,go test 无缝接入。管理运行测试用例,而且提供了丰富的函数断言、非常友好的WEB界面,直观地查看测试结果。 如果没有goconvey的话,编写一个测试结果,首先运行被测试函数,然后判断被测试函数的运行结果,各种if判断,各种输出提示信息,而且回归测试也比较麻烦。但是如果使用了goconvey这些都就变得无比的简单。 还是看些使用代码比较简单明了。

怎么使用goconvey测试程序

第一步当然是安装goconvey

  1. go get github.com/smartystreets/goconvey


看下被测试的代码

  1. package main
  2. import"fmt"
  3. type Studentstruct{
  4. Numint
  5. Namestring
  6. Chinaeseint
  7. Englishint
  8. Mathint
  9. }
  10. func NewStudent(num int, name string)(*Student,error){
  11. if num <1|| len(name)<1{
  12. returnnil,fmt.Errorf("num name empty")
  13. }
  14. stu :=new(Student)
  15. stu.Num= num
  16. stu.Name= name
  17. return stu,nil
  18. }
  19. func (this*Student)GetAve()(int,error){
  20. score :=this.Chinaese+this.English+this.Math
  21. if score ==0{
  22. return0,fmt.Errorf("score is 0")
  23. }
  24. return score/3,nil
  25. }


主要看下goconvey的测试代码

  1. package main
  2. import(
  3. "testing"
  4. ."github.com/smartystreets/goconvey/convey"
  5. )
  6. func TestNew(t *testing.T){
  7. Convey("start test new", t, func(){
  8. stu,err :=NewStudent(0,"")
  9. Convey("have error", func(){
  10. So(err,ShouldBeError)
  11. })
  12. Convey("stu is nil", func(){
  13. So(stu,ShouldBeNil)
  14. })
  15. })
  16. }
  17. func TestScore(t *testing.T){
  18. stu,_ :=NewStudent(1,"test")
  19. Convey("if error", t, func(){
  20. _,err := stu.GetAve()
  21. Convey("have error", func(){
  22. So(err,ShouldBeError)
  23. })
  24. })
  25. Convey("normal", t, func(){
  26. stu.Math=60
  27. stu.Chinaese=70
  28. stu.English=80
  29. score,err := stu.GetAve()
  30. Convey("have error", func(){
  31. So(err,ShouldBeError)
  32. })
  33. Convey("score > 60", func(){
  34. So(score,ShouldBeGreaterThan,60)
  35. })
  36. })
  37. }


进入到test代码目录,执行 go test

  1. === RUN TestNew
  2. start test new
  3. have error ✔
  4. stu isnil✔
  5. 2 total assertions
  6. --- PASS:TestNew(0.00s)
  7. === RUN TestScore
  8. if error
  9. have error ✔
  10. 3 total assertions
  11. normal
  12. have error ✘
  13. score >60✔
  14. Failures:
  15. */data/www/go/src/test/student_test.go
  16. Line35:


其实命令行显示的是有颜色标识的。期望出现的结果都会打上对勾,如果期望出现而没有出现的都会打上叉。 还有更好玩的WEB界面。进入的test代码的目录,然后执行 goconvey 会打开一个WEB界面,更加友好的标识出了测试的结果,测试了多少次,有几个通过,几个失败,一目了然。

其实使用特别简单 引入类库,启动Convey函数,剩下的就是调用So各种断言各种比较

  1. import(
  2. "testing"
  3. ."github.com/smartystreets/goconvey/convey"
  4. )
  5. Convey("desc", t, func(){
  6. So(var,function)
  7. })


基本平常开发中的比较函数基本都有,看下比较的函数列表,看着貌似都涵盖了。

  1. Convey("Equality assertions should be accessible", t, func(){
  2. thing1a := thing{a:"asdf"}
  3. thing1b := thing{a:"asdf"}
  4. thing2 := thing{a:"qwer"}
  5. So(1,ShouldEqual,1)
  6. So(1,ShouldNotEqual,2)
  7. So(1,ShouldAlmostEqual,1.000000000000001)
  8. So(1,ShouldNotAlmostEqual,2,0.5)
  9. So(thing1a,ShouldResemble, thing1b)
  10. So(thing1a,ShouldNotResemble, thing2)
  11. So(&thing1a,ShouldPointTo,&thing1a)
  12. So(&thing1a,ShouldNotPointTo,&thing1b)
  13. So(nil,ShouldBeNil)
  14. So(1,ShouldNotBeNil)
  15. So(true,ShouldBeTrue)
  16. So(false,ShouldBeFalse)
  17. So(0,ShouldBeZeroValue)
  18. So(1,ShouldNotBeZeroValue)
  19. })
  20. Convey("Numeric comparison assertions should be accessible", t, func(){
  21. So(1,ShouldBeGreaterThan,0)
  22. So(1,ShouldBeGreaterThanOrEqualTo,1)
  23. So(1,ShouldBeLessThan,2)
  24. So(1,ShouldBeLessThanOrEqualTo,1)
  25. So(1,ShouldBeBetween,0,2)
  26. So(1,ShouldNotBeBetween,2,4)
  27. So(1,ShouldBeBetweenOrEqual,1,2)
  28. So(1,ShouldNotBeBetweenOrEqual,2,4)
  29. })
  30. Convey("Container assertions should be accessible", t, func(){
  31. So([]int{1,2,3},ShouldContain,2)
  32. So([]int{1,2,3},ShouldNotContain,4)
  33. So(map[int]int{1:1,2:2,3:3},ShouldContainKey,2)
  34. So(map[int]int{1:1,2:2,3:3},ShouldNotContainKey,4)
  35. So(1,ShouldBeIn,[]int{1,2,3})
  36. So(4,ShouldNotBeIn,[]int{1,2,3})
  37. So([]int{},ShouldBeEmpty)
  38. So([]intGitHub.com,ShouldNotBeEmpty)
  39. So([]int{1,2},ShouldHaveLength,2)
  40. })
  41. Convey("String assertions should be accessible", t, func(){
  42. So("asdf",ShouldStartWith,"a")
  43. So("asdf",ShouldNotStartWith,"z")
  44. So("asdf",ShouldEndWith,"df")
  45. So("asdf",ShouldNotEndWith,"as")
  46. So("",ShouldBeBlank)
  47. So("asdf",ShouldNotBeBlank)
  48. So("asdf",ShouldContainSubstring,"sd")
  49. So("asdf",ShouldNotContainSubstring,"af")
  50. })
  51. Convey("Panic recovery assertions should be accessible", t, func(){
  52. So(panics,ShouldPanic)
  53. So(func(){},ShouldNotPanic)
  54. So(panics,ShouldPanicWith,"Goofy Gophers!")
  55. So(panics,ShouldNotPanicWith,"Guileless Gophers!")
  56. })
  57. Convey("Type-checking assertions should be accessible", t, func(){
  58. // NOTE: Values or pointers may be checked. If a value is passed,
  59. // it will be cast as a pointer to the value to avoid cases where
  60. // the struct being tested takes pointer receivers. Go allows values
  61. // or pointers to be passed as receivers on methods with a value
  62. // receiver, but only pointers on methods with pointer receivers.
  63. // See:
  64. // http://golang.org/doc/effective_go.html#pointers_vs_values
  65. // http://golang.org/doc/effective_go.html#blank_implements
  66. // http://blog.golang.org/laws-of-reflection
  67. So(1,ShouldHaveSameTypeAs,0)
  68. So(1,ShouldNotHaveSameTypeAs,"1")
  69. So(bytes.NewBufferString(""),ShouldImplement,(*io.Reader)(nil))
  70. So("string",ShouldNotImplement,(*io.Reader)(nil))
  71. })
  72. Convey("Time assertions should be accessible", t, func(){
  73. january1, _ := time.Parse(timeLayout,"2013-01-01 00:00")
  74. january2, _ := time.Parse(timeLayout,"2013-01-02 00:00")
  75. january3, _ := time.Parse(timeLayout,"2013-01-03 00:00")
  76. january4, _ := time.Parse(timeLayout,"2013-01-04 00:00")
  77. january5, _ := time.Parse(timeLayout,"2013-01-05 00:00")
  78. oneDay, _ := time.ParseDuration("24h0m0s")
  79. So(january1,ShouldHappenBefore, january4)
  80. So(january1,ShouldHappenOnOrBefore, january1)
  81. So(january2,ShouldHappenAfter, january1)
  82. So(january2,ShouldHappenOnOrAfter, january2)
  83. So(january3,ShouldHappenBetween, january2, january5)
  84. So(january3,ShouldHappenOnOrBetween, january3, january5)
  85. So(january1,ShouldNotHappenOnOrBetween, january2, january5)
  86. So(january2,ShouldHappenWithin, oneDay, january3)
  87. So(january5,ShouldNotHappenWithin, oneDay, january1)
  88. So([]time.Time{january1, january2},ShouldBeChronological)
  89. })


特别实用的一个测试类库,养成写完代码使用goconvey做测试的好习惯,也顺便覆盖下使用方法和案例,定能让开发事半功倍,减少Bug率。