当前位置: 首页 > 编程日记 > 正文

《xUnit Test Patterns》学习笔记3 - Philosophy of Test Automation

这一章主要讲自动化测试的原则。前面的章节介绍了很多测试的思想,而思想的东西难免有点虚,这一章就是告诉你,遇到了具体的什么问题时,应该怎么办。作者咨询了很多的开发人员和测试人员,同时也和Martin Fowler就自动化测试的一些原则问题进行了交流,有些是显而易见的,有些又是让人把握不定。因此,这章主要讨论了以下几个问题:

  1. Test First or Last?
  2. Tests or Examples?
  3. Test-by-Test or Test All-at-Once?
  4. Outside-In or Inside-Out?
  5. State or Behavior Verification?
  6. Fixture Design Upfront or Test-by-Test?

Test First or Last?

是应该先写代码还是先写测试案例?作者认为应该先写测试案例,然后再写代码。这也是测试驱动开发和敏捷测试的一个重要原则。这样做的原因有很多,比如:

  1. 对一个已完成或旧的代码编写测试案例,比在代码完成前编写测试案例难的多。(面对一个庞大的已完成的系统时,确实会让人无从下手)
  2. 先写测试案例,可以极大的增强代码的可测性。使得后面编写的代码,天生就具备可测试的能力,因为测试案例已经早于它写好了。
  3. 先写测试案例,可以对后面的编码起到约束作用,避免编码时添加一些臃肿的、根本就不会用到的函数,使得代码看起来更加精简。

个人感受:

先编写测试案例再写代码,的确有很多好处。但是发现真正这样做的人很少,一方面,对于传统的软件开发公司,要做出一些改变确实有些困难。一方面,先编写测试案例带来的好处并不是立竿见影,很多人尝试了一下就放弃了。因此,需要不断的实践,坚持。(我也要努力了)

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?

通常,模块之间会有一些依赖和层次结构,应该从最外层的调用模块开始写案例呢,还是从最里层开始写案例呢?作者的观点是从外到里。

先看下从里到外的情形:

image

上图,从里到外的开发过程更像传统的开发过程,容易理解,实施起来相对简单。但是,这样的顺序有个缺点,就是上层的SUT必须依赖于已经实现的底层的SUT。如果两个模块是不同的人开发的,上层模块的开发必须等底层模块的开发编写完成才能开始工作。同时,最底层的SUT先实现的话,有可能会过度设计,设计出一些上层模块根本就不使用的一些特性。最终使得整个程序的可测性降低。因此,从外向里的过程会好一些:

image

先编写最外层的测试案例,可以使用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

相关文章:

js new 运算符到底做了什么?

MDN上是这么介绍new运算符的:new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一。 这里,我们探究的是new运算符实际上做了什么? var a new A(); 复制代码当这段代码运行的时候,内部实际上执行的是&am…

Qt中文手册 之 QTableWidgetItem

头文件 #include<QTableWidgetItem> 成员函数 1、QTableWidgetItem::QTableWidgetItem(int type = Type) 使用指定item类型type构造。 item的type QTableWidgetItem::Type0默认的类型:窗口部件QTableWidgetItem::UserType1000The minimum value for custom types. Val…

你知道“啥是佩奇”,却不一定了解佩奇排名算法

作者 | 程序员小吴 从初学者的角度学习算法&#xff0c;以动画的形式呈现解题的思路。来源 | 五分钟学算法佩奇排名介绍佩奇排名是根据页面之间的链接结构计算页面的值的一种算法。下面我们通过动画来理解进行计算的具体流程。假设一个正方形表示一个 WEB 页面&#xff0c;一个…

用友发布U8 All-in-One引爆中小企业全面信息化

1月16日&#xff0c;北京经历了2010年第一场大雪和创50年的低温记录后&#xff0c;温度似有回升的感觉。什刹海一座别致建筑二楼的"用友中小企业全面信息化策略暨U8 All-in-One发布会"现场洋溢着融融暖意。用友在这里隆重发布了面向中小企业全面信息化的解决方案--U8…

Qt中文手册 之 QTreeWidgetItem

头文件:#include <QTreeWidgetItem> 成员函数 1、QTreeWidgetItem::QTreeWidgetItem(int type = Type) 使用类型type构造项,默认类型窗口类型 2、QTreeWidgetItem::QTreeWidgetItem(const QStringList & strings, int type = Type) 使用字符串列表strings作为项…

6位技术大咖11月倾心巨献,大数据+安全主题的技术分享合集【阿里云MVP 干货集锦】...

为什么80%的码农都做不了架构师&#xff1f;>>> 摘要&#xff1a; 大家好&#xff0c;阿里云 MVP 11月大数据安全主题分享新鲜出炉&#xff0c;快来一睹为快吧&#xff01;哪些MVP的分享最吸引你&#xff0c;你最想支持哪个MVP&#xff1f; 我们将开启为期一周的最…

linux下jsp环境的搭建

