0%

【Kubernetes】e2e 测试

End to End (e2e) 测试模拟用户行为操作Kubernetes,用于保证Kubernetes服务或集群的行为完全符合设计。本文以 NetworkPolicy 的 e2e 测试为例,介绍基于 Kubernetes 原生 e2e 测试框架进行测试的步骤与原理。

Ginkgo

Ginkgo 是一个高效测试框架

Behavior Driven Development

Ginkgo最大的特点就是对BDD风格的支持。比如:

1
2
3
Describe("delete app api", func() {
It("should delete app permanently", func() {...})
It("should delete app failed if services existed", func() {...})

Ginkgo定义的DSL语法(Describe/Context/It)可以非常方便的帮助大家组织和编排测试用例。在BDD模式中,测试用例的标题书写,要非常注意表达,要能清晰的指明用例测试的业务场景。只有这样才能极大的增强用例的可读性,降低使用和维护的心智负担。

可读性这一点,在自动化测试用例设计原则上,非常重要。因为测试用例不同于一般意义上的程序,它在绝大部分场景下,看起来都像是一段段独立的方法,每个方法背后隐藏的业务逻辑也是细小的,不具通识性。这个问题在用例量少的情况下,还不明显。但当用例数量上到一定量级,你会发现,如果能快速理解用例到底是能做什么的,真的非常重要。而这正是BDD能补足的地方。

不过还是要强调,Ginkgo只是提供对BDD模式的支持,你的用例最终呈现的效果,还是依赖你自己的书写。

进程级并行,稳定高效

相应的我们知道,BDD框架,因为其DSL的深度嵌套支持,会存在一些共享上下文的资源,如此的话想做线程级的并发会比较困难。而Ginkgo巧妙的避开了这个问题,它通过在运行时,运行多个被测服务的进程,来达到真正的并行,稳定性大大提高。其使用姿势也非常简单,ginkgo -p命令就可以。在实践中,我们通常使用32核以上的服务器来跑集测,执行效率非常高。

这里有个细节,Ginkgo虽然并行执行测试用例,但其输出的日志和测试报告格式,仍然是整齐不错乱的,这是如何做到的呢?原来,通过源码会发现,ginkgo CLI工具在并行跑用例时,其内部会起一个监听随机端口的本地服务器,来做不同进程之间的消息同步,以及日志和报告的聚合工作,是不是很巧妙?

Ginkgo使用Tips

Ginkgo框架的功能非常强大,对常见测试场景的都有比较好的支持,即使是一些略显复杂的场景,比如:

  • 在平时的代码中,我们经常会看到需要做异步处理的测试用例。但是这块的逻辑如果处理不好,用例可能会因为死锁或者未设置超时时间而异常卡住,非常的恼人。好在Ginkgo专门提供了原生的异步支持,能大大降低此类问题的风险。类似用法:

    1
    2
    3
    4
    5
    6
    It("should post to the channel, eventually", func(done Done) {
    c := make(chan string, 0)
    go DoSomething(c)
    Expect(<-c).To(ContainSubstring("Done!"))
    close(done)
    }, 0.2)
  • 针对分布式系统,我们在验收一些场景时,可能需要等待一段时间,目标结果才生效。而这个时间会因为不同集群负载而有所不同。所以简单的硬编码来sleep一个固定时间,很明显不合适。这种场景下若是使用Ginkgo对应的matcher库GomegaEventually功能就非常的贴切,在大大提升用例稳定性的同时,最大可能的减少无用的等待时间。

  • 笔者一直认为,自动化测试用例不应该仅仅是QA手中的工具,而应该尽可能多的作为业务验收服务,输出到CICD,灰度验证,线上验收等尽可能多的场景,以服务于整个业务线。同样利用Ginkgo我们可以很容易做到这一点:

    • CICD: 在定义suite时,使用RunSpecWithDefaultReporters方法,可以让测试结果既输出到stdout,还可以输出一份Junit格式的报告。这样就可以通过类似Jenkins的工具方便的呈现测试结果,而不用任何其他的额外操作。
    • TaaS(Test as a Service): 通过ginkgo build或者原生的go test -c命令,可以方便的将测试用例,编译成package.test的二进制文件。如此的话,我们就可以方便的进行测试服务分发。典型的,如交付给SRE同学,辅助其应对线上灰度场景下的测试验收。所以在测试用例的组织上,这里有个小建议,过往我会看到有同学会习惯一个目录就定义一个suite文件,这样编译出的二进制文件就非常多,不利于分发。所以建议不要定义太多的suite,可以一条产品就一个suite入口,其他的用例包通过_导入进来。

NetworkPolicy

下面列出了所有的网络策略功能

参考资料