51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2904|回复: 0
打印 上一主题 下一主题

[转贴] 敏捷自动化测试(1)—— 我们的测试为什么不够敏捷?

[复制链接]
  • TA的每日心情
    无聊
    昨天 09:06
  • 签到天数: 530 天

    连续签到: 2 天

    [LV.9]测试副司令

    跳转到指定楼层
    1#
    发表于 2019-1-8 16:47:39 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
    本帖最后由 测试积点老人 于 2019-1-8 16:49 编辑

    测试是为了保证软件的质量,敏捷测试关键是保证可以持续、及时的对软件质量情况进行全面的反馈。由于在敏捷开发过程中每个迭代都会增加功能、修复缺陷或重构代码,所以在完成当前迭代新增特性测试工作的同时,还要通过回归测试来保证历史功能不受影响。为此我们期望:


    测试范围足够广:

    • 测试用例要覆盖所有功能;
    • 要在各种可能的环境下作兼容性测试;
    • 系统的稳定性、性能都要测试;

    测试频率足够高:

    • 每日构建产生的版本要保证可用;
    • 每个迭代都需要对历史功能做回归测试;
    • 释放前或上线后如果打了补丁,就需要回归;

    但实际情况往往不遂人愿:

    实际测试周期变短:

    • 上线时间提前确定,研发进度延期,测试计划被迫延后;
    • 最后阶段经常会临时增加测试任务;
    • 所有人都知道还需要再经过一轮测试,但时间没有了;

    有效测试资源稀缺:

    • 临时从其他项目抽调的测试人员不能立刻有效的开展测试工作;
    • “搞不清楚”本项目的研发人员到底是不会做测试还是不愿做测试;

    因此由于客观上的资源和时间限制,完整的、及时回归测试在人工测试情况下,往往是不可能完成的任务。团队内部也会产生各种争执:

    • 提交给测试的版本为什么研发人员不先做通过性测试?
    • 这次代码改动量不大,有必要再花那么多时间回归么?
    • 当初不是承诺这次修改肯定不会影响以前的功能么?
    • 怎么不早说要支持Chrome浏览器,现在哪还有时间测试啊?
    • 怎么能让现场出现这种低级的Bug,打补丁后为什么不仔细回归一遍?

    争执越演越烈,最终有团队成员爆发了:“这简直不是人干的活!”。


    您怎么看待这句话呢?

    其实话糙理不糙,用更理性的语言翻译一下就是“有些工作不应该以人工的方式来完成”,比如:

    • 大量机械的、重复性的回归测试;
    • 结果的正确性不依赖主观判断的测试;
    • 需要模拟大量数据、大量并发量的测试;
    • 需要不间断执行的测试(比如7*24小时持续执行);
    • 需要短时间内完成的大量测试用例执行(比如完整的功能回归测试);

    通过自动化测试可以极大的提升回归测试、稳定性测试以及兼容性测试的工作效率,在保障产品质量和持续构建等方面起到举足轻重的作用。特别是在敏捷开发模式下,自动化测试是必不可少的。

    目前业界的商业/开源自动化测试工具有很多,比如,功能测试工具有QTP、Selenium等,性能测试有LoadRunner、JMeter等。其工作原理无非都是通过“测试脚本”和“测试数据”来完成“测试过程”,并比较“测试结果”,进而形成“测试报告”。


    本文不对这些测试工具的差异或优劣进行对比,只以作者目前采用的Selenium为例进行分析:敏捷开发模式需要自动化测试,但自动化测试本身的敏捷性又如何呢?

    Selenium是针对Web应用的开源自动化测试工具,通过编写模拟用户操作的脚本,它会打开浏览器对Web应用进行黑盒测试。可以方便的用于功能测试、兼容性测试、 稳定性测试及并发测试。目前已被主流浏览器厂商广泛支持,同时也是很多其它自动化测试工具(比如,RobotFramework)的底层核心技术。Selenium由IDE、Remote Control(简称RC)、WebDriver、Grid四个工程组成:


    • Selenium IDE

    是一个用于录制/回放测试脚本的Firefox附加组件,录制的脚本可以生成基于Selenium RC的测试代码(Java、Ruby、C#等)。适用于快速入门,不太适用于实际较大的测试项目;


    • Selenium RC

    RC由Server和Client组成两部分组成,Server负责加载/关闭浏览器以及作为HTTP代理来访问Web应用,Clinet支持多种编程语言和测试框架(TestNG、JUnit、NUnit等)。


    • Selenium WebDriver

    WebDriver作为Selenium2的核心特性提供比RC更简洁易用的API,是官方推荐的RC替代方案。可以更好的支持动态网页,不需要再额外启动一个独立的Server。


    • Selenium Grid

    是Selenium的一个扩展工具,可以很方便地同时在多台机器上和异构环境中并行运行多个RC或WebDriver用例。


    Selenium RC是通过在浏览器加载时“注入”JS函数来操纵后续的浏览器行为,Selenium WebDriver则通过直接调用各个浏览器内置的本地事件来达到这一目的。WebDriver目前已经作为W3C规范草案,提交由Google、Mozilla等浏览器厂商讨论。


    “WebDriver”顾名思义就是“Web浏览器驱动”,它专注于解决如何通过外部命令(通常为测试用例)操作浏览器的问题。至于测试用例按照什么顺序执行、执行过程中如何传递数据、测试结果如何断言、如何报告,则可以通过集成其它优秀的专业测试框架(比如,TestNG)来实现(WebDriver没有必要重复造轮子)。


    下面用以“用户管理”为例,来看看用WebDriver实现的“增加”和“删除”测试脚本(只示意部分关键代码)。


    1、在用户列表页面点击“新增”按钮,跳转到新增用户页面:

    1. webDriver.findElement(By.xpath("//a[contains(@id,'addUserBtn')]//button")).click();.
    复制代码

    脚本解读:

    • By.xpath()表示通过XPath来定位页面元素;
    • click()表示在找到的当前控件上执行点击操作;

    2、在新增用户页面,输入“帐号”、“密码”、“姓名”,选择“性别”、“生日”和“国籍”,然后点击“保存”按钮,回到用户列表页面,并判断是否增加成功:

    1. 1)  String account="autotest2";
    2. 2)  webDriver.findElement(By.xpath("//div[contains(@id,'account_userForm')]//input")).sendKeys(account);
    3. 3)  webDriver.findElement(By.xpath("//div[contains(@id,'password_userForm')]//input")).sendKeys("1");
    4. 4)  webDriver.findElement(By.xpath("//div[contains(@id,'name_userForm')]//input")).sendKeys(account);
    5. 5)  webDriver.findElement(By.xpath("//div[contains(@id,'sex_userForm')]//input")).click();
    6. 6)  webDriver.findElement(By.xpath("//span[text()='女']")).click();  
    7. 7)  webDriver.findElement(By.xpath("//div[contains(@id,'birthdate_userForm')]//input")).click();
    8. 8)  webDriver.findElement(By.xpath("//div[contains(@id,'nationality_userForm')]//input")).click();
    9. 9)  webDriver.findElement(By.xpath("//span[text()='中国']")).click();     
    10. 10) webDriver.findElement(By.xpath("//a[contains(@id,'userSaveBtn')]//button")).click();        
    11. 11) WebElement ele = webDriver.findElement(By.xpath("//div[text()='"+account+"']"));   
    12. 12) Assert.assertNotNull(ele);
    复制代码

    脚本解读:

    • sendKeys ()表示在找到的当前控件上输入字符;
    • 2~9行表示通过输入或点击选择的方式为用户相关属性赋值;
    • 第10行表示点击“保存”按钮(点击后会自动转向用户列表页面);
    • 11~12行表示查找页面上文本内容为新增帐号的div,并断言该div是存在的(不为空);

    3、删除刚刚增加的人员,然后判断是否删除成功:

    1. 1)  webDriver.findElement(By.xpath("//a[contains(@id,'deleteUserBtn')]//button")).click();
    2. 2)  WebElement ele = webDriver.findElement(By.xpath("//div[text()='"+account+"']"));
    3. 3)  Assert.assertNull(ele);
    复制代码

    脚本解读:

    • 第1行表示点击“删除”按钮;
    • 2~3行表示查找页面上文本内容为新增帐号的div,并断言该div已经不存在了(为空);

    通过上面的脚本就可以实现“用户增加、删除”的自动化测试,并且可以跨浏览器。看到这里您会不会觉得整体还不错,如果测试脚本再能通过录制的方式自动生成就更好了!

    “看”起来确实还不错,但在实际项目中用起来就没那么爽了。这其实是在技术/工具选型时普遍存在的现象:在验证/试用阶段的评价很高,但在投入生产使用时会遇到各种各样的问题,因此大家在选型阶段除了考虑功能,还要考虑技术/工具本身的开放性和可扩展性。

    上面的方案单纯从技术的角度来讲是很不错的:开源、社区活跃、标准化程度高、支持跨浏览器、脚本回放稳定、可集成性高,等等。


    但是如果就这样应用在实际项目中,会从过程的角度暴露一些棘手的问题:


    • 测试脚本是“代码级”的,那么应该由谁来编写呢?

    测试人员和开发人员好像都有编写这些测试脚本义务,但似乎又都有不写的理由。


    • 测试脚本必须不断的修改才能在最新版本上跑通,谁该为此买单?

    在敏捷开发过程中需要快速响应需求的变化(新增、变更),这一点整个团队都好理解。因此如果需求发生变化,开发人员修改代码、测试人员修改测试脚本,一切顺理成章,大家相安无事。但是在用户需求没有变化时,开发人员频繁修改代码的情况也很常见:比如,修改Bug、针对“坏味道”做重构、调整页面布局或样式。于是在“毫无征兆”的情况下,测试脚本又无法执行了!


    这时候测试人员可能会质问开发人员:“做之前怎么不想清楚?都已经测试完成的功能,为什么还总是反复修改?什么时候代码才能稳定?”。


    而开发人员此时也会非常理直气壮:“有Bug能不改么?页面布局不合理导致用户体验差,能不改么?而且敏捷中的一个重要的实践就是重构啊”。


    大家又是似乎都有道理、也都有苦衷。我虽然作为测试人员,但是在这个问题上还是“偏向于”开发人员的: 在软件生命周期的各个阶段(需求、设计、开发、测试)中,后面的阶段对前置阶段是有一定依赖的,所以越往后期响应变化的难度越大。比如,在“开发”环节不仅需要响应“需求”的变化(新增、变更),而且需要响应“设计”的变化。从这个角度来看,“测试”本就应该响应“开发”的变化。


    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏2
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-22 06:24 , Processed in 0.061013 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表