极客时间已完结课程限时免费阅读

33 | 如何做好验收测试?

33 | 如何做好验收测试?-极客时间

33 | 如何做好验收测试?

讲述:郑晔

时长10:24大小14.29M

你好,我是郑晔。
经过前面三讲的讲解,相信你对一个项目自动化应该是什么样子有了一个相对完整的认识:程序员写好程序,用构建脚本执行检查,提交代码,在服务器上打出一个发布镜像,部署到各个环境进行检查,检查好了,随时可以发布上线。
我们在前面的内容中只说了该检查,但怎么检查呢?这就轮到测试发挥作用了。
在“任务分解”的模块,我给你完整地介绍了一下开发者测试的概念,但在那个部分讲解的测试基本上还停留在单元测试和集成测试的范畴。对于整个应用该怎么测,我们并没有仔细讨论。
今天我们就来说说应用测试的话题:验收测试。

验收测试

验收测试(Acceptance Testing),是确认应用是否满足设计规范的测试。这种测试往往是站在用户的角度,看整个应用能否满足业务需求。
从名字上来看,验收应该是业务人员的事,但业务人员能做的最多只是验收,测试是他们无论如何也不太可能做仔细的。
所以,验收测试这件事,往往还是由技术团队自己完成,而且在很多公司,这就是测试人员的事。
时至今日,很多测试团队都拥有自动化的能力。所以,自动化验收测试自然是重点考虑对象。今天,我们的重点就是怎么做好自动化的验收测试。
其实,验收测试应该是人们最早想到的自动化测试,早在单元测试还不流行的年代,人们就开始了对自动化验收测试的探索。有不少团队甚至还构建了自己的框架,只不过,这种框架不是我们今天理解的测试框架,而是针对着一个应用的测试框架。
比如,我曾经见过有人为通信软件构建的一套完整的测试框架,甚至构建了属于自己的语言,测试人员的工作就是用这种特定的语言,对系统进行设置、运行,看它是否满足自己的预期。
相对来说,他们的这种做法已经非常成熟了。但更多团队的现实情况是,自己把对应用的访问做一个简单的封装,然后,写测试就是编写代码调用这个封装。
让验收测试从各自为战的混乱中逐渐有了体系的是行为驱动开发(Behavior Driven Development)这个概念的诞生,也就是很多人知道的 BDD。

行为驱动开发

行为驱动开发中的行为,指的是业务行为。BDD 希望促进业务人员与开发团队之间的协作,换句话说,如果你想做 BDD,就应该用业务语言进行描述。
这与我们传统上理解的系统测试有着很大的差别,传统意义上的系统测试是站在开发团队的角度,所以,更多的是在描述系统与外部系统之间的交互,用的都是计算机的术语。
而 BDD 则让我们换了一个视角,用业务语言做系统测试,所以,它是一个更高级别的抽象。
BDD 是 2003 年由 Dan North 提出了来的。Dan North 不仅仅提出了概念,为了践行他的想法,他还创造了第一个 BDD 的框架:JBehave。后来又改写出基于 Ruby 的版本 RBehave,这个项目后来被并到 RSpec 中。
今天最流行的 BDD 框架应该是 Cucumber,它的作者就是 RSpec 的作者之一 Aslak Hellesøy。
Cucunber 从最开始的 Ruby BDD 框架发展成今天支持很多不同程序设计语言的 BDD 测试框架,比如,常见的 Java、JavaScript、PHP 等等。
BDD 框架给我们最直观的感受就是它给我们提供的一套语言体系,供我们描述应用的行为,下面是一个例子,它描述了一个交易场景,应用需要根据交易结果判定是否要发出警告。你可以感受一下:
Scenario: trader is not alerted below threshold
Given a stock of symbol STK1 and a threshold of 10.0
When the stock is traded at 5.0
Then the alert status should be OFF
Scenario: trader is alerted above threshold
Given a stock of symbol STK1 and a threshold of 10.0
When the stock is traded at 11.0
Then the alert status should be ON
我们在这里的关注点是这个例子的样子,首先是描述格式:“Given…When…Then”,这个结构对应着这个测试用例中的执行步骤。Given 表示的一个假设前提,When 表示具体的操作,Then 则对应着这个用例要验证的结果。
还记得我们讲过的测试结构吗?前置准备、执行、断言和清理,这刚好与“Given…When…Then”做一个对应,Given 对应前置条件,When 对应执行,Then 则对应着断言。至于清理,它会做一些资源释放,属于实现层面的内容,在业务层面上意义不大。
了解了格式,我们还要关心一下内容。你会看到这里描述的行为都是站在业务的角度进行叙述的,而且 Given、When、Then 都是独立的,可以自由组合。也就是说,一旦基础框架搭好了,我们就可以用这些组成块来编写新的测试用例,甚至可以不需要技术人员参与。
不过,这些内容都是站在业务角度的描述,没有任何实现的内容,那实现的内容放在哪呢?
我们还需要定义一个胶水层,把测试用例与实现联系起来的胶水层,在 Cucumber 的术语里,称之为步骤定义(Step Definition)。这里我也给出了一个例子,你可以参考一下:
public class TraderSteps implements En {
private Stock stock;
public TraderSteps() {
Given("^a stock of symbol {string} and a threshold of {double}", (String symbol, double threshold) -> {
stock = new Stock(symbol, threshold);
});
When("^the stock is traded at {double}$", (double price) -> {
stock.tradeAt(price);
});
Then("the alert status should be {string}", (String status) -> {
assertThat(stock.getStatus().name()).isEqualTo(status);
})
}
}

