自2015年开始,七牛工效团队一直使用Go语言+Ginkgo的组合来编写自动化测试用例,积累了大约5000+的数量。在使用和维护过程中,我们觉得Ginkgo的很多设计理念和功能非常赞,因此特分享给大家。

本篇不是该框架的入门指导。如果您也编写或维护过大量自动化测试用例,希望能获得一些共鸣.

BDD(Behavior Driven Development)

要说Ginkgo最大的特点,笔者认为,那就是对BDD风格的支持。比如:

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

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

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

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

进程级并行,稳定高效

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

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

其他的一些Tips

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

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

    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入口,其他的用例包通过_导入进来。比如:

另外,值得说道的是,Ginkgo框架在提供强大功能和灵活性的同时,有些地方也需要使用者特别留心:

  • DescribeTable功能是对TableDriven模式的友好支持,但它的原理是通过Entry在用例执行之前,通过反射机制来自动生成It方法,所以如果期望类似BeforeEach+It的原生组合来使用BeforeEach+Entry的话,可能在值类型的变量传递上,会不符合预期。其实,相较于DescribeTable+Entry的模式,我个人更倾向于通过方法+多个It的原生组合来写用例,虽然代码量显得有点多,但是用例表达的逻辑主题会更清晰,可读性较高。类似如下:

  • Ginkgo CLI的focus和skip命令非常好用,能够灵活的指定想执行或者排除的测试用例。不过要注意的是,focus和skip传入的是正则表达式,而适配这个正则的,是组成用例的所有的Container标题的组合(Suite+Describe+Context+It), 这些标题从外到里拼接成的完整字符串,所以使用时当注意。

都有谁在用Ginkgo?

Ginkgo的官方文档非常详细,非常利于使用。另外,我们看到著名的容器云项目Kubernetes也是使用Ginkgo框架来编写其e2e测试用例。

最后,如果您也使用Go语言来编写测试用例,不妨尝试下Ginkgo。

Contact me ?

Email: jinsdu@outlook.com

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

Github: https://github.com/CarlJi

高效测试框架推荐之Ginkgo的更多相关文章

  1. 消灭Bug!十款免费移动应用测试框架推荐

      对于移动应用开发者而言,Bug往往是最让人头疼的一大问题.不同于时时刻刻可以修补的Web App,移动App中的Bug往往隐藏得很深,甚至有时候等到用户使用才显现出来,这么一来开发者搞不好就会赔了 ...

  2. #测试框架推荐# test4j,数据库测试

    # 背景 后端都是操作DB的,这块的自动化测试校验的话,是需要数据库操作的,当然可以直接封装方法来操作数据,那么有没有开源框架支持数据操作,让我们关注写sql语句?或者帮我们做mysql的断言呢? # ...

  3. Android开源测试框架学习

    近期因工作需要,分析了一些Android的测试框架,在这也分享下整理完的资料. Android测试大致分三大块: 代码层测试 用户操作模拟,功能测试 安装部署及稳定性测试 代码层测试 对于一般java ...

  4. 十大免费移动程序测试框架(Android/iOS)

    十大免费移动程序测试框架(Android/iOS) 概述:本文将介绍10款免费移动程序测试框架,帮助开发人员简化测试流程,一起来看看吧. Bug是移动开发者最头痛的一大问题.不同于Web应用程序开发, ...

  5. Google推出iOS功能性UI测试框架EarlGrey

    经过了一段时间的酝酿后,Google很高兴地宣布了EarlGrey,一款针对于iOS的功能性UI测试框架.诸如YouTube.Google Calendar.Google Photos.Google ...

  6. 测试框架mochajs详解

    测试框架mochajs详解 章节目录 关于单元测试的想法 mocha单元测试框架简介 安装mocha 一个简单的例子 mocha支持的断言模块 同步代码测试 异步代码测试 promise代码测试 不建 ...

  7. python测试框架总结

    最流行的有unittest和nose 其他的请看http://wiki.python.org/moin/PythonTes... 中Unit Testing Tools部分 py.test unitt ...

  8. Google C++测试框架系列:入门

    Google C++测试框架系列:入门 原始链接:V1_6_Primer 注 GTest或者Google Test: Google的C++测试框架. Test Fixtures: 这个词实在找不到对应 ...

  9. 前端测试框架Jest系列教程 -- Matchers(匹配器)

    写在前面: 匹配器(Matchers)是Jest中非常重要的一个概念,它可以提供很多种方式来让你去验证你所测试的返回值,本文重点介绍几种常用的Matcher,其他的可以通过官网api文档查看. 常用的 ...

随机推荐

  1. Android TextView点击效果

    在Android开发中,我们有时候需要单独的点击某一段文本,如图所示: 如上图,我们要求点击新用户注册这个TextView,为了有更好的用户体验,我们肯定要设置该TextView的点击效果.下面介绍如 ...

  2. PHP调用纯真IP数据库返回具体地址

    function convertip($ip) { $ip1num = 0; $ip2num = 0; $ipAddr1 =""; $ipAddr2 =""; ...

  3. 列出display的值,说明他们的作用。position的值, relative和 absolute定位原点是?

    display的值: block 像块类型元素一样显示. none 像行内元素类型一样显示. inline-block 像行内元素一样显示, 但其内容像块类型元素一样显示. list-item 像块类 ...

  4. [转]swagger2 入门教程

    swagger2 是一个规范和完整的框架,用于生成.描述.调用和可视化Restful风格的web服务,现在我们使用spring boot 整合它 作用: 1.接口的文档在线自动生成 2.功能测试 先介 ...

  5. laravel 常用文档

    [ Laravel 5.6 文档 ] 快速入门 —— 目录结构  laravel学院 http://laravelacademy.org/post/8657.html Laravel 的缓存系统    ...

  6. [转]1.2 java web的发展历史

    前言 了解java web的发展历史和相关技术的演进历程,非常有助于加深对java web技术的理解和认识. 阅读目录 1.Servlet的出现 2.Jsp的出现 3.倡导了MVC思想的Servlet ...

  7. H3C OSPF基本配置命令

  8. 访问HTML可以,访问PHPfile not found

    www目录的所有者和所属组都改为nginx用户试一下. 参考命令: chown nginx.nginx /home/www ps aux |grep nginx   看一下您的nginx是以哪个用户的 ...

  9. npm install 报错(npm ERR! errno -4048,Error: EPERM: operation not permitted)

    问题现象 原因 1.初次看报错日志内容,定义权限为问题,后来查资料才知道是缓存问题. 解决方法 1.简单直接 直接删除 npmrc文件 tips: 不是nodejs安装目录npm模块下的那个npmrc ...

  10. H3C DHCP中继工作原理