前言

Kubernetes的成功少不了大量工程师的共同参与,而他们之间如何高效的协作,非常值得我们探究。最近研究和使用了他们的e2e测试和框架,还是挺有启发的。

怎样才是好的e2e测试?

不同的人写出的测试用例千差万别,尤其在用例,可能由开发人员编写的情形下,其情形可想而知。要知道,绝大多数开发人员,可能并没有经历过大量测试用例场景的熏陶。所以如何持续输出高质量的e2e测试用例,确实是一个挑战。不过,Kubernetes社区非常聪明,他们抽象出来了一些共性的东西,来希望大家遵守。比如说

  1. 拒绝“flaky”测试 - 也就是那些偶尔会失败,但是又非常难定位的问题。
  2. 错误输出要详细,尤其是做断言时,相关信息要有。不过也不要打印太多无效信息,尤其是在case并未失败的情况。
  3. make case run in anywhere。这一点很重要,因为你的case是提交到社区,可能在各种环境下,各种时间段内运行。面对着各种cloud provider,各种系统负载情况。所以你的case要尽可能稳定,比如APICall,能异步的,就不要假设是同步; 比如多用retry机制等。
  4. 测试用例要执行的足够快。超过两分钟,就需要给这种测试打上[SLOW]标签。而有这种标签的测试用例,可以运行的场景就比较有限制了。谁又不希望自己写的用例都被尽可能的执行呢?很有激励性的一条规则。

另外,社区不过定下规则,还开发和维护了一系列的基础设施,来辅助上面规则的落地。我们接下来要讲的e2e框架就是其中之一。

e2e 验收测试

搞过测试的应该都知道,在面对复杂系统测试时,我们通常有多套测试环境,但是测试代码通常只有一份。所以为了能更好的区分测试用例,通常采取打标签的方式来给用例分类。这在Kubernetes的e2e里,这也不例外。

Kubernetes默认将测试用例分为下面几类,需要开发者在实际开发用例时,合适的使用。

  • 没标签的,默认测试用例是稳定的,支持并发,且运行足够快的
  • [Slow] 执行比较慢的用例.(对于具体的时间阈值,Kubernetes不同的文档表示不一致,此处需要修复)
  • [Serial] 不支持并发的测试用例,比如占用太多资源,还比如需要重启Node的
  • [Disruptive] 会导致其他测试用例失败或者具有破坏性的测试用例
  • [Flaky] 不稳定的用例,且很难修复。使用它要非常慎重,因为常规CI jobs并不会运行这些测试用例
  • [Feature:.+] 围绕特定非默认Kubernetes集群功能或者非核心功能的测试用例,方便开发以及专项功能适配

当然除了以上标签,还有个比较重要的标签就是[Conformance], 此标签用于验收Kubernetes集群最小功能集,也就是我们常说的MAT测试。所以如果你有个私有部署的k8s集群,就可以通过这套用例来搞验收。方法也很简单,通过下面几步就可以执行:

# under kubernetes folder, compile test cases and ginkgo tool
make WHAT=test/e2e/e2e.test && make ginkgo # setup for conformance tests
export KUBECONFIG=/path/to/kubeconfig
export KUBERNETES_CONFORMANCE_TEST=y
export KUBERNETES_PROVIDER=skeleton # run all conformance tests
go run hack/e2e.go -v --test --test_args="--ginkgo.focus=\[Conformance\]"

注意,kubernetes的测试使用的镜像都放在GCR上了,如果你的集群在国内,且还不带翻墙功能,那可能会发现pod会因为下载不了镜像而启动失败。

Kubernetes e2e test framework

研究Kubernetes的e2e测试框架,然后类比我们以往的经验,个人觉得,下面几点特性还是值得借鉴的:

All e2e compiled into one binary, 单一独立二进制

在对服务端程序进行API测试时,我们经常会针对每个服务都创建一个ginkgo suite来框定测试用例的范围,这样做的好处是用例目标非常清晰,但是随着服务数量的增多,这样的suite会越来越来多。从组织上,看起来就稍显杂乱,而且不利于测试服务的输出。

比如,我们考虑这么一个场景,QA需要对新机房部署,或者私有机房进行服务验证。这时候,就通常需要copy所有代码到指定集群在运行了,非常的不方便,而且也容易造成代码泄露。

