The "good use case, bad use case" of automated testing

Abstract:  The importance of automated testing is obvious, but automated testing cannot solve all problems, so it is impossible to completely rely on automation, but it is absolutely impossible to have no automation at all. In software development projects, heavy reliance on manpower for continuous regression is a very tedious repetitive task. Enterprises need to spend a lot of time and money to maintain such a team to ensure product quality, and the students in the team cannot grow at all and have no direction under the repeated work every day.

Although automated tests cannot solve all problems, they do have one advantage: "Once" Written, Run Anytime as Desired (once written, it can be repeated at will). Therefore, automated testing is usually used in conjunction with continuous integration systems (such as Jenkins), just like "Beautiful Days" and "Moonlight Cups" are the ultimate. This way we can avoid being mired in software problems at the last minute when the software goes live or is delivered. Of course, this is also the key to agile development. To eliminate problems in the process, just keep focusing on incremental content. In addition, in continuous integration, you can determine the trigger frequency and time of automated tests according to your own needs, such as "code submission", "timed trigger" and so on.

All things have yin and yang, automated testing has so many advantages, of course it also has its disadvantages. Therefore, there are still many companies with a low level of automation. We analyze these disadvantages, mainly in the following aspects:
  1. The requirements for testers are relatively high.
  2. Test cases need to be updated iteratively according to the version, and there is a certain maintenance cost.
  3. The test results are not necessarily reliable, and the test cases are also divided into "good" and "bad".

The first two points are also well-known issues, and each company has its own judgment on the situation, so I won’t go into details today. Today I mainly discuss the third question, that is: how to ensure that the automated tests we spend time and energy on are effective and can reflect the quality of the code under test?

First, test cases are also divided into good and bad

  
For the title, you may have questions, test cases are also good or bad? It is true that there are good and bad test cases, so what is a bad use case? What is a good use case? Let's start with the characteristics of the test case:

自动化测试或者测试用例的根本目的就是judge(判断)被测系统是否有问题,是以衡量被测产品的“标尺”存在的。所以,它具备一个重要的特征:在测试脚本和被测代码都保持不变的情况下,测试结果应该是稳定的、不变的。

根据这个原则,“坏用例”并不是指测试不通过的用例,更不是测试通过的用例,而是指那些在相同条件下,偶尔通过、偶尔不通过的测试用例。反之,“好用例”则是表现稳定的用例。
  
为什么说“坏用例”破坏性大?因为如果用例本身不具备稳定的结果输出,就无法准确的衡量被测产品是代码的问题还是用例本身的问题。如果每次测试结果都不能直接说明问题,需要进行反复分析,将直接导致大家对测试用例失去信心。也就是说,测试同学和开发同学会把测试用例的不通过,当成“Warning”而非“Error”,这样的最终效果就是自动化测试慢慢被抛弃。

二、测试用例的生命周期

有了“好用例”、“坏用例”的区分,测试用例就是“鲜活”的了。事实上,我们也可以规划处一个测试用例从生到死的生命周期。

image

一般情况下,我们可以以测试用例通过率或通过次数来为其划分“好/坏”。随着执行次数的增多,测试用例可以切换“好/坏”状态,当“坏用例”持续一段时间之后,我们可以把它标记为“垃圾用例”,并从自动化执行的序列中剔除。“坏用例”和“垃圾用例”可以被开发或者测试同学修复,然后进入“未知状态”。“未知状态”中的应用随着执行次数的增加,不断的在这个生命周期里循环往复。
 

三、 如何消灭坏用例

至此,我们明白了测试用例的“好/坏”之分,也了解了测试用例的生命周期。
那么,我们如何保证用例质量,“消灭坏用例”呢?

1,通过“CI”(Continuous Integration持续集成)发现“坏用例”

“坏用例”指的是偶尔不通过、偶尔通过的用例。所以,你会发现在本地运行的时候很难发现“坏用例”,因为“坏用例”需要被执行很多次才能被检测出来。执行很多次的过程可以非常好地通过CI系统来帮助实现,所以,如果你还没有使用CI系统,也依然建议使用持续集成工具进行多次的执行用例,即便你的工程量很小。另外一点,CI系统可以在一天不同的时刻执行用例,而时间也是一个“坏用例”产生的可能属性。

