当 defer func 在 ginkgo 执行时

when defer func is executed at ginkgo

我正在用 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 是原始进程,如果是这种情况是否意味着 It 规范中定义的 defer 将在退出 container 之前执行,而不是退出 It规格

例如,

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)}()
  })
})

结果会是:

a

100
a100
200
b200

b

100
200
b200
a100

就我而言,我肯定是第一个行为。或者我在获得 defer 行为方面走错了方向?我的意思是,我应该看看 BeforeEachAfterEach 方法吗?

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

我建议看看 controller tests are implemented in controller-runtime. I believe, they create new Control Plane with envtest each time BeforeSuit function is called. And as ginkgo docs 是如何表述的:

when running in parallel, each parallel process will run BeforeSuite and AfterSuite functions

您会看到第一个行为,因为 defer 的封闭范围与前面的 Println 是相同的匿名函数。 defer红色函数在退出作用域时被调用。

"Origin process"与此无关。 Defer statements run when the surrounding function returns。在你的例子中,周围的函数是你的匿名 func() 传递给(并被调用)It.