kubernetes显然也会有这个需求,所以他们改变写法,将所有的测试用例都编译进一个e2e.test的二进制,这样针对上面场景时,就可以直接使用这个可执行文件来操作,非常的方便。

当然可执行文件的方便少不了外部参数的自由注入,以及整体测试用例的精心标记。否则,测试代码写的不规范,需要频繁的针对特定环境修改,也是拒不方便的。

Each case has a uniqe namespace, 每个case拥有唯一的空间

为每条测试用例创建一个独立的空间,是kubernetes e2e framework的一大精华。每条测试用例独享一个空间,彼此不冲突,从而根本上避免并发困扰,借助ginkgo的CLI来运行,会极大的提高执行效率。

而且这处代码的方式也非常优美,很有借鉴价值:

func NewFramework(baseName string, options FrameworkOptions, client clientset.Interface) *Framework {
f := &Framework{
BaseName: baseName,
AddonResourceConstraints: make(map[string]ResourceConstraint),
Options: options,
ClientSet: client,
} BeforeEach(f.BeforeEach)
AfterEach(f.AfterEach) return f
}

利用ginkgo 的BeforeEach的嵌套特定,虽然在Describe下就定义framework的初始化(如下),但是在每个It执行前,上面的BeforeEach才会真正执行,所以并不会有冲突:

var _ = framework.KubeDescribe("GKE local SSD [Feature:GKELocalSSD]", func() {
f := framework.NewDefaultFramework("localssd")
It("should write and read from node local SSD [Feature:GKELocalSSD]", func() {
...
})
})

当然e2e框架还负责case执行完的环境清理,并且是按需灵活配置。比如你希望,case失败保留现场,不删除namespace,那么就可以设置flag 参数 delete-namespace-on-failure为false来实现。

Asynchronous wait,异步等待

几乎所有的Kubernetes操作都是异步的,所以不管是产品代码还是测试用例,都广泛的使用了这个异步等待库:kubernetes/vendor/k8s.io/apimachinery/pkg/util/wait。这个库,实现简单,精悍,非常值得学习。

另外,针对测试的异步验证,其实ginkgo(gomega)本身提供的Eventualy,也是非常好用的。

Suitable logs,打印合适的log

Kubernetes e2e 主要使用两种方式输出log,一个是使用glog库,另一个则是framework.Logf方法。glog本身是golang官方提供的log库,使用比较灵活。但是这里主要推荐的还是Framework.Logf。因为使用此方法的log会输出到GinkgoWriter里面,这样当我们使用ginkgo.RunSpecsWithDefaultAndCustomReporters方法时,log不光输出到控制台,也会保存在junit格式的xml文件里,非常方便在jenkins里展示测试结果。

Clean code, 测试代码也可以很干净,优美

很多时候大家会觉得测试代码比较low,其实却不然。代码无所谓优劣,好坏还是依赖写代码的人。而且我想说,测试代码也是可以,并且应该写的很优美的,不然如何提升逼格?!。

我们从Kubernetes e2e能看到很多好的借鉴,比如:

  • 抽取主干方法,以突出测试用例主体
  • 采用数据驱动方式书写共性测试用例
  • 注释工整,多少适宜
  • 不输出低级别log
  • 代码行长短适宜
  • 方法名定义清晰,可读性强

Kubernetes环境普适性的e2e测试框架

现实中,如果需要围绕k8s工作,你可能需要一套,自己的测试框架。不管是测试各种自定义的controller or watcher,还是测试运行在k8s里运行的私有服务。这套框架都适用于你:

https://github.com/CarlJi/golearn/tree/master/src/carlji.com/experiments/k8s_e2e_mat_framework

逻辑改动很小,只是在原有kubernetes e2e 框架基础上抽取了最小集合。以方便快速使用。

是不是很贴心?

童鞋,点个赞吧(⊙o⊙)?

参考文档

Contact me ?

Email: jinsdu@outlook.com

Blog: http://www.cnblogs.com/jinsdu/

Github: https://github.com/CarlJi


