You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
13 KiB
Markdown

2 years ago
# 023KU法则如何找出最优自动化实施截面
你好,我是柳胜。
上一讲我们提出了自动化测试ROI模型在回归测试中的应用。回归测试是一个笼统的概念单元测试、接口测试以及UI测试里都有回归测试甚至性能测试也已经成为回归测试的一部分。
今天我们要关注一个具体场景给你一个软件系统作为自动化测试人员你怎么找出测试截面制定自动化测试方案这些事可能你都做过觉得并不稀奇但既然我们已经学习了ROI思维今天要再加上一个小目标**制定策略能够让这个自动化测试设计获得尽可能大的ROI**。换句话说,能干还不够,还要干得好,既要马儿跑,又要马儿少吃草。
有挑战不?那就跟我进入这一讲的学习,一起找到最佳策略吧。
## 测试ROI金字塔
在测试设计领域,经常提到的方法是分层。具体就是给定一个系统,结构上划分三个层级,单元在最小圈;服务包含多个单元,在中圈;而系统又包含多个服务,是外部的最大圈。结构图如下:
![图片](https://static001.geekbang.org/resource/image/77/c3/7713a7081ac2723a2cfc35d3277b21c3.jpg?wh=1920x1050 "软件结构圈图")
相应地我们的测试结构是在代码层做单元测试服务层做接口测试系统层做UI功能测试。
在实践中这三种测试该怎么组合安排呢迈克·科恩在2009年他的新书《敏捷成功之道》中首次提出了测试金字塔模型。单元测试自动化在金字塔底部接口测试自动化在中部而UI测试自动化在金字塔顶部。
![图片](https://static001.geekbang.org/resource/image/bd/68/bdyy34691cc7a36c8e50f13e3bbaca68.jpg?wh=1920x1050 "分层测试金字塔")
迈克·科恩讲到自动化测试工作量配比时认为应该按照层面积分配。也就是说单元测试案例的数目应该多于接口测试案例数目接口测试案例数目应该多于UI测试自动化测试案例数目。
后来,金字塔模型又被业界发展,赋予了不同的测试策略,比如自底向上执行速度减慢,自顶向下业务属性减弱,技术属性增强。
但迈克·科恩没有解释为什么各层工作量配比要按照测试金字塔分布按照软件结构图系统在最大圈测试案例应该最多而到了自动化测试金字塔UI自动化测试案例却最少单元测试在小圈测试案例应该最少但到了自动化测试金字塔单元测试案例却最多。
为什么是金字塔要是不去理解规律背后这个“为什么”你就用不好这个规律。上一讲我们知道了“ROI其实是自动化测试的隐式命脉”现在我们就利用ROI思维分析一下测试金字塔规律。
![图片](https://static001.geekbang.org/resource/image/cd/00/cd34280bc70b3633e696a7ba16f9e300.jpg?wh=1920x868 "ROI公式")
下面我们分别看看每层的ROI。单元测试可以在开发人员每次code commit触发运行回归频率高接口测试在每轮集成测试运行回归频率中UI自动化测试在用户验收测试回归频率低。
按照ROI模型我们可以得出3种类型自动化测试的ROI排序如下表
![](https://static001.geekbang.org/resource/image/71/08/713a743c26347d08d561d5a77ab27608.jpg?wh=3363x1379)
对照测试金字塔不难发现实际上三类自动化测试的ROI是自底向上由高到低的。
![图片](https://static001.geekbang.org/resource/image/7e/af/7ebe91f53e1fc7a84e53a26d68c4baaf.jpg?wh=1920x1050 "分层测试ROI金字塔")
按照第一讲得出的规律“自动化测试顺序从ROI高到低”我们优先投入精力做ROI最高的单元测试再做ROI中的接口测试最后完成UI测试。
现在就可以轻松解释迈克·科恩的金字塔了因为ROI存在差异所以按照高ROI大投入中ROI中投入低ROI小投入工作量比例呈金字塔分布底层面积最大顶层面积最小。发现没**根源在于ROI金字塔是表现出来的形态而已**。
好,到这里,总结一下。各种软件理论学派,大致可以分为两种,一种是理论基础,讲的是做什么,比如软件测试定义、软件过程,另外一种是实践经验,讲的是该怎么做,比如金字塔模型。
实践和理论很大的不同就是在现实商业中我们不可能完全按照理想来工作而是要加入很多制约因素其中最大的制约就是钱。明白这个道理你就会知道为什么ROI是根源你也会知道怎么能够在工作中做出业绩了不是耍两个工具忽悠一下领导就算成功而是认认真真地去思考踏踏实实地去提高ROI直到边际效应ROI无法提高为止。
## 寻找最优ROI策略
刚才说了分层测试和各层ROI业界也很认可这种分层理论但实际落地时却存在问题一批人做UI测试自动化另外一批人去做接口测试然后开发人员做单元测试。三路人马忙得不亦乐乎都说自己贡献大等到bug发生了泄漏到生产环境又开始甩锅。
### 分层测试为啥会“内卷”
很明显,这是一个内卷的场景,让我们结合例子具体看看内卷发生在哪里?
以一个Web登录操作为例用户在UI上输入用户名和密码点击“登录”按钮。Selenium UI 自动化会这样实现:
```plain
@Test
public void login() {
WebDriver driver=new ChromeDriver();
driver.manage().window().maximize();
//打开页面
driver.get("https://www.example.com/users/sign_in");
WebElement username=driver.findElement(By.id("user_email_Login"));
WebElement password=driver.findElement(By.id("user_password"));
WebElement login=driver.findElement(By.name("login"));
//输入用户名
username.sendKeys("liusheng@example.com");
//输入密码
password.sendKeys("123456");
//点击登录按钮
login.click();
}
```
上面UI的操作被Web服务转化成Rest请求进入到API网关是这样的
```plain
curl --location --request POST 'http://auth.example.com/auth/realms/Test/users' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'username=liusheng@example.com' \
--header 'password=123456'
```
在单元上执行的则是这样的代码:
```plain
public Future<ResponseData> login(String userName, String password) {
//入口参数检验
if (StringUtil.isBlank(userName)||StringUtil.isBlank(password)){
return new AsyncResult<>(ResponseData.error("账号密码不能为空"));
}
//查询用户是否存在
List<User> userList = baseMapper.getUserInfo(userName);
if (CollectionUtils.isEmpty(userList)){
return new AsyncResult<>(ResponseData.error("账号不存在"));
}
//验证账号密码是否正确
User user = userList.get(0);
String requestMd5 = SaltUtil.md5Encrypt(password, user.getSalt());
String dbMd5 = user.getPassword();
if (dbMd5 == null || !dbMd5.equalsIgnoreCase(requestMd5)) {
return new AsyncResult<>(ResponseData.error("账户密码不正确"));
}
//生成 access token并返回
String token = JwtTokenUtil.generateToken(user);
return new (ResponseData.success(token));
}
```
可以看到一个请求从浏览器页面发起进入API网关再传递到服务里的Login函数经过了UI测试、API测试和单元测试三个测试截面。
![图片](https://static001.geekbang.org/resource/image/0a/ce/0a1af39ca343083b14fe1472c5610cce.jpg?wh=1920x1045 "三个测试截面示意图")
三个测试截面测的是一个请求在不同层面上的形态那么每一个截面都可以测试全部的案例也可以测试部分的案例。就像3个人负责1个项目一样如果没有经过事先的协调和安排3个人可能做了重复的事情造成浪费也可能存在一件事3个人都没干形成测试盲区。
### 需求/策略矩阵
这种“内卷”是不是一个问题可能你会说没问题各层独立测试能够加强质量保障。说这话的底气在于测试上的投入充足不计内卷成本。实际上在DevOps风行的今天趋势是追求效果和效率。所以在资源有限的条件下我们需要在整体上看待分层测试的最优ROI。
咱们先看看测试需求是什么,用 [FURPS模型](https://zh.wikipedia.org/wiki/FURPS)来理一下需求。FURPS是用5个维度来描述一个软件的功能需求FURPS这个单词对应着每个需求的英文首字母
* F=Function 功能
* U=Usability 易用性
* R=Reliability 可靠性
* P=Performance 性能
* S=Supportability 可支持性
把测试需求和测试类型组合在一起,就整合了后面这个矩阵表格:
![](https://static001.geekbang.org/resource/image/44/21/443b6845a599a19d27704a3f89b44b21.jpg?wh=4000x1410 "3KU测试矩阵")
结合表格可以看到UI测试、接口测试和单元测试每个截面的测试能力。
* 在UI层面上功能性最强所有测试需求都可以做。这个可以理解因为软件本身就是满足用户需求没有一个需求不可以从用户层面感受到。如果真的存在一个需求用户却无法体验到那根据[奥卡姆剃须刀原理](https://zh.wikipedia.org/wiki/%E5%A5%A5%E5%8D%A1%E5%A7%86%E5%89%83%E5%88%80),这种用户无法体验到的需求就是无效的。
* 接口层面上,功能性减弱,技术性增强。
* 单元层面上,技术性最强,功能性主要体现在数据的处理,算法逻辑上。
### 3KU整体策略
好,有了需求/策略矩阵后结合上面讲到的自动化测试ROI金字塔我们的整体最优ROI策略就呼之欲出了。什么是整体最优ROI呢
有3个Key关键因素
* **U**seful: 每个测试需求都是有效的;
* **U**ltimate: 每个测试需求的验证都在优先寻找自动化ROI高的层面去实现如果不可行按照ROI高到低回退直到UI层
* **U**nique: 每个层面上验证的测试需求都和别的层面都不是重复的。
这样分配的工作既不重复又没遗漏还遵循了ROI的原则。我管它叫**3KU原则。**
![图片](https://static001.geekbang.org/resource/image/7e/af/7ebe91f53e1fc7a84e53a26d68c4baaf.jpg?wh=1920x1050 "3KU测试金字塔")
3KU策略该怎么执行呢?按照3KU策略我们把表格里的测试需求对照下面这三个问题按顺序检查一遍
1.能在单元测试验证么?
2.能在接口测试验证么?
3.能在UI测试验证么
这样检查以后,就能得出各个需求的自动化实现截面了。
UI测试关注功能场景测试易用性测试和可执行性测试而接口测试关注不同数据的循环接口的性能和错误恢复能力单元测试关注算法的正确性和性能。
恭喜你看到这里最后就是我们收割成果的环节了。我们又得出了一个满足3KU原则的自动化测试实施金字塔各层有自己的关注点又在整体上实现了互相配合补偿。
![图片](https://static001.geekbang.org/resource/image/95/a7/950bdb1892c70d0598cd0657e2ca92a7.jpg?wh=1920x1064 "3KU测试金字塔")
在3KU测试金字塔下每一个测试需求都会选择最大的ROI测试截面通过这样的安排实现了整体最优ROI的目标。对不对
## 小结
这一讲我们从ROI角度分析了一下分层测试的原理和在实践中的应用。先入为主地分层理论上的分层测试的特性必然会造成重叠和错失。这给测试从业者带来了挑战。但挑战也是机会如何解决这个问题
这就需要我们遵循回归到效益的原则思考怎么用最少的资源干最多的事能达到这个效果就是好的实践。因此我们提出了分层但协调实现整体最优ROI的解决方案3KU测试矩阵和3KU测试金字塔。
![](https://static001.geekbang.org/resource/image/44/21/443b6845a599a19d27704a3f89b44b21.jpg?wh=4000x1410 "3KU测试矩阵")
![图片](https://static001.geekbang.org/resource/image/95/a7/950bdb1892c70d0598cd0657e2ca92a7.jpg?wh=1920x1064 "3KU测试金字塔")
沿着这个思路,各层做好自己具有优势能力的测试需求,比起全部需求系于端到端的测试上,更有效率和效益,**分层是追求整体ROI的结果**。之后的课程里我们还会反复提到ROI最后你也会不由感叹ROI是背后无形的大手大道无形无处不在。
## 思考题
1 软件大师马丁·福勒曾经说过“在微服务时代分层测试不再呈现金字塔形状。”这是为什么试着用ROI来解释一下。
2 学完今天的内容,如果你是测试主管,你希望你的团队是全栈(一个人负责一个模块的所有层面测试),还是精细分工(一个人负责所有模块的一个层面测试)?有什么优劣?
欢迎你在留言区跟我交流互动,如果这一讲对你有启发,也推荐你分享给身边更多同事和朋友。