转自http://gehailong.blog.51cto.com/765312/264162作gehailong一 、安装JDK#chmod x jdk-6u13-linux-i586-rpm.bin//给文件加入执行权限#./jdk-6u13-linux-i586-rpm.bin//生成安装文件,运行完此命令后会生成一个jdk-6u13-linux-i586.rpm#rpm -ivh jdk-6u13-linux-i586.rpm//安…

ABP理论学习之通知系统

本篇目录 介绍订阅通知发布通知用户通知管理者实时通知通知存储通知定义介绍 通知&#xff08;Notification&#xff09;用于告知用户系统中的特定事件。ABP提供了基于实时通知基础设施的发布订阅模型&#xff08;pub/sub&#xff09;。 发送模型 给用户发送通知有两种方式&am…

linux驱动:TI+DM8127+GPIO(一)之应用——报警输入输出

一、【GPIO应用】 报警输出1 ALRM_OUT1A、ALRM_OUT1B <-- ALM_OUT1 <-- CVOUT1_YC4 <-- W22 <--VOUT[1]_G_Y_YC[4]/EMAC[1]_MRXD[7]/VIN[1]A_D[9]/PATA_D[1]/GP3[8] /sys/class/gpio/gpio104/value 其中104 32*38 GPIOn_x的编号为32*nx&#xff0c;例如此处用…

Facebook增强版LASER开源:零样本迁移学习,支持93种语言

来源| Facebook AI 研究院译者 | Linstancy责编 | 琥珀出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09;【导语】为了加速自然语言处理 (NLP) 在更多语言上实现零样本迁移学习 (zero-shot transfer learning)&#xff0c;Facebook 研究者扩展并增强了 LASER (Languag…

Python文本预处理:步骤、使用工具及示例

作者 | Data Monster译者 | Linstancy编辑 | 一一出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;本文将讨论文本预处理的基本步骤&#xff0c;旨在将文本信息从人类语言转换为机器可读格式以便用于后续处理。此外&#xff0c;本文还将进一步讨论文本预处理过程所需要…

读《杜拉拉升职记》有感

读杜拉拉升职记有感1.一定要在核心部门任职&#xff0c;防止被边缘化2.劳心者治人&#xff0c;劳力者治于人干了活还受气怎么办&#xff1f;1.把每一个阶段的主要任务和安排的都做成清晰简明的表格&#xff0c;发给我的老板&#xff0c;告诉他如果有反对意见&#xff0c;在某某…

linux驱动:TI+DM8127+GPIO(二)之驱动

二、【GPIO驱动框架》驱动driver】 重要结构体 gpio_chip&#xff1a;管理一组GPIO gpio_desc&#xff1a;描述每个GPIO gpio_bank&#xff1a;封装了gpio_chip加入GPIO控制的属性 1、驱动注册到platform中 Arch/arm/plat-omap/gpio.c中 static int __init omap_gpio_drv…

菜鸟的DUBBO进击之路(八):配置抽离导致${jdbc.url}被当成字符串处理

为什么80%的码农都做不了架构师&#xff1f;>>> 导致这个问题的原因有很多&#xff0c;基于我查到的资料做个记录 第一:xmlns:context"http://www.springframework.org/schema/context" xsi:schemaLocation"http://www.springframework.org/schema/…

用VS2005打开方案出现“此安装不支持该项目类型”

当在用VS2005打开已有项目时常会出现“此安装不支持该项目类型”。 出现此原因是因为已有项目是在打了VS 2005 SP1补丁后编写的&#xff0c;所以在没有打补丁的.net中会出现此种情况 下面就补丁下载&#xff1a;VS80sp1-KB926604-X86-CHS.exeWebApplicationProjectSetup.msi

linux驱动:TI+DM8127+GPIO(三)之omap_hwmod中添加GPIO资源

三、【GPIO驱动框架》向omap_hwmod中添加GPIO资源】 ***将GPIO硬件信息添加到注册到omap_hwmod_list列表中 Arch/arm/plat-omap/include/plat/ti81xx.h中 #define TI814X_GPIO3_BASE 0x481AE000 Arch/arm/plat-omap/gpio.c中 输入输出控制寄存器偏移地址 #define OMAP4…

用Redis存储Tomcat集群的Session(转载)

本文转自http://blog.csdn.net/chszs/article/details/42610365 感谢作者 前段时间&#xff0c;我花了不少时间来寻求一种方法&#xff0c;把新开发的代码推送到到生产系统中部署&#xff0c;生产系统要能够零宕机、对使用用户零影响。 我的设想是使用集群来搞定&#xff0c;通…

微信的Bug差点让我被老板炒鱿鱼!

作者 | 屠敏转载自CSDN&#xff08;ID:CSDNnews&#xff09;1 月 24 日上午 10&#xff1a;30 左右&#xff0c;10 亿用户量的国民应用微信疑似出现大 Bug。据网友反馈&#xff0c;自己一直使用的微信号突然显示被删除&#xff0c;登也登不上。对此&#xff0c;不少人的银行卡一…