写好验收测试用例

有了对 BDD 框架的基本了解,接下来的问题就是,怎么用好 BDD 框架。我们举个简单的例子,如果我们要写一个登录的测试用例,你会怎么写呢?
有一种写法是这样的,为了方便叙述,我把它转成了中文描述的格式,Cucumber 本身是支持本地化的,你可以使用自己熟悉的语言编写用例:
假定 张三是一个注册用户,其用户名密码分别是 zhangsan 和 zspassword
当 在用户名输入框里输入 zhangsan,在密码输入框里输入 zspassword
并且 点击登录
那么 张三将登录成功
这个用例怎么样呢?或许你会说,这个用例挺好的。如果你这么想,说明你是站在程序员的视角。我在前面已经说过了,BDD 需要站在业务的角度,而这个例子完全是站在实现的角度。
如果登录方式有所调整,用户输完用户名密码自动登录,不需要点击,那这个用例是不是需要改呢?下面我换了一种方式描述,你再感受一下:
假定 张三是一个注册用户,其用户名密码是分别是 zhangsan 和 zspassword
当 用户以用户名 zhangsan 和密码 zspassword 登录
那么 张三将登录成功
这是一个站在业务视角的描述,除非做业务的调整,不用用户名密码登录了,否则,这个用例不需要改变,即便实现的具体方式调整了,需要改变的也是具体的步骤定义。
所以,想写好 BDD 的测试用例,关键点在用业务视角描述。
编写验收测试用例的步骤定义时,还有一个人们经常忽略的点:业务测试的模型。很多人的第一直觉是,一个测试要啥模型?还记得我们讲好测试应该具备的属性吗?其中一点就是 Professional,专业性。想要写好测试,同写好代码是一样的,一个好的模型是不可或缺的。
这方面一个可以参考的例子是,做 Web 测试常用的一个模型:Page Object。它把对页面的访问封装了起来,即便你在写的是步骤定义,你也不应该在代码中直接操作 HTML 元素,而是应该访问不同的页面对象。
以前面的登录为例,我们可能会定义这样的页面对象:
public class LoginPage {
public boolean login(String name, String password) {
...
}
}
如此一来,在步骤定义中,你就不必关心具体怎么定位到输入框,会让代码的抽象程度得到提升。
当然,这只是一个参考,面对你自己的应用时,你要考虑构建自己的业务测试模型。

总结时刻

