今天在用GoConvey写单测时掉到了坑里,发现Convey的执行顺序并不像之前我想象的那样。实际上,每执行一次最内层的Convey都会从最外层开始逐层执行Convey的,只不过每次执行都会略过最内层已经执行过的Convey。
一个简单的例子就可以很好的帮助理解是什么意思。
比如我们写了一个GWT结构的Convey:
- Convey("Given", t, func() {
- fmt.Println("GGGGGG")
- Convey("When", func() {
- fmt.Println("WWWWWW")
- Convey("Then1", func() {
- So(nil, ShouldBeNil)
- fmt.Println("TTTTTT-1")
- })
- Convey("Then2", func() {
- So(1, ShouldNotBeZeroValue)
- fmt.Println("TTTTTT-2")
- })
- })
- })
可能多数人都会认为打印顺序是:
- GGGGGG
- WWWWWW
- TTTTTT-1
- TTTTTT-2
但是实际的打印顺序却是:
- GGGGGG
- WWWWWW
- TTTTTT-1
- GGGGGG
- WWWWWW
- TTTTTT-2
说明每执行一次最内部的Then Convey,都会从最外部的Given Convey开始执行,但是会略过已经执行过的最内层Convey(要是不略过那就是死循环了)。
再来一个更复杂的示例:
- Convey("Given", t, func() {
- fmt.Println("GGGGGG")
- Convey("When1", func() {
- fmt.Println("WWWWWW-1")
- Convey("Then1", func() {
- So(nil, ShouldBeNil)
- fmt.Println("TTTTTT-1")
- })
- Convey("Then2", func() {
- So(1, ShouldNotBeZeroValue)
- fmt.Println("TTTTTT-2")
- })
- })
- Convey("When2", func() {
- fmt.Println("WWWWWW-2")
- Convey("Then1", func() {
- So(nil, ShouldBeNil)
- fmt.Println("TTTTTT-1")
- })
- Convey("Then2", func() {
- So(1, ShouldNotBeZeroValue)
- fmt.Println("TTTTTT-2")
- })
- })
- })
打印的顺序是:
- GGGGGG
- WWWWWW-1
- TTTTTT-1
- GGGGGG
- WWWWWW-1
- TTTTTT-2
- GGGGGG
- WWWWWW-2
- TTTTTT-1
- GGGGGG
- WWWWWW-2
- TTTTTT-2