2

我正在用 ginkgo 重写我们的 k8s 控制器的单元测试。

与之前的 TDD 一样,对于每个测试,我们都会有类似的东西。

    // Create the Channel  object and expect the Reconcile
    g.Expect(c.Create(context.TODO(), myObj)).NotTo(gomega.HaveOccurred())
    defer c.Delete(context.TODO(),myObj)

我们想要的是,为测试创建一个对象,并在此测试后将其从下划线集群中删除。

现在,ginkgo我们正在spec容器内运行测试。对我来说,这container是原始过程,如果是这种情况,是否意味着规范中defer定义的将在退出而不是退出规范It之前执行。containerIt

例如,

var _ = Describe("my desr", func(){
   It("a", func(){
     fmt.Println(100)
     defer func(){fmt.Println("a", 100)}()
   })

   It("b", func(){
     fmt.Println(200)
     defer func(){fmt.Println("b", 200)}()
  })
})

结果会是:

一个

100
a100
200
b200

或者

b

100
200
b200
a100

就我而言,我绝对是第一个行为。或者我在获得defer行为方面的方向是错误的?我的意思是,我应该研究BeforeEachandAfterEach方法吗?

4

3 回答 3

3

您会看到第一个行为,因为 s 的封闭范围与之前的defers 是相同的匿名函数Printlndefer退出范围时调用红色函数。

于 2020-04-04T03:57:41.610 回答
2

“起源过程”与它无关。Defer 语句在周围函数返回时运行。在您的情况下,周围的函数是您的匿名func()传递给(并被调用)It

于 2020-04-04T04:04:03.180 回答
1

您是否计划并行运行测试?如果是这样,那么结果将是不可预测的。在这种情况下,建议为每个进程设置一个单独的外部资源实例。

我建议看看控制器测试是如何在 controller-runtime 中实现的。我相信,每次调用函数时,他们都会使用envtest创建新的控制平面。正如银杏文档所述:BeforeSuit

并行运行时,每个并行进程都会运行BeforeSuite和AfterSuite函数

于 2020-04-03T22:17:32.407 回答