今天我和你分享了自动化验收测试的话题。验收测试(Acceptance Testing),是确认应用是否满足设计规范的测试。验收测试是技术交付必经的环节,只不过,各个团队实践水平有所差异,有的靠人工,有的用简单自动化,一些做得比较好的团队才有完善的自动化。
自动化验收测试也是一个逐步发展的过程,从最开始的各自为战,到后来逐渐形成了一个完整的自动化验收测试的体系。
今天,我以行为驱动开发(Behavior Driven Development,BDD)为核心,给你介绍了一种自动化验收测试的方式。这个在 2003 年由 Dan North 提出的概念已经成为了一套比较完善的体系,尤其是一些 BDD 框架的发展,让人们可以自己的项目中实践 BDD。
我以 Cucumber 为样例,给你介绍了 BDD 验收用例的编写方式,你知道“Given…When…Then”的基本格式,也知道了要编写步骤定义(Step Definition)将测试用例与实现连接起来。
我还给你介绍了编写 BDD 测试用例的最佳实践:用业务的视角描述测试用例。在编写步骤定义时,还要考虑设计自己的业务测试模型。
其实,验收测试的方法不止 BDD 一种,像实例化需求(Specification by Example,SbE)也是一种常见的方法。验收测试框架也不止 BDD 框架一类,像 Concordion 这样的工具甚至可以让你把一个验收用例写成一个完整的参考文档。
如果你有兴趣,可以深入地去了解。无论哪种做法,都是为了缩短业务人员与开发团队之间的距离,让开发变得更加高效。
如果今天的内容你只能记住一件事,那请记住:将验收测试自动化。
最后,我想请你分享一下,你的团队是怎么做验收测试的呢?欢迎在留言区分享你的做法。
感谢阅读,如果你觉得这篇文章对你有帮助的话,也欢迎把它分享给你的朋友。
分享给需要的人,Ta购买本课程,你将得20
生成海报并分享

赞 16

提建议

上一篇
32 | 持续交付:有持续集成就够了吗?
下一篇
34 | 你的代码是怎么变混乱的?
unpreview
 写留言

