- 浏览: 450150 次
- 性别:
- 来自: 北京
博客专栏
-
张小庆,在路上
浏览量:8576
文章分类
最新评论
-
bad_brain:
很好的文章,帮助我快速了解zookeeper提供的能力以及为什 ...
Zookeeper与paxos算法 -
ixu:
支持,已经买了 是对工作流和BPM的很好总结啊
无知者无畏,一本写了四年的书 -
yangsong158:
看来,我与这个时代有些脱节了。必需加快赶上来。谢谢你的奉献。必 ...
无知者无畏,一本写了四年的书 -
黄粱一梦11:
目标 人没有目标就很容易迷失自己,常常陷入困惑中
PM成长日记第二话-一定要想清楚自己要什么 -
fenian_zhq:
支持。就凭你这个感悟,必须买一本收藏!
无知者无畏,一本写了四年的书
我们从一个最简单的登录例子开始。
最开始我们需要验证在用户名和密码都正确的情况下,能够正常登录系统,我们这样编写测试代码(以下都是伪代码,使用TestNG和Selenium):
@Test def should_login_success_with_exist_username_and_correct_password(){ LoginPage page = user.open(LoginPage,"/login.html") user.perform("login",['user1','1234'],on(page)) assert page.successLogin }
恩,很不错,运行一下,出现红条。为什么呢?原来测试数据库里没有用户名为user1的用户,好吧,写个数据库数据初始化脚本。再运行,OK,绿条!
那么,接下来我们再增加一个测试,需要覆盖密码错误时不能登录系统的情况,很快测试就完成了:
@Test def should_login_success_with_exist_username_and_incorrect_password(){ LoginPage page = user.open(LoginPage,"/login.html") user.perform("login",['user1','4321'],on(page)) assert page.successLogin,false }
再运行一下测试,绿条。好啦,现在可以看下这段代码,恩,有些重复,重构一下:
@Test def should_login_success_with_exist_username_and_correct_password(){ assert login('user1','1234') } @Test def should_login_success_with_exist_username_and_incorrect_password(){ assert login('user1','4321'),false } def login(username,password){ LoginPage page = user.open(LoginPage,"/login.html") user.perform("login",[username,password],on(page)) return page.successLogin }
重构完成,可以看到,我们的测试方法里现在没有了任何行为,仅仅是数据!这样让我感觉有点怪,不管了,先用TestNG提供的@dataProvider整理一下:
@Test(dataProvider="testdata") def testLogin(username,password,expected){ LoginPage page = user.open(LoginPage,"/login.html") user.perform("login",[username,password],on(page)) assert page.successLogin,expected } @DataProvider(name="testdata") def Object[][] dataForLogin(){ def data=new Object[2][] data[0]=['user1','1234',true] as Object[] data[1]=['user1','4321',false] as Object[] }
测试方法只剩下了一个!如果要测试不存在的用户不能登录系统呢?很简单,增加数据即可!
@DataProvider(name="testdata") def Object[][] dataForLogin(){ def data=new Object[2][] data[0]=['user1','1234',true] as Object[] data[1]=['user1','4321',false] as Object[] data[1]=['inexistuser','1234',false] as Object[] }
在我们的测试方法里,测试数据和测试的行为进行了完全的分离。从系统的功能来说,功能一旦实现,那么就是一个黑盒,我们只要提供数据即可进行测试,这个数据包括两部分:输入和期待的输出。我开始暗自嘀咕:难道我以前那么多的洋洋得意测试方法很多都是不需要的吗?这些方式为什么会存在呢?恩,想起来了,这些方法是为了覆盖功能的各个路径的,是提高测试覆盖率的。那么为什么会产生这么多的测试方法呢?哦,在这些测试方法里,测试数据和测试行为是耦合在一起的!
我伸了个懒腰,突然想,这下好了,我已经封装好了功能行为,QA想增加测试用例只需要自己增加数据就可以了,嘿嘿,爽啊。说曹操,QA到。QA mm说,你的某个功能实现有问题。我瞅了一眼,说,不可能啊(这是dev面对bug的第一反应),俺有测试的,持续集成一直是绿条的。QA mm说,在你的开发环境下测试是没有问题的,但是在QA环境,因为数据库变了,数据变了,应用服务器变了,所以会有些问题。我极不情愿的登录到QA环境,一测试,还真是,郁闷。
怎么办?修复完BUG,第一反应就是自动化测试能不能跑在QA环境呢?一般情况下,这些测试需要干净的测试环境,我们会制造很多的测试数据,可是在QA环境下,QA有她自己的测试数据,这些数据都不存在了哈。恩,看看刚才的测试代码,哈,就用QA的数据也可以啊,心情愉悦的改下:
@DataProvider(name="testdata") def Object[][] dataForLogin(){ def data=new Object[2][] data[0]=['hrong','1234',true] as Object[] data[1]=['hrong','4321',false] as Object[] data[1]=['rhao','1234',false] as Object[] }
OK,完成!为了该测试既能在开发测试环境运行又能在QA环境下运行,我们可以引入一个环境变量,将测试数据扔到文件里,通过环境变量来加载不同的测试数据(测试文件)。
好吧,喝点东西(甲流很厉害,喝板蓝根好了),总结一下:
数据驱动测试:测试数据与测试行为分离,通过数据来驱动测试。
好处:在对测试行为封装好的情况下,QA mm能够自己通过数据修改自动化测试;
自动化测试能够运行在多个环境下(开发环境、QA环境、产品环境);
测试的可读性;
测试方法大量压缩
适用范围:功能测试(selenium测试)
通过环境准备测试数据(非测试用例自己准备数据)
可能存在的问题:比一般的测试编写困难,特别是在静态语言里
最后:该文章的思考来自于徐昊在团队内部的相应Session.
评论
我先说说我怎么测试的吧!
我将一个登陆页面的所有情况使用XML文件进行编写。然后使用dom4j进行解析XML。将XML的中的每个数据通过Selenium进行测试。基本上可以将登陆的所有想到的情况都测试。但是我就是不知道怎么将这些一个单独的功能测试进行整合成一个业务流的方式进行有序的测试。!
给出我的一些代码
以下这个是一个登陆数据及其验证结果
<loginPage> <user sid="001"> <login>admin</login> <password>123</password> <validateCode>1</validateCode> <result>true</result> <ResultSuccessMessage>Successfully</ResultSuccessMessage> <ResultFailMessage>Fail</ResultFailMessage> </user> <user sid="002"> <login>abc</login> <password>123</password> <validateCode>1</validateCode> <result>false</result> <ResultSuccessMessage>Successfully</ResultSuccessMessage> <ResultFailMessage>Fail</ResultFailMessage> </user> <user sid="003"> <login>dd</login> <password>123456</password> <validateCode>1</validateCode> <result>false</result> <ResultSuccessMessage>Successfully</ResultSuccessMessage> <ResultFailMessage>Fail</ResultFailMessage> </user> <user sid="004"> <login>def</login> <password>123456</password> <validateCode>1</validateCode> <result>false</result> <ResultSuccessMessage>Successfully</ResultSuccessMessage> <ResultFailMessage>Fail</ResultFailMessage> </user> <user sid="005"> <login>jian</login> <password>1236</password> <validateCode>1</validateCode> <result>false</result> <ResultSuccessMessage>Successfully</ResultSuccessMessage> <ResultFailMessage>Fail</ResultFailMessage> </user> <user sid="006"> <login>dddddc</login> <password>1234536</password> <validateCode>1233a</validateCode> <result>false</result> <ResultSuccessMessage>Successfully</ResultSuccessMessage> <ResultFailMessage>Fail</ResultFailMessage> </user> ........ </loginPage>
类似的将这样列出想到的所有情况!
在使用dom4j进行解析出来。调用Selenium进行页面填充。
ps:我觉得适用范围可以是功能测试(如selenium测试)和集成测试(如JUnit写出的集成测试)
更进一步的我想象的可能场景是,前者由QA mm来维护测试数据文件,后者由开发人员来维护测试数据文件。
我的看法和你一致,使用范围应该是功能测试和集成测试,不包括单元测试。
恩 表示同意 。单元测试都是开发人员测
data[0]=['hrong','1234',true] as Object[] data[1]=['hrong','4321',false] as Object[] data[1]=['rhao','1234',false] as Object[]
有点担心的是,如果输入和输出比较复杂时,QA mm能看懂吗?
之前一个项目有一个比较大JUnit集成测试,也是类似以上的写法,
维护时发觉比较痛苦(主要是data[][]不够直观,修改输入输出时比较麻烦)
客户提出改进意见(他们也会跑这个JUnit),希望能用excel来描述输入输出,这样他自己就能追加case了
修改后发现果然更好用了
代价是:读excel比读data[][]烦
ps:我觉得适用范围可以是功能测试(如selenium测试)和集成测试(如JUnit写出的集成测试)
更进一步的我想象的可能场景是,前者由QA mm来维护测试数据文件,后者由开发人员来维护测试数据文件。
我的看法和你一致,使用范围应该是功能测试和集成测试,不包括单元测试。
首先声明一下,本人的数据驱动测试经验并不多,但是个人认为所有的测试数据都需要由环境准备。
我的数据驱动测试经验也很少。虽然还不清楚你说的测试数据由环境准备什么意思,但我想知道是否遇到过这样的问题:
如果每个dev准备自己的测试环境,创建db纪录,会不会在集成的时候造成db的冲突,比如这个简单和极端的情况,你用于fail的用户名/密码,却被另一个dev当作能成功登陆的用户对待。如果发现类似的问题,应该怎么解决?
是这样,环境准备的意思是在测试开始之前所有测试数据已经准备完毕,测试代码里不准备数据。环境准备可以是一段在测试开始前的脚本也可以是一个程序,它的目的是清理测试环境并准备数据。
既然是环境准备数据,那么显然这些脚本和程序也是要放入版本管理中的,这样就避免冲突。
ps:我觉得适用范围可以是功能测试(如selenium测试)和集成测试(如JUnit写出的集成测试)
更进一步的我想象的可能场景是,前者由QA mm来维护测试数据文件,后者由开发人员来维护测试数据文件。
集成测试下倒没有研究过,主要涉及到测试环境是否存在多人共用情况,如果不存在此种情,倒是可以在集成测试脚本启动前加载进行测试数据环境加载。
首先声明一下,本人的数据驱动测试经验并不多,但是个人认为所有的测试数据都需要由环境准备。
我的数据驱动测试经验也很少。虽然还不清楚你说的测试数据由环境准备什么意思,但我想知道是否遇到过这样的问题:
如果每个dev准备自己的测试环境,创建db纪录,会不会在集成的时候造成db的冲突,比如这个简单和极端的情况,你用于fail的用户名/密码,却被另一个dev当作能成功登陆的用户对待。如果发现类似的问题,应该怎么解决?
首先声明一下,本人的数据驱动测试经验并不多,但是个人认为所有的测试数据都需要由环境准备。
发表评论
-
Zookeeper与paxos算法
2012-03-22 20:36 16687一、 zookeeper是什么 ... -
关于异常的问与答
2010-09-16 22:34 1112今天的问题是关于异常 ... -
一家公司发展的胡言乱语
2010-01-16 23:06 2805终于一天早上,睁开极 ... -
《Head First Process-深入浅出流程》连载预告
2009-10-17 22:58 6139似乎一到年末,就会忙 ... -
也说炮轰
2009-10-05 13:13 1911社区里目前最火的无疑 ... -
使用selenium测试showModalDialog模态对话框
2009-07-27 21:10 7010Selenium目前没有提供对IE模态对话框(即通过showM ... -
(Multi-stage Continuous Integration)多阶段持续集成
2009-05-26 23:08 1219一、目前的情况 目前我 ... -
JbpmSide 流程设计器进度
2009-03-26 22:15 4400汇报一下设计器当前进度以及下一阶段主要的开发目标。 当前进度主 ... -
jBPM-side流程设计器功能规划
2009-03-08 21:57 2212目标: jBPM-side ProcessDesigne ... -
Flex框架Riawave应用以及对AJAX开发框架的思考
2009-03-01 22:05 1177Jbpmside要使用Flex开发流 ... -
你服务,你全家才服务
2009-02-19 14:18 1642在拥挤的公交车上读完《工作流管理(模型、方法和系统)》,自从搬 ... -
工作流技术基础读后
2009-02-09 18:03 1645大概花了三天的时间读完这本书,书本身也 ... -
BPM向左,工作流向右(二)工作流系统杂谈
2008-11-07 11:28 2290当 面对一个完整的工作流系统时,你可能会被它众多的功能所困惑: ... -
基于memcached的SNA实现
2008-10-28 17:34 3665系统要集群,使用SNA方案。一、 缓存的处理缓存要使用统一的缓 ... -
SNA方案之session炒冷饭
2008-09-04 14:49 2046SNA方案中,session的处理是一个重要方面。原帖见这里: ... -
一次性能调优的实战
2008-09-01 12:56 1889项目情况:是一个大型 ... -
BPM向左,工作流向右(一)什么是业务流程
2008-08-26 17:43 2379从事工作流以及相关开 ... -
js组件的测试,是个问题
2008-08-11 19:06 1064用js编写自己的组件,测试一直是个头疼的问题。最开始大量使用a ... -
工作流之收回
2008-07-15 18:31 1560收回 收回是工作 ... -
从贫血到充血Domain Model
2008-07-03 12:01 1688关于Domain Model的讨论已经非常多了,炒炒冷饭,这里 ...
相关推荐
介绍如何进行数据驱动测试 测试脚本的开发和维护是自动化测试的重要环节,适当地调整和增强测试脚本,能提高测试脚本的灵活性,增加测试覆盖面,以及提高应对测试对象变更的能力。数据驱动方式的测试脚本开发是解决...
高级数据驱动测试高级数据驱动测试高级数据驱动测试高级数据驱动测试高级数据驱动测试高级数据驱动测试
Test automation can be thought of as "writing software to test other software”. Using one of the commercially available automated testing tools, test scripts are written that drive the application ...
让你知道黑盒测试,是你的首先,如果你想要知道黑盒测试法
本文来自于testerhome,文章介绍了如何搭建基于SeleniumWebDriver的数据驱动测试框架的相关内容。在自动化测试框架中,数据驱动的意思指定的是测试用例或者说测试套件是由外部数据集合来驱动的框架。这里说的数据集...
此文档讲述了利用QTP进行数据驱动测试是怎么实现的。
webdriver 数据驱动 webdriver 数据驱动webdriver 数据驱动webdriver 数据驱动webdriver 数据驱动webdriver 数据驱动
提出采用面向自动化测试的测试用例设计格式,通过QTP的编程功能,使用外部数据源来实现较复杂的数据驱动测试。具体方法是采用Excel作为测试数据源,制定Excel中测试数据的设计格式,建立专用的函数库来操作Excel数据...
黑盒测试方法揭密,黑盒测试又被称为功能测试、数据驱动测试或基于规格说明的测试,实际上是站在最终用户的立场上,检验输入输出信息及系统性能指标是否符合规格说明书中有关功能需求及性能需求的规定。
机械手数据驱动器DataDriver是用于Robot Framework的数据驱动测试库。 本文档说明了如何使用DataDriver库侦听器。 有关安装,支持等的信息,请访问有关机器人框架的更多信息,请参见 。 DataDriver用作/导入为库,但...
test-nginx, 面向 Nginx C 模块和 OpenResty Lua库开发的数据驱动测试 电子邮件名称Test::Nginx - Nginx MODULE 和 Nginx/openresty库和应用程序的数据驱动测试脚手架 table-内容NAME描述用户指南使用 Test::Nginx ...
sazerac一个JavaScript数据驱动单元测试
本文来自于简书,本文章主要详细介绍了如何通过存储输入数据和结果的是Excel文件,在JMeter中实现数据驱动测试,希望对您的学习有帮助。DataDrivenTesting(DDT)即数据驱动测试,是一种用于创建自动化测试的方法,...
在测试接口时,一个接口会先写好...采用数据驱动方式,把数据写在excel表格中,代码做封装,用数据驱动测试,两部分相互独立。python中用ddt模块来做数据驱动,代码简单好维护,调试也方便。 自己写的框架,结构如下:
所谓数据驱动测试,简单的理解为数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。通过使用数据驱动测试的方法,可以在需要验证多组数据测试场景中,使用外部数据源实现对输入输出与期望值的参数化,...
火龙果软件工程技术中心 本文内容包括:1.RFT与数据驱动测试2.实例分析——数据驱动测试3.RFT默认支持的迭代器——顺序迭代访问和随机迭代访问4.选择合适的数据池访问方式5.结束语参考资料对数据驱动测试的支持是...
为了解决单元测试工具Nunit本身不支持数据驱动测试的问题,提出了在Nunit框架下实现数据驱动测试的方法。该方法首先将测试类所使用的测试数据基本信息设定在ini文件中,将输入数据及预期结果存放于Excel文件中。随后...
数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!...ddt库包含一组类和方法用于实现数据驱动测试。可以将测试中的变量进行参数化。 可以通过python自带的pip命令进行下载并安装:pip install