自动化测试 如何做好软件系统自动化测试

admin · December 31, 2020 · 86 hits

测试分类

系统级测试一般指对交付的系统进行端到端的测试,验证系统是否满足所有功能和非功能需求。

一般而言,系统测试是整个测试实践最重要的,但也是成本最大的测试。为了让系统测试能够有效并且低成本,我们先来看看系统测试在整个测试象限中的位置和分类。

如上在敏捷测试四象限,将所有测试实践分为四大类。上图中横轴从支持团队变化到评价产品,纵轴从面向技术变化到面向业务。

  • Q1:面向技术和支持团队;这一象限中主要包含单元测试和组件测试。该象限中的测试帮助团队获得代码级别的快速反馈,一般借助 xUnit 测试框架,要求完全自动化。
  • O2:面向业务和支持团队;这一象限中包含功能测试,原型测试和仿真测试等。该象限中的测试大多也可以自动化,但是需要借助面向领域专门的测试工具。一般是否自动化,取决于是否有低成本的系统级别自动化功能测试工具。
  • Q3:面向业务和评价产品;这一象限中包含探索性测试、可用性测试等等。探索性测试指靠测试人员的主观发挥去探索系统潜在的故障,该象限中其它的则测试偏重于客户主观感受,所以以手工测试为主。
  • Q4:面向技术和评价产品;该象限一般包括非功能测试,例如性能测试、压力测试等。非功能测试一般需要依靠专门的测试工具,能否自动化取决于性能工具天生是否对自动化有效的支持。

从上面的分类可见,系统级别测试包含上图中的 Q2、Q3、Q4 象限中的所有测试。还可以将系统级别测试按如下维度划分:

测试类型

  • 功能测试:对系统功能进行验收的测试,包括用户验收测试、探索测试、A/B 测试等;主要分布在 Q2、Q3 象限。
  • 性能测试:指非功能性测试,包含性能测试、压力测试等;主要分布在 Q4 象限。

测试方式

  • 自动化测试:包含 Q2 中容易自动化的功能测试,以及 Q4 中测试工具支持自动化运行的非功能性测试部分。
  • 手工测试:主要针对 Q3 中的探索性测试,以及以客户主观感受进行对比和验收的测试用例。

测试策略

经过了前面对系统级测试的分类,我们看到有些测试是必须手动测试的,这些测试是自动化测试替代不了的。

对于可以进行自动化的测试,我们需要利用自动化的优势来降低测试成本,加快反馈周期。

对于一些依靠专有工具进行测试的,我们期望可以改造工具,逐渐将其自动化。

如下我们按照功能测试和非功能测试的分类,分别谈一下其中可以实施自动化部分的测试策略。

功能测试

功能测试原则上需要针对系统要完成的功能点逐一进行遍历测试,一般我们称其为验收测试。当代码发生修改,功能验收测试需要做回归,以确保修改的代码没有破坏系统功能。

由于功能验收测试需要频繁的运行和回归,所以这类测试需要尽快通过自动化来降低测试成本。取代人工回归测试的自动化测试可以释放人力,让测试人员把主要精力放在非机械性的需要创造性的探索性测试上。

由于越偏向业务,测试的独特性就越强,所以自动化功能测试工具一般需要自行开发。

好的消息是对于功能测试来说,测试用例编写、调度、报表生成的部分基本是通用的,所以可以找到不少开源的功能测试框架。但是这类测试框架一般不面向任何领域,只是完成通用的功能并且为扩展留好了接口,由使用者根据自己的领域对工具进行扩展。

常用的功能验收测试框架有 Cucumber 和 Robot Framework。这两款工具对比如下:

Cucumber Robot Framework
功能 • 使用自然语言,更易读
• 支持表格参数
• 支持多种格式的
• 支持多种语言
• 支持四种状态的测试步骤:Passed、Failed、Skipped、Pending
• 支持使用变形器消除重复
• 使用关键字的机制,更容易上手
• 提供了 RIDE,对于不熟悉编码的人来说比较友好
• 能够精细的控制关键字的 scope
• Log 和 Report 非常好
• 使用变量文件的机制来描述不同的环境
• 丰富的关键字库
• 内置变量
扩展语言 ruby python、java
不足 用例风格单一,只支持 BDD 风格 没有 cucumber 轻量
Jenkins 支持 支持 支持
开发效率 可集成 IDE 开发,效率高 可集成 IDE 开发,效率高
社区支持 广泛 广泛