Kubernetes e2e test and test framework的更多相关文章

  1. kubernetes高级之动态准入控制

    系列目录 动态准入控制器文档介绍了如何使用标准的,插件式的准入控制器.但是,但是由于以下原因,插件式的准入控制器在一些场景下并不灵活: 它们需要编译到kube-apiserver里 它们仅在apise ...

  2. kube-scheduler的调度上下文

    前一章节了解到了kube-scheduler中的概念,该章节则对调度上下文的源码进行分析 Scheduler Scheduler 是整个 kube-scheduler 的一个 structure,提供 ...

  3. windows类书的学习心得

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  4. 第24 章 : Kubernetes API 编程利器:Operator 和 Operator Framework

    Kubernetes API 编程利器:Operator 和 Operator Framework 本节课程主要分享以下三方面的内容: operator 概述 operator framework 实 ...

  5. [E2E] Robot Framework introduction

    We will use demo project as an example, go though QuickStart repo. Install: First you should have py ...

  6. Kubernetes系统架构简介

    1. 前言 Together we will ensure that Kubernetes is a strong and open container management framework fo ...

  7. angular 调试 js (分 karms protractor / test e2e unit )

    首页订阅 Protractor端到端的AngularJS测试框架教程 2014年01月18日 分类:教程, JavaScript, AngularJS Protractor是一个建立在WebDrive ...

  8. Kubernetes系统架构简介--转

    原文地址:http://www.infoq.com/cn/articles/Kubernetes-system-architecture-introduction?utm_campaign=infoq ...

  9. 【云计算】Kubernetes、Marathon等框架需要解决什么样的问题?

    闲谈Kubernetes 的主要特性和经验分享       Capitalonline全球云主机.全球私有网络,免费试用进行时 »   主要介绍 Kubernetes 的主要特性和一些经验.先从整体上 ...

随机推荐

  1. 51nod_1627:瞬间移动

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1627 还是杨辉三角~ #include<bits/st ...

  2. Docker for windows10 配置镜像加速

    windows玩docker的时候,经常碰到这种问题: Error response from daemon: Get https://registry-1.docker.io/v2/: net/ht ...

  3. 如何重置密码 oracle sys和system

    有时候我们会忘记oracle sys和system的密码,不用担心,通过sqlplus即可修改密码.只能修改,不能找回. 方法如下: 1.打开 cmd界面,输入sqlplus /nolog 显示结果如 ...

  4. 如何通过binlog获取我们想要的MySql语句?

    前言 MySql的binlog一般用于我们对数据的恢复,以及从数据库对主数据库的复制和更新. 假设此时我们有一个需要查询和读取Mysql最近操作DDL的信息,我们需要怎么处理? 聪明的你可能已经想到了 ...

  5. 使用Jexus 5.8.2在Centos下部署运行Asp.net core

    这里安装的Jexus不是独立版本,所以需要先安装Mono   系统版本:Cenos7,Mono版本:5.0.1 Stable (5.0.1.1) Mono官方doc:http://www.mono-p ...

  6. swift UITapGestureRecognizer获取点击事件点击的位置point

    func picTap(sender: UITapGestureRecognizer) { let point = sender.location(in: sender.view) } 其中获取的po ...

  7. C#上位机串口控制12864显示

    实现的效果 上面是用Proteus仿真的,,对了如果自己想用proteus仿真需要安装下面这个软件 再看一下实物显示效果 先做上位机部分........... 为了程序一启动就把电脑上能用的串口号显示 ...

  8. TestNG的组测试和组中组测试

    在编写测试的过程中,我们经常遇到只想执行个别或者某一部分/某一类型的测试用例,这时我们可以使用TestNG的分组测试方法 分组测试在配置时,TestNG执行的原则是:只保留最小集合进行执行 看代码: ...

  9. Gitlab CI 自动部署 asp.net core web api 到Docker容器

    为什么要写这个? 在一个系统长大的过程中会经历不断重构升级来满足商业的需求,而一个严谨的商业系统需要高效.稳定.可扩展,有时候还不得不考虑成本的问题.我希望能找到比较完整的开源解决方案来解决持续集成. ...

  10. Git版本控制之多人协作

         上篇文章我们主要简单的介绍了有关git的一些基本常识和一些简单的命令.但那终究是皮毛,我们使用git最主要的目的还是管理我们的项目,多人协作.本篇文章主要涉及以下两个大模块: 分支的概念及原 ...