vPower系列1: vMotion-没有vMotion,虚拟化只是玩具

vPower今天开讲&#xff0c;第一篇vMotion。vMotion是虚拟化可以支撑核心应用的重要前提&#xff0c;没有vMotion&#xff0c;虚拟化只是玩具&#xff0c;只能应用在实验环境和开发环境。为什么这么说呢&#xff1f;为什么会有vMotion&#xff1f;vMotion解决了虚拟平台上的什么…

linux驱动:TI+DM8127+GPIO(四)之设备

四、【GPIO驱动框架》设备device】 arch/arm/mach-omap2/gpio.c中 1、static int __init omap2_gpio_init(void) { returnomap_hwmod_for_each_by_class("gpio", omap2_gpio_dev_init, NULL); } archarm/mach-omap2/omap_hwmod.c 中 2、int omap_hwmod_for_each…

简单的TableViewCell高度自适应(只有Label,仅当参考思路)

在iOS开发中或多或少的都会碰到TableViewCell高度自适应,那么今天这篇文章就简单的介绍一下如何给tableViewCell自适应高度 #ViewController copy interface ViewController ()<UITableViewDelegate, UITableViewDataSource>{UITableView *_tableView; }property (nonato…

Google发布新的问答语料库,专攻篇章级的NLU问题

译者 | Linstancy整理 | Jane出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;开放域的问答&#xff08;QA&#xff09;是自然语言理解&#xff08;NLU&#xff09;中的一项基本任务&#xff0c;旨在模拟人是如何通过阅读和理解完整的文档&#xff0c;从而寻找信息、发…

AjaxControltoolkit(工具包)安装步骤说明

本来打算做一个系统搜索中Ajax AutoComplete自动提示的效果,想尝试一下以前用AjaxControlToolkit中控件,在官网上下载一个AjaxControlToolkit2.0版本我尽然忘了如何安装.很是汗了一把. 看来人都是有惰性的,哪怕自己认为以前比较熟练自信的东西 如果时间一长不做回顾还是不行的 …

linux驱动:TI+DM8127+GPIO(五)之plarform

五、【GPIO驱动框架》平台platform】 &#xff08;一&#xff09;设备找驱动 1、drivers/base/platform.c中 int platform_device_register(structplatform_device *pdev) { device_initialize(&pdev->dev); returnplatform_device_add(pdev); } 2、int platform_…

2:0!谷歌 AI “AlphaStar“ 虐杀职业星际玩家

作者 | 若名出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;刚刚&#xff0c;在更复杂的《星际争霸 II》游戏中&#xff0c;DeepMind AI 以总比分 2:0 分别战胜两位职业人类选手。这或许是自 2017 年 AlphaGo 在围棋上战胜人类后&#xff0c;再次让人类刷新 AI 认知的…

插件化知识梳理(7) 类的动态加载入门

一、前言 在 插件化知识梳理(6) - Small 源码分析之 Hook 原理 这一章的学习完成之后&#xff0c;下一步我们将进入插件化加载的精髓&#xff0c;动态加载类的学习&#xff0c;在此之前&#xff0c;我们需要先准备一些关于类加载的知识。 Android当中&#xff0c;支持动态加载的…

redhat中使用securecrt 中文乱码解决办法

具体解决方法是&#xff1a; 1&#xff0c;修改远程linux机器的配置 vim /etc/sysconfig/i18n 把LANG改成支持UTF-8的字符集 如&#xff1a;LANG”zh_CN.UTF-8″ 或者是 LANG”en_US.UTF-8″ 2&#xff0c;然后再改Secure CRT的设置,选项->会话选项->外观->字符编码-&…

知否?知否?一文看懂深度文本分类之DPCNN原理与代码

【导读】ACL2017年中&#xff0c;腾讯AI-lab提出了Deep Pyramid Convolutional Neural Networks for Text Categorization(DPCNN)。论文中提出了一种基于word-level级别的网络-DPCNN&#xff0c;由于上一篇文章介绍的TextCNN 不能通过卷积获得文本的长距离依赖关系&#xff0c;…

linux驱动:设备-总线-驱动(以TI+DM8127中GPIO为例)

一&#xff1a;说明&#xff1a;这次学习设备-总线-驱动是以TIDM8127的GPIO为例 1、GPIO资源注册到omap_hwmod链表中 2、初始化GPIO 3、将GPIO注册到plarform层 4、将GPIO注册到device层 二、流程图 1、GPIO资源注册到omap_hwmod链表中 2、初始化GPIO 3、将GPIO注册到pla…

生活总是在推着你一步一步往前走

上早班的时候&#xff0c;无意间看到了关于高考这个字眼。对于我的高考已经过去五年了&#xff0c;但回想起来记忆依旧是那么深刻。记得五年前的那个日子&#xff0c;阳光明媚&#xff0c;空气中到处都是一股夏天的气息&#xff0c;我妈和我哥早早的从家里搭车到县城&#xff0…