如上,两款常用的功能验收测试框架使用都很广泛。Robot Framework 相比较重量一些,但是支持的扩展方式多,而且测试用例风格不局限于 BDD(行为驱动测试)风格,对传统测试人员比较友好。而大量的新的 web 应用开发者则更钟情于 Cucumber,具体需要根据自己项目的实际情况进行选择。

无论是选择上述哪种测试框架,针对领域进行扩展是避免不了的。

如上图,从测试框架到被测系统之间,需要使用者去编写测试支撑库。这些支撑库和使用者的测试具体特征有关。例如对需要通过收发消息来测试的系统,就要根据消息协议开发具体的测试支撑库,以支持访问被测系统。对于常用的功能,都可以直接找到别人开发好的测试支撑库。例如 Robot Framework 就已经自带了常用的 telnet,ssh,xml 等库,而使用者特殊的产品功能一般都需要自行开发支撑库。

另外为了让测试用例容易编写可读性强,还需要编写支撑测试用例编写的库。框架在这方面会提供一些基本的支撑机制。例如 Robot Framework 支持关键字驱动的测试用例编写,框架已经提供了常用的关键字,但是和使用者领域相关的关键字还需要自行开发。

如上可见,系统级别的自动化功能测试是需要花一些精力的。但是以作者的经验,一旦在这方面取得突破,整个组织的敏捷性会提高一大步,这些付出还是值得的。

非功能测试

通过前面的介绍我们看到,非功能测试一般是需要借助专门的工具进行。例如性能测试,一般需要由专门的工具来制造负荷和压力。对于成熟常见的领域,一般可以找到免费的工具使用。例如对于互联网 web 服务器的性能和压力测试,可以找到一些免费工具。而对于专门的领域,则很难找到免费的工具,大多需要自行开发或者购买专门的仪表进行测试。

如果购买专门的性能测试工具的话,对自动化的支撑只能看工具本身的能力了。但是通过封装也能把一些测试过程自动化掉,但是由于专有工具的使用成本,一般自动化的意义未必很大。

对于性能测试,除去对系统做端到端的测试外,对代码级别进行 profiling(性能打点统计)也是有价值的。一般出现性能问题后,需要找到代码的性能瓶颈进行代码修改,这时如果直接有数据指出哪里是可能的性能瓶颈,可以有效的指导代码修改。

代码级别的 profile 工具开源免费的比较多,例如 Gprof 和 Valgrind 都能对代码做精确到语句的性能分析。但是这两款工具都需要在运行时对代码进行打点,所以如果能结合自动化的 xUnit 测试框架来编写供 profiling 用的测试用例,那么可以有效的加快反馈速度,降低成本。

作者曾经为某企业开发过一款性能 CI 工具,在开发人员提交代码的时候由持续集成工具触发对代码进行 profiling,一旦出现性能异常恶化,则阻止代码入库并通知开发人员进行分析。该工具可以防患于未然,尽早地让开发人员去关注性能。

其它

自动化测试不能取代人工测试,事实上两种测试的定位是不同的。自动化测试是为了回归,而人工测试是为了探索。一旦探索测试中的一部分开始变得常规化,则可以将其编写成自动化测试用例后续自动执行回归,而让测试人员重新投入更有创造性的测试工作。

另外,自动化的系统测试也不能取代自动化的单元测试。从前面的四象限可以看到,系统测试是帮助产品的,而单元测试为了帮助开发团队的,两者的定位和价值方向不同。

借用下图说明一个健康的测试用例分布模式:

健康的测试用例分布应该如同上面的金字塔,由顶部少量的手工测试和系统测试,中间适度的集成测试和底层大量的单元测试用例组成。测试金字塔越往上更接近真实业务,但是成本越大也越慢,反馈周期长。金字塔越往下越靠近技术,远离业务,但是好处是运行速度块成本低,可以加快反馈速度。所以如果能够搭配如上图,在整体上可以获得很好的成本收益比。

推荐材料

「软件匠艺社区」旨在传播匠艺精神,通过分享好的「工作方式」,让帮助程序员更加快乐高效地编程!

No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.