《xUnit Test Patterns》学习笔记3 - Philosophy of Test Automation
这一章主要讲自动化测试的原则。前面的章节介绍了很多测试的思想,而思想的东西难免有点虚,这一章就是告诉你,遇到了具体的什么问题时,应该怎么办。作者咨询了很多的开发人员和测试人员,同时也和Martin Fowler就自动化测试的一些原则问题进行了交流,有些是显而易见的,有些又是让人把握不定。因此,这章主要讨论了以下几个问题:
- Test First or Last?
- Tests or Examples?
- Test-by-Test or Test All-at-Once?
- Outside-In or Inside-Out?
- State or Behavior Verification?
- Fixture Design Upfront or Test-by-Test?
Test First or Last?
是应该先写代码还是先写测试案例?作者认为应该先写测试案例,然后再写代码。这也是测试驱动开发和敏捷测试的一个重要原则。这样做的原因有很多,比如:
- 对一个已完成或旧的代码编写测试案例,比在代码完成前编写测试案例难的多。(面对一个庞大的已完成的系统时,确实会让人无从下手)
- 先写测试案例,可以极大的增强代码的可测性。使得后面编写的代码,天生就具备可测试的能力,因为测试案例已经早于它写好了。
- 先写测试案例,可以对后面的编码起到约束作用,避免编码时添加一些臃肿的、根本就不会用到的函数,使得代码看起来更加精简。
个人感受:
先编写测试案例再写代码,的确有很多好处。但是发现真正这样做的人很少,一方面,对于传统的软件开发公司,要做出一些改变确实有些困难。一方面,先编写测试案例带来的好处并不是立竿见影,很多人尝试了一下就放弃了。因此,需要不断的实践,坚持。(我也要努力了)
Tests or Examples?
这一段,说实话,没看懂在讨论什么问题。只看出在表达一个观点,测试案例相对于文档。同时,还提出一个名词:EDD(example-driven development),但后又提到EDD的框架,如RSpec,JBehave,让我有点摸不着头脑,据我说知,RSpec,JBehave应该是BDD框架才对。
作者最后的观点:Tests are examples.
Test-by-Test or Test All-at-Once?
到底是应该写一个测试案例,写一段代码呢,还是应该先把测试案例都写好,再写代码?这个问题比较有意思,因为这是一个非常实际的问题。迭代开发(incremental development)中,有一句话:Test a bit, code a bit, test a bit more。当然,这样的做法是比较理想的,因为这样能够更加准确的定位到代码的问题。但是,作者提到,一个更好的办法,是先列一个提纲,把测试案例的函数都填好,里面的实现为空。然后,每次填充一个测试案例,写一段代码。
我的观点:
和作者一样。比如,在需要编写一个类前,先假设自己就是代码的调用者,把Test Fixture中的测试案例罗列一下,然后再逐个完成测试案例。每编写完一个测试案例,就把相应的代码实现一下。
Outside-In or Inside-Out?
通常,模块之间会有一些依赖和层次结构,应该从最外层的调用模块开始写案例呢,还是从最里层开始写案例呢?作者的观点是从外到里。
先看下从里到外的情形:
上图,从里到外的开发过程更像传统的开发过程,容易理解,实施起来相对简单。但是,这样的顺序有个缺点,就是上层的SUT必须依赖于已经实现的底层的SUT。如果两个模块是不同的人开发的,上层模块的开发必须等底层模块的开发编写完成才能开始工作。同时,最底层的SUT先实现的话,有可能会过度设计,设计出一些上层模块根本就不使用的一些特性。最终使得整个程序的可测性降低。因此,从外向里的过程会好一些:
先编写最外层的测试案例,可以使用Test Double对象替代被调用的底层模块,使得SUT天然就具备很好的可测性(依赖注入)。同时,由于时刻都是保持“从用户或调用者的角度去思考”,使得SUT对象实现起来目标更加明确,实现的更加精简,从而避免了过度的设计。
State or Behavior Verification?
提出的问题是,应该使用基于状态的验证,还是基于行为的验证?基于状态的验证是指在调用SUT后只检查SUT的状态,比如返回值,比如一个求和函数,最后检查一下求和的结果是否正确。而基于行为的验证,通常是,SUT被调用后,不仅仅改变SUT的状态,还会产生其他影响。比如,一个用户注册的函数,除了要检查返回值是否注册成功,还要坚持数据库中是否写入了新的用户记录。BDD(behavior-driven development),就是基于行为的验证方式。作者最后说,他主要使用基于状态的验证,但有时为了追求代码覆盖率,会使用基于行为的验证。
我的理解:
对于功能单一,简单,设计良好的代码,使用State Verification确实已经足够。但往往真实的系统是很复杂的,模块之间互相调用,单个函数的功能可能也不是那么单一。基于行为的测试,其实就是站在了用户的角度,去验证各种行为所产生的各种影响。
Fixture Design Upfront or Test-by-Test?
Fixture是某一类案例的集合,一种观点是,让很多案例都共享一个Fixture,每个测试案例的方法执行时都会创建一个新的Fixture实例,并在案例前执行其中的SetUp方法。另一种观点是,前一个观点的做法,会让案例看起来不那么清晰,不容易找到一个测试案例的方法到底会执行哪些SetUp或TearDown的方法。因此,提出了在每个测试案例方法中,使用自定义的Minimal Fixture,而不是使用一个大的,不容易找到或理解的Fixture。
我的感受:
这一点我也有感受,我也发现我写的一些测试案例,都喜欢让很多Test Class继承一个基类Fixture,在里面定义SetUp和TearnDown,同时,子类中,还可以添加额外方法执行一些准备和清理的操作。这样,使得我的测试案例看起来并不清晰,因为很难从我的测试案例的函数中看出,我到底在SetUp里做了些什么,以及执行了哪些SetUp操作。
转载于:https://www.cnblogs.com/coderzh/archive/2010/01/21/xUnit-Test-Patterns-3.html
《xUnit Test Patterns》学习笔记3 - Philosophy of Test Automation相关推荐
- 《xUnit Test Patterns》学习笔记4 - Principles of Test Automation
自动化测试过程中,有一些基本的原则,就如同宣言(Manifesto).由于大部分的原则在前面其实都提到的,因此,有的不做太多说明了. 原则:Write the Tests First 原则:Desig ...
- 《xUnit Test Patterns》学习笔记2 - Goal Of Test Automation
或许有人觉得单元测试可有可无,因为觉得需要付出太多的精力,而客户并不需要它.这就涉及到投资回报率的问题,其实所付出的用于测试的投资,往往会收获到更多回报.它让我们减少了Bug的数量,减少了调试代码寻找 ...
- 大卫的Design Patterns学习笔记19:Observer
一.概述 Observer(观察者)模式又被称作发布-订阅(Publish -Subscribe)模式,用于定义对象间的一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自 ...
- Structural patterns (proxy、bridge、decorator)学习笔记(一)
Structural patterns (proxy.bridge.decorator)学习笔记(一) 一.proxy pattern是实际应用中,一般都用于比较复杂的一些对象当中,尤其是创建对象需要 ...
- CSS3秘笈第三版涵盖HTML5学习笔记6~8章
第二部分----CSS实用技术 第6章,文本格式化 指定备用字体: font-family:Arial,Helvetica,sans-serif; 当访问者没有安装第一种字体时,浏览器会在列表中继续往 ...
- ELK学习笔记之Logstash详解
0x00 Logstash概述 官方介绍:Logstash is an open source data collection engine with real-time pipelining cap ...
- Redis学习笔记(五)——持久化及redis.conf配置文件叙述
对于日常使用来说,学习完SpringBoot集成Redis就够我们工作中使用了,但是既然学习了,我们就学习一些Redis的配置及概念,使我们可以更深层次的理解Redis,以及增强我们的面试成功概率,接 ...
- MNE学习笔记(六):Epoched data的可视化
MNE学习笔记(六):Epoched data的可视化 参考文章:https://mne.tools/stable/auto_tutorials/epochs/20_visualize_epochs. ...
- MOOC人工智能原理学习笔记1
人工智能原理学习笔记1 The Foundations of AI: Philosophy Mathematics Economics Neuroscience Psychology Computer ...
最新文章
- Python 之 matplotlib (八)Bar
- 9月份准备备考RHCE 10份考试争取一次通过
- python字符类型的一些方法
- Shell Basic
- [Java]向上/下转型Casting
- qtdesigner右击按钮没有 to slot_或添加“力感按钮”再升级,Apple Pencil会更“能打”?...
- 手动实现bind函数(附MDN提供的Polyfill方案解析)
- ssh相互访问不用密码
- 高级程序员不写代码?
- 计算机缩写术语完全介绍
- HTML基础入门教程
- elasticsearch+filebeat+kibana实现系统日志收集
- 中西方对时间的差异_中西方时间观差异的跨文化分析
- 互联网商业模式O2O、C2C、B2B、B2C等介绍
- Bootstrap3 Font Awesome 字体图标的基本图标
- AsyncTask下载网络图片并显示下载进度
- html5 dpi,关于meta viewport中target-densitydpi属性详解(推荐)_哒哒_前端开发者
- 使用matlab编程给qq或163邮箱等发邮件
- VB和VBS、VBA的区别及作用
- Cmake在VS下设置MT
热门文章
- js:appendChild、insertBefore和insertAfter
- SQLDataSet中执行DDL语句
- 搭建Solr集群的推荐方案
- Lichee(三) Android4.0该产品的目标文件夹,Lichee链接---extract-bsp
- 什么是LAN(局域网)
- c语言面向对象编程中的类_C ++中的面向对象编程
- clojurescript_为什么ClojureScript在NPM上如此出色
- unity 灯笼_如何创建将自己拼成文字的漂亮灯笼
- 为什么您不需要精通数学就可以学习编程
- 【学习笔记】git 使用文档