精选留言(17)

  • 西西弗与卡夫卡
    2019-03-27
    之前团队就有人自己开发了一套DSL用来描述验收测试用例,自己跑各种测试,从构建依赖环境,启动虚拟机,到运行测试,不亦乐乎。我发现真有一类人迷恋这种做法,愿意把代码和测试代码以及验收测试代码写得很好,即便开始的时候要花比较多时间,他们非常享受测试通过后的绿色bar。虽然过于迷恋未必有利于项目,但据我观察大多有这样工作习惯的技术人员都很出色

    作者回复: 我很喜欢一个说法,软件工匠,把写代码这件事当做手艺活来不断打磨。

    27
  • helloworld
    2019-05-05
    类似BDD这种行为驱动开发相关的内容,包括其已有的框架Concordion是第一次了解到,长见识了。不过在我的了解中,能够践行这种验收测试的公司应该很少吧?

    作者回复: 做测试的程序员不多,做BDD的人就更少,所以,只要学会这些东西,就比业界大部分程序员水平高了。

    10
  • 行与修
    2019-03-31
    如果在理想状态下,单元测试、持续集成和系统测试等都做的很好,那么验收测试一把过是不是就顺理成章了甚至不需要了?它们几个在软件生命周期里侧重些什么?验收测试作为一个主题单独讲解是不是说明前几个还不能保证足够完善或者需要从别的视角对它们做出修正呢?

    作者回复: 你都说了“理想状态”下,现实情况是,理想状态不存在。验收测试就是站在业务的视角看待系统的一个过程,而其它几个都是站在软件本身的角度在看。 以我对开发做测试这件事的理解来看,开发人员在测试用例设计上,与测试人员还是有很大差距的,测试人员总是可以探索出不同的角度打败你。

    7
  • 苦行僧
    2019-03-27
    验收测试和常规的集成测试 有什么区别?

    作者回复: 一般说集成测试,还是站在内部的角度,也就是技术的角度在说,而验收测试应该是站在业务的角度,没做好的另当别论。

    7
  • shniu
    2019-03-27
    自动化验收测试确实是很好的东西,比如在回归测试,省去了很多的重复工作。但我理解BDD的初衷是驱动产品、业务、开发、测试等去深入讨论沟通需求,在还没有真的写代码的时候去实例化story,并一起定义验收用例,让每个人对需求的理解都很透彻,当然特别注意的是要从统一的业务角度去描述,可见,真的做好BDD是需要不断的尝试和总结的。

    作者回复: 你的理解很对,BDD 不太可能一蹴而就,需要各方不断磨合。

    5
  • Geek_fe0336
    2019-03-27
    请教老师,有真实项目中的一些验收测试的例子吗?有github上的项目可借鉴的吗?

    作者回复: 我还真不知道哪个开源项目这么做,我都是在内部项目上这么做的。

    2
  • 宝宝太喜欢极客时间了
    2019-03-27
    老师,selenium跟Cucumber,端到端测试跟验收测试,有区别吗?

    作者回复: 对比这里的例子,Selenium是用来实现这里的步骤定义的。

    2
  • Jxin
    2019-03-27
    公司老项目,没有测试代码,更别说bdd自动化验收代码了。不过我在尝试为核心的一些业务补充测试代码。刚好可以研究下。有价值的活动不仅仅是写需求,如果只是验收需求,整成自动化验收成本是比较高的,业务不见个愿意买单。但如果说成减少测试队友重复工作,提高需求开发速度和项目可扩展性与健壮性(利于重构,而重构能产生以上价值),并给出大概的量化指标,大部分业务都会再斟酌下的。

    作者回复: 关于遗留系统的讨论正在不远处等着你。

    1
  • enjoylearning
    2019-03-27
    作者给出的参考链接和一些参考书名都很好,国内项目实施BDD的很少吧,可能客户觉得这很浪费时间,或者他们觉得开发做这个他们要承受一些成本

    作者回复: 不做的理由有一万个,做的理由有一个就够了!

    2
  • 冰激凌的眼泪
    2019-03-27
    验收测试是不是针对业务需求的测试?

    作者回复: 对,应该是这样的。

    1
  • 梦倚栏杆
    2019-03-27
    我没有明白举那个例子的意义,配置文件写了几段话,程序里写胶水代码去支持,这个感觉也不动态啊,这不是绑死了吗?

    作者回复: 这里面在业务层需要组合的代码是 Given...When...Then 的部分。当你有了足够的基础描述之后,就可以任意组合这些语句了。至于胶水层代码,它本来就是为了支持每一个 Given/When/Then 的实现,不需要更多的能力。

    1
  • 蓝色海洋
    2022-05-25
    没有听说过验收自动化测试的概念,受教了
  • ifelse
    2022-04-27
    将验收测试自动化,最佳实践:bdd
  • Gojustforfun
    2021-08-26
    这个验收测试是否就是将“以终为始”篇中用户故事的需求验收标准自动化后形成的? BDD与ATDD(验收测试驱动开发)有什么区别呢?

    作者回复: 验收标准是很好的起点,但验收标准不一定就是全部,我们可以把在开发过程中发现的新东西也做成测试。 从宽泛的角度看,BDD 和 ATDD 是差不多的,在细节上,BDD 更强调对于业务的描述。

  • 陈伟
    2020-12-30
    快速迭代中持续集成 持续验收 忽略整体验收是不是比较危险?有没有成本比较低的做法解决这一问题?

    作者回复: 在持续集成或持续交付中加入自动化验收测试。

  • Stephen
    2020-12-28
    一开始总以为验收测试就是系统测试,后来发现系统测试是不直接测试业务规则的,而验收测试也有人称它为QA测试

    作者回复: 不同的公司对于不同的测试,叫法会有所差别。

  • 晓小东
    2019-03-27
    我的团队在做一个web项目, 随着业务复杂, 一个迭代开发完成后, 经常会发现系统某些隐藏的功能用例不在了,除了前面所讲项目中增加单元测试, code-review 外, 如果从自动化验收测试角度, 该如何检查出这样的问题。我们团队测试一般针对当前迭代功能需求进行人工验收测试。很难做不到把系统所有用例都进行一番测试。所有很是一个头疼事, 每次迭代都存在风险。

    作者回复: 当问题确实出现了,你就知道一些实践的价值了。