当然,成熟的CI系统(比如Jenkins)都可以满足绝大部分人的业务需求

2,防微杜渐

可能大家都听过“破窗理论”:当房子上的一扇窗户的玻璃被打破,如果不及时修复,将会有破坏者破坏更多的窗户。“坏用例”现象也是一样的,当出现一个“坏用例”时,如果不抓紧修复,整个测试用例集甚至自动化测试结果的可信度都将快速下滑。
  
对“坏用例”采取零容忍的态度,有助于整体自动化水平和质量的提升。可以建立测试或开发人员“坏用例”档案,并自动追踪每一个“坏用例”的来源,督促负责人跟进解决。

3,避免执行环境差异

4,使用异步等待  

通常,一个测试用例多个测试步骤组合而成,每一个测试步骤都需要特定的执行时间,所以,大家写测试用例一般的做法就是等待特定的时长,比如5秒。但是相同的测试步骤在每次用例执行过程中的时长并不相同,并且有时差异还会很大。这往往会导致上一步还未完成,下一步就开始执行,导致“坏用例”的产生。  
另外,即便是步骤执行没有超时,但依然可能造成时间上的浪费,比如一个步骤等待5s,但实际执行只用了2s,就有3s的时间浪费。  
理论上,解决这个问题有两种方式:回调、轮询。回调是指,上一步执行完成后,通知执行测试用例的进程/线程继续下一步。但这种方式在实际中并不采用,因为它需要紧耦合被测系统,可能为被测系统带来新的问题和维护成本。所以,实际中,更多的采用的是以“观察者”身份存在的轮询。比如说,以很小的时间间隔来不断查询是否到达下一步执行的状态。这样就能够避免一定程度的“坏用例”的产生。

5,解决并行执行的问题  

如果测试用例存在并行执行的情况,请确保多个测试用例之间不会因为相互对被测系统的影响导致冲突,从而使用例变成“坏用例”。比如,在所有测试用例执行过程中,数据库相关操作都采取事务的方式,用例执行完成后,就立即进行回滚。

6,避免测试用例互相依赖  

如果一个用例集中的测试用例时相互依赖的,那如果其中有一个“坏用例”出现,将会导致整个用例集不稳定。所以,尽量保证用例集中的每一个用例没有相互依赖关系,每一个都可以独立执行验证。

7,避免测试脚本太长  

毫无疑问,一个测试用例的步骤越多,可能变成“坏用例”的概率越高,所以,一般情况下,一个App的测试用例不超过在30步最好。

8,提高测试用例代码水平  

一个“好用例”除了结果足够稳定之外,还需要具备良好的结构设计,以及良好的可读性、可维护性。这一点对测试用例编写人员要求较高,当然,通过多读、多思、多写,能够很快的提高自己的自动化用例编写能力。

四、 MQC让测试用例“转”起来  

“坏用例”的产生跟被测应用、编写方法、测试环境等,都有非常大的关系,很难找到一个“all in one”的解决方案。但是,只要我们认真分析解决就可以让所有测试用例达到都是“好用例”这个状态。接下来,需要做的就是大家共同维护好这样一个最佳状态,避免“破窗理论”的发生。
  
在解决“坏用例”这个问题上,阿里云测MQC提出并实施了众多有效方案,例如,对于未通过的用例,增加N次重跑,避免“坏用例”的产生;比如“在线录制”可以帮助用户短时间内获得稳定性和兼容性都很高的测试用例;比如“用例管理”可以跟踪所有测试用例的通过率及通过次数,及早发现和处置“坏用例”;再比如,阿里云测MQC还提供了“Jenkins插件,让大家无需关心硬件资源等问题,方便大家将MQC云上的服务添加到自己的持续集成流程中来,真正做到“Once Written, Run Anytime”。这也是为什么只有在MQC平台上,测试用例才能真正“流转”起来。

原文链接:https://yq.aliyun.com/articles/152070?spm=5176.8091938.0.0.Zz5zDk

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326375482&siteId=291194637