今天下午给同事就自动化验收测试做了一个简单的介绍,引起了大家的阵阵讨论。同时还有其他Team的人来分享各自的经验,他们也都做得相当不错。

  测试包括很多种,单元测试、集成测试、功能测试、验收测试、数据库测试等等。撇开大家都熟悉的单元测试、功能测试不谈,为什么这里要单独拿验收测试来说自动化呢?

  首先谈谈准备一次发布要做哪些事情。首先得验收这个迭代里面的所有Story,功能符合验收条件,没有bug。然后呢,需要对以往的所有迭代的Story都要进行回归测试,来验证这个迭代里面的修改没有破坏以前的功能。如果全部通过,或者核心功能工作完好,那么系统就能进行发布了。

  由此看来,测试人员的工作量相当大,验收Story+回归所有功能。如果在一个发布很频繁的互联网项目上,两周甚至一周一个发布,要是这些活全部手工做的话,测试人员就得累得吐血了。即使这样,血吐光了都不一定能测得完。测不完?所有人都来做测试,所有人都得吐血了。“人肉测试”不仅仅是很难完成任务,而且还有以下几个问题:

1. 重复劳动。这样一件事情,每次都得做一遍,烦不烦?

2. 人工测试精确度不高,容易出错。人不是机器,没有百分百的准确性,某个时候肚子饿了,或者听说股市大跌,精神一紧张,手一抖,就测不准了。

3. 浪费人力,物力和时间。一大堆人花大量时间来测试,测试完还得花时间写书面报告,成本增长的那个快。

  结论是人肉测试不行!能自动化的必须得自动化。因为有了自动化以后:

1. 系统质量得到保证。任何时候,只要测试通过,你就能勇敢的说:看!测试全过,功能肯定没问题。

2. 消除浪费。上面所提到的人力、物力和时间的浪费都能消除掉。

3. 加快了测试速度。人工测试需要两天的,自动化通常2个小时可以测完。累得吐血这种情况已经看不见了。而且自动化测试可以通过一系列的方法,比如使用更好的机器,将测试分布式运行等来加速。

4. 提高测试的效率和准确性。自动化测试是高效的,它一刻也不停的在运行。同时它也是准确的,程序代码帮你做验证,不会有任何偏差。

5. 勇气和反馈。开发人员有勇气去修改、维护或重构代码,有的时候即使单元测试通过,功能不一定正确。有双重保证的话,开发人员就有足够的勇气。项目所有人都有勇气说发布,不会像以前那样战战兢兢。

6. 可阅读的文档。验收测试的代码就是测试用例。看代码就是看用例,一步一步,清晰明确。不需要投入精力去维护一份测试用例文档,而且很有可能是过期不管用的。

  自动化测试,不管是XP、精益还是DSDM都把它放在最重要的地位。如果还处在人工测试阶段上的朋友,请自动化它们吧。

  如果写好测试,也是一门很高深的学问。不要认为写测试是测试人员的专利,不管白盒黑盒,写出漂亮的测试是开发人员的基本素质。先看看下面这个测试,以Watir+RSpec为例:

it “Scenario: create story with full information” do

@browser.open(…)

@browser.text_field(:id, ‘..’).set story_name

@browser.text_field(:id, ‘..’).set story_description

……

@browser.button(:id, ‘..’).click

@browser.div(:id, ‘..’).text.should contains(‘…’)

……

end

  这里描述了一个场景,用户填写一些字段,然后保存提交来创建一个用户故事。细看每一行代码,会发现看不懂!不知道每一行代码是在做什么。无法领会写测试人员的意图。

  这段代码最大的问题是其脆弱性。测试代码跟页面元素、结构紧紧耦合在一起,而UI元素是会经常被重构被改变的,一旦改变,很多测试用例就会失败,需要做出相应的修改。

  要想同时解决这两个问题,可以引入Page Model模式(相信ThoughtWorks的人都会用)。上面的代码便可以写成这样:

it “Scenario: create story with full information” do

create_story_page = @navigator.goto_add_story_page

create_story_page.add_story :name=>’…’, :description=>’…’

……

view_story_page = page.save_and_view

view_story_page.information.text.should contains(‘…’)

……

end

下面再来一个复杂点的测试用例

it “Scenario: import all the stories from excel file”

import_stories_page = @navigator.goto_import_stories_page

import_stories_page.import_from excel_path

preview_page = import_stories_page.preview_import

preview_page.choose_import_stories :all

preview_page.to_next_page

preview_page.choose_import_stories :first

story_list_page = preview_page.confirm_import

story_list_page.stories.should contains(‘imported story1’)

……

end

  看!代码是不是可读性很好,业务意图是不是很清晰。每一行代码都是一个业务操作,代表着测试用例的一个步骤,最后是一些断言,进行验收。断言也避免了assertEquals这种写法,采用RSpec的should来达到可读性最佳,最贴近人类语言的效果。如果你仔细看看这段代码,会发现它没有一点UI元素的操作在里面。UI再怎么重构,页面结构再怎么变化,测试用例代码都是稳定的。

  因为Page Object封装了UI元素和结构,使得测试代码稳定,达到要修改只修改一处的效果。同时,Page Object也封装了业务行为及操作,使得测试代码更可读。Page Model还有几个重要的概念,Driver, Navigator, DataFixture,其实都是封装了不同的变化点,这里也不多做介绍。

  验收测试的理想目标是全部自动化,测试代码即测试用例文档,易读易写。

 posted on 2009-09-30 00:29  紫色阴影  阅读(2627)  评论(9编辑  收藏  举报
我要啦免费统计