This commit is contained in:
Nathan Bu 2023-10-17 12:58:07 +08:00 коммит произвёл GitHub
Родитель c368700a72
Коммит 7fa3e1eb81
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
56 изменённых файлов: 1257 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,7 @@
# 第十五章 软件测试
软件测试是质量保障的核心手段,开发和测试很像软件研发的辩证对立统一两个方面,一个实现预期,一个验证预期,仿佛通过“竞争合作”的方式共同打造服务用户的软件产品。本章将聚焦于软件测试的内涵定义、目标、基本概念和应用实践,通过实际的工程问题帮助读者梳理软件测试的脉络,回答以下几个问题:
* 软件测试是什么?
* 测什么,谁来测,怎么测?
* 大公司是如何做软件测试的?

Просмотреть файл

@ -0,0 +1,81 @@
## 15.1 木头与软件测试的故事
转眼之间木头已来到自己职业生涯的第8个年头本月初有一位新同事小陈入职木头带领他一起完成了一次线上bug的排查。借由这次机会小陈很快地熟悉了项目中的相关feature定位到了代码中的问题并在木头的帮助下得出了解决方案需要改一行代码然后加两行日志收集的代码方面进行修复情况跟进。
### 15.1.1 一行代码引起的“惨案”
拿定主意新人小陈熟练的打开IDE写好并提交了代码就找到木头兴致勃勃地讲述了想法打算一气呵成地完成代码签入、热修复hotfix、部署和发布完成自己职业生涯的第一个“代码产品化”里程碑。木头见他热情可嘉回想起了自己初入职场的青葱岁月也没有直接泼冷水打趣说道
“好啊不过你这个里程碑肯定早晚会拿到你先别急着合入代码修改先针对这段改动丰富一下单元测试然后最好自己也多测几轮这样再上线比较稳妥。这个feature虽然是新feature不过生产环境目标用户数量也有好几万了。”
“这...需要吗一共就一行代码改动加了个if判断都是局部变量不可能出问题啊。”小陈一脸狐疑的说道。他心想自己以往LeetCode战无不胜写代码经常是一把过这次就这么简单的改动的话完全可以省去测试流程。
“哦,可是这里还加了日志输出,原来是没有这个调用的。”木头一边看着小陈的改动,一边说道。
```java
private void interceptRedirect(String redirectUrl){
...
traceLogger.infoWithArgs(String.format("Redirect URL: %s", redirectUrl));
...
}
```
```java
// 以下是示例infoWithArgs的底层实现并没有在本次修改中被小陈修改。
public class TraceLogger {
...
public void infoWithArgs(String message, Object... args){
...
info(String.format(message, args));
...
}
...
}
```
“对对,不过这个能出什么问题吗,日志模块的接口到处都在调用,我这里就是把变量的值打印出来而已。而且这个方法貌似已经有一个单元测试在覆盖了,你看这里。”
```java
public void testInterceptRedirect_NoException(String redirectUrl) {
...
interceptor.interceptRedirect("https://www.bing.com/search?q=software+testing");
...
}
```
聊到此处木头直觉事情没有那么简单“你调用日志的时候没有传入参数却调用了infoWithArgs这样会有问题吗”。
“我从上面直接复制粘贴过来的,应该没问题吧?单元测试是通过的。”
两人一起研究起了一下这段代码并对现有的单元测试进行了扩展提供了一些新的数据用例实战了一下结对编程。没想到两人很快发现在入参URL为某些特例包含%a、%b或%c的时候字符串格式化语句会出现异常 `MissingFormatArgumentException` 报错,导致整个业务流中断。而这个所谓的特例,在这个业务场景中和代码逻辑中频次很高,可能会导致线上数千用户的体验中断。
```java
@Test
public void testInterceptRedirect_NoException(String redirectUrl) {
...
interceptor.interceptRedirect("https://www.bing.com/search?q=software+testing");
// 新增的用例会在原有代码上触发 `MissingFormatArgumentException` 异常
interceptor.interceptRedirect("https://www.bing.com/search?q=%e5%be%ae%e8%bd%af%e4%b8%ad%e5%9b%bd");
...
}
```
小陈惊出一身冷汗自己心心念念的职业里程碑差点演变成大型翻车现场本来是打算修复一个线上问题没想到差点制造出新问题。这时的他再看木头不由觉得木头周身有一圈佛光是上天派来拯救他的。“看来一行代码改动也要仔细研究而测试是很好的代码问题的检验手段需要多下功夫研究研究。”小陈顿了顿然后激动地说“软件bug的代价太大宁可错杀不可放过。”小陈又燃了起来不过这次却让木头很是欣慰听的频频点头。
“哈哈你讲的挺逗确实如此bug能咱们自己发现修掉就不要让客户帮咱们体验。从某种程度上来说编程是对逻辑复杂性的管理。咱们的项目代码行数是百万级别的逻辑复杂情境和用例非常多每一处修改都有可能牵一发而动全身。全面的测试可以帮助我们在更早的阶段评估代码修改的影响。”
木头接着说“其实你不用后怕咱们的代码合入之后还会经过层层检测。代码合入主分支之后还会经过bvt测试、更全面的集成测试热修复上线之前还会经过验收测试、回归测试以及压力测试再部署到测试环境进行内部的自测。之后都没问题才可能发布到预生产环境、生产环境。所以你这个问题大概率能够在上到预生产之前被拦截下来。我估计集成测试都过不了哈哈。”
小陈挠头附和打个哈哈,心想,这些你不早说,原来还有这么一大堆测试。
又聊了几句,两人看时间不早了,就由小陈着手把代码修复完整后提交了,等待其他同事帮忙评审,就先下班了。
“还有一条规则,周五下午坚决不发版。下周见!”木头大手一挥,消失在大楼转角。
### 15.1.2 小陈的反思
今天发生的事情对小陈触动很大回家后他依然在思考为什么自己当时写代码时没有想到这个特例corner case木头说的“全面的测试”又如何理解其具体含义一方面他今天只接触了单元测试而木头还提到了其他很多种类的测试。另一方面测试团队似乎很重要可以帮忙发现很多问题而自己作为开发人员、代码修改的第一作者和“全面的测试”之间的关系是什么是否软件质量要依赖于测试团队的工作
最终,如果有了“全面的测试”,是不是软件质量就可以高枕无忧了?
带着这样一个又一个问题,小陈查了查资料,看到一句“测试是为发现错误而执行程序的过程”,还没来得及梳理出脉络,就感觉困意袭来,于是洗漱睡觉,结束了充实的一天。

Просмотреть файл

@ -0,0 +1,31 @@
## 15.2 故事分析-软件测试的复杂性
软件测试的重要性是和软件所服务的用户数量正相关的越是成熟的公司越是大型的软件就越需要完善测试层层把关。软件测试的复杂性会随着软件本身的复杂性的上升而上升。如果是简单明确的程序或者脚本自测验证即可而对于例如微软内部的Windows或者Office大型产品线测试的计划需要在产品设计阶段就介入在架构和组件层面要考虑软件的可测试性确保Testable并设计和逐步建立完善的、全方位的测试体系来保障问题尽早被发现Fail fast
尤其对于微软这样用户规模很大(亿级别)的公司来讲,任何一次“小的”软件质量事故,哪怕是只有万分之一的概率出现,也可能会影响成千上万的用户,破坏体验、口碑,甚至演变成为公关事件,影响公司声誉,造成巨大的商业损失。
<img src="img/Slide4.SVG"/>
### 15.2.1 软件测试的目标定位
既然如此,什么能为软件产品的上线、版本更新带来信心呢?测试这一活动,通过衡量实际情况与预期之间差距,正是增加对软件质量信心的关键活动。团队在上线前,看到一份“测试通过”的测试报告,自然会更放心一点。这是软件测试服务于质量保障的重要结合点。
<img src="img/Slide5.SVG"/>
不过,“增强信心”仅仅是软件测试的结果,而绝不是目的。从刚刚木头和小陈的故事当中,我们也可以体会到这点:因为代码有单元测试覆盖,所以会小陈会觉得自己的修改有保障,获得了“迷之自信”;但实际情况是,代码依然存在严重问题。而小陈后来反思的时候,看到了书上的"测试是为发现错误而执行程序的过程",也得到了一些启发。这些共同说明:
1. 开发人员的自测是有很大局限性的。
2. 仅靠测试是无法保障产出高质量软件。
3. 从心理学角度上讲,测试不应该是“自卖自夸”;而应该勇于质疑软件质量,“疑罪从有”,努力揭露软件问题。
### 15.2.2 测试的复杂性来源
故事中,小陈认为代码的修改量很小,并且是局部变量的改动,“问题不大”,忽视了所谓的“边界”情况。根据实践中的经验,软件开发中出现的问题往往不必和精巧的设计、核心的业务逻辑有必然联系,而更多出现在被疏忽的“边缘”环节上。而测试就是要发现软件错误和异常情况。
当今时代编程已经发生了更多的演化:我们有越来越多的类库、别人写好的方法可以调用,有越来越多的“轮子”、“巨人的肩膀”来加速功能实现。这就意味着,**一行代码可能暗藏着很深的调用栈和很长的调用链条**。木头作为资深的工程师,意识到即使是小的改动也可能引入问题,尤其是在复杂的软件系统、数据场景中。当软件足够复杂,所谓的“简单”的改动已经非常不可信,务必进行相应的测试,以避免潜在的问题。
木头作为经验丰富的同事,担任着指导和教育小陈的角色。他强调了测试的重要性,并解释了测试的流程和不同阶段的测试类型。在软件开发中,测试团队在保证软件质量方面的重要作用。然而质量并不是测试团队的“锅”,软件质量保障是整个团队的责任。
要做好测试,需要了解和运用一系列的测试知识和工具。木头也提到,不仅仅有单元测试,还有其他类型的测试,如集成测试、回归测试、压力测试等,并解释了这些测试环节在保证软件质量方面的作用:在不同层次和环境中验证软件的正确性和稳定性。
总的来说,软件测试发展至今,体系庞大、功能也很强大,但它不是万能的。它是确保软件质量的最为关键和最被依赖的环节。开发人员应该积极参与测试,并与测试团队合作,打造测试体系,诚实勇敢地去发现问题、重视问题、面对问题、评估问题和最终解决问题。

Просмотреть файл

@ -0,0 +1,113 @@
## 15.3 什么是软件测试
软件测试似乎并没有所谓的“权威”的定义,说法众多,比较常见的说法是,软件测试是一种实际输出与预期输出之间的验证和比较的过程。测试的意图是验证软件的行为,进而发现会导致系统失败的问题。结合前文,“测试是为发现错误而执行程序的过程”,我们提炼两个关于测试的重点:
- 测试过程体现了实际输出与预期输出间的比较。
- 要带着**质疑**的视角,“疑罪从有”,提供客观、独立的结论,暴露软件实施的风险。
在时间要求上,测试这个过程可以很简短,内部达成某个或某几个维度指标的验证即可;也可以持续到所有利益相关者都满意为止。
### 15.3.1 以问题为导向
问题是测试的最重要的产出之一谈及测试我们先全面的认识一下软件的“问题”。我们一般习惯称软件的问题为“Bug”不同语境下也可以用为“Defect缺陷”、“Exception异常”、“Fault错误”和“Issue问题”等代指他们分别强调了问题的不同方面或者不同部分。以下是一些由表及里的概念
| 概念 | 解读 |
| ------------------- | -------------------------------------------------- |
| Symptom 症状 | 问题的表征,如崩溃、严重的卡顿 |
| Issue 问题 | 一般是问题的表象的描述,代表了用户对这个问题的感知 |
| Defect 缺陷 | 可能指逻辑上的疏漏、不足之处和软件设计层面的问题 |
| Exception 异常 | 强调“和预期不符”,不一定是真的问题 |
| Fault/Error 错误 | 问题在程序层面的表现,如段错误 Segment Fault |
| Root Cause 根本原因 | 错误的根源,即导致代码错误的根本问题 |
从问题表象到根本原因之间的距离可长可短一个程序的崩溃、请求的失败一般首先反映在用户体验上开发团队可以将问题定位到一段出错的代码中然而一段代码的错误或异常可能是由其他代码导致的比如Out of memory内存溢出OOM问题往往报错的代码只是压倒骆驼的最后一根稻草问题的根本原因可能隐藏在整体的软件内存管理、资源利用效率和方式上。再发散一点一个软件问题的根本原因可能和软件的工程流程、发布流程、团队管理甚至企业文化都有些许联系。
微软内部的产品组会在临近上线前组织“Bug-bash”打虫子大会召集开发团队的所有人产品、开发、测试全都来对产品进行“Self-host”自用自测发现问题就报告出来。这样做有很多好处一方面鼓励大家多多用自己开发的软件增强主人翁精神另一方面团队发现问题和解决问题的人坐在一个屋子里、或者处在一个会议中缩短问题解决的周期效率很高。
一般用于描述一个问题的报告称为“Bug report”缺陷报告。它通常由以下几个主要部分组成以帮助开发团队定位和修复问题
1. 标题:
Bug Report的标题应简明扼要地概括问题使读者能够快速了解报告的主要内容。
2. 描述Description
描述部分详细说明了bug的情况包括以下内容
- 测试环境和准备工作:描述进行测试时所用的软件环境、硬件设备、配置等信息,以及为了测试而进行的准备工作。
- 测试步骤:清晰列出每一步所执行的操作和动作,包括输入的数据、点击的按钮、导航的路径等。
- 实际发生的结果:记录在执行测试步骤后实际观察到的结果,可能包括错误信息、异常行为、崩溃等现象。
- 应该发生的结果:根据规范和用户的期望,描述在特定情况下应该发生的预期结果。
3. 附加材料:
如果有必要Bug Report可以附带其他补充材料例如相关联的bug编号、输出文件、日志文件、调用堆栈的列表、截屏等。这些附件或链接有助于进一步的问题分析和复现。
4. 其他字段:
在Bug Report中还可以包含其他字段用于提供更多信息如严重程度Severity、功能区域等。这些字段有助于对问题进行分类、评估和优先级排序。
<img src="img/Slide6.SVG"/>
Bug Report是一个重要的工具它能够帮助测试团队和开发团队之间进行有效的沟通和合作以及保障软件质量的提升。编写清晰、准确的Bug Report有助于减少问题的误解和漏洞提高问题解决的效率和质量。
<img src="img/Slide7.SVG"/>
那么,测试是通过怎样的过程和方式把问题挖掘出来的呢?
### 15.3.2 测试的分类:测什么和怎么测
软件测试的被测对象被称为Software Under TestSUT。根据具体的测试目的和对被测对象的关注点的不同在测试什么内容就叫什么测试测试可以分为如下几类
1) 功能验证
- **功能测试**Function test测试软件系统的设计功能是否符合规格要求。
- **结构测试**Structure test白盒测试中对模块内部结构进行测试验证代码的逻辑正确性和覆盖率。
- **冒烟测试** Smoke test冒烟测试的目的是验证软件的核心功能是否正常以便快速发现关键问题和确保软件稳定性。它主要关注于系统的基本功能和主要路径Golden Path而不是详尽地测试每个细节和功能。
- **可用性测试**Usability test从使用的合理性和方便性等角度进行测试发现人为因素或使用上的问题。
- **配置测试**Configuration test测试软硬件系统平台对软件的支持和兼容性。
- **构建验证测试**Build Verification Test也被称为构建验证或基本验证测试。它被用于验证软件构建build的基本稳定性和可用性简称BVT。
- **回归测试**Regression Test对一个新的版本重新运行以往的测试用例看看新版本和已知的版本相比是否有“退化”regression
2) 性能验证
- **性能测试**Performance test验证系统是否满足规格中规定的性能要求如响应时间、吞吐量、处理精度、缓冲区大小、内存占用等。
- **负载测试**Load test用满负荷长时间测试系统的稳定性此时性能可以忽略
- **压力测试**Stress test验证系统在超负荷和异常环境下的运行能力和稳定性此时性能可以忽略
- **可靠性测试**Reliability test评估系统的平均失效时间MTBF和故障停机时间MTTR
3) 辅助测试
- **兼容性测试**Compatibility test测试不同版本间的兼容性尤其关注文件存储/读取的兼容性,包括向下兼容和交叉兼容。
- **安全测试**Security test验证系统的安全性确保系统对于潜在攻击的防护措施有效。
- **可访问性测试**Accessibility test验证系统对于聋哑人、盲人等特殊用户的易用性和无障碍访问性。
- **本地化/国际化测试**Localization test主要验证软件在不同地区和语言环境下的本地化和国际化适配性特别关注界面文字的正确性。
<img src="img/Slide8.SVG"/>
这些测试分类方式有助于测试团队根据不同的测试目标和需求,制定合适的测试策略和执行计划。此外,测试可以按照如下几个方面进行分类:
#### 1. 按照测试设计的方法分类
- **黑盒测试**通过观察系统的输入和输出以及对系统功能的期望行为进行测试不需要了解系统内部的实现细节。黑盒测试在设计的过程中把软件系统当作一个“黑箱”无法了解或使用系统的内部结构及知识。也可以说是“Behavioral Test Design”从软件的行为而不是内部结构出发来设计测试。
- **白盒测试**:基于对系统内部结构和代码的理解,设计测试用例来验证系统的逻辑正确性和代码覆盖率。在设计测试的过程中,设计者可以“看到”软件系统的内部结构。“白盒”并不是一个精确的说法,因为把盒子涂成白色,同样也看不见箱子里的东西;叫玻璃盒测试又有点奇怪。
- **灰盒测试**:结合黑盒测试和白盒测试的特点,既关注功能验证,又考虑系统内部的结构和实现。灰盒和白盒有同样的问题,其实这里的灰可以理解为“半透明”或者灰色地带的“灰”,表示可以一定程度的看清内部情况的“毛玻璃盒”;或者黑盒上挖了一个小洞,可以“偷窥”到内部的一部分。
<img src="img/Slide9.SVG"/>
黑盒测试更接近用户视角,可以作为整体系统测试的一部分,验证系统在各种使用情况下的功能和行为。白盒测试对测试人员的要求更高,有时需要侵入系统、进行访问和修改,但更接近代码层面,可以发现潜在的逻辑错误、边界条件问题和代码覆盖不足的情况。“灰盒测试”还不是一个很流行的说法,但是在实战中其实比较常见,比如结合逆向工程的测试,或者测试期间可以通过常规或非常规的手段,观察到运行时软件内存堆栈里的数值存储情况;这可能对测试人员的综合能力要求更高。下文讲到的穿透测试和这个概念很相关。
#### 2. 按照测试的实施方法分类
- **自动测试**:利用自动化工具和脚本执行测试,提高测试效率和一致性,适用于重复性较高的测试任务。
- **手动测试**:通过人工操作和观察进行测试,适用于需要人的主观判断和复杂交互的测试场景。
- **探索测试**Ad hoc Test or Exploratory Test探索性测试是一种以探索为导向的测试方法通过同时进行测试设计和执行测试人员可以自由地、发散地探索软件系统发现新的测试场景、缺陷和问题。这也是一种很有技术含量的测试技术微软还专门出过一本书就叫“探索式软件测试”。
- **穿透测试**Penetration Testing也简称为Pen Test或漏洞测试是一种安全评估方法旨在模拟真实攻击者的行为以发现和验证计算机系统、应用程序或网络中的安全漏洞和弱点。
测试并不一定要全部依赖于自动化测试也不一定自动化越多越好手动测试在某些情况下仍然具有必要性和重要性例如探索性测试Exploratory test这种兼具灵活性和创造性的测试方法在自动化测试中难以实现手动测试能够模拟真实用户的操作和交互更好地评估系统的用户体验在某些情况下系统的变动频繁或测试需求经常变化手动测试具有更高的灵活性和适应性能够快速调整测试策略和执行方式。
#### 3. 按照测试的范围分类
- **单元测试**:对软件的最小单元(如函数、方法)进行测试,验证其独立性和功能正确性。
- **集成测试**:测试不同模块之间的接口和交互,确保模块能够协同工作。
- **系统测试**:以整个系统为被测对象进行测试,验证系统在各方面的功能和性能。
- **验收测试**:由最终用户或客户进行的测试,以确认软件是否满足其需求和期望。
<img src="img/Slide10.SVG"/>
单元测试确保代码的正确性,集成测试验证模块间的协作,系统测试验证整个系统的功能和性能,而验收测试确认软件是否满足用户需求和准备进行部署,他们依次越来越接近用户视角,也依次越来越“黑盒”、远离代码。这些测试阶段一起构成了软件开发周期中的重要质量保证措施。
有时单元测试与集成测试的边界并不是很明确,我们可以这样理解:理想情况下,在单元测试中,被测试的单元应该与代码中的其他部分完全隔离。这种“纯粹”的单元测试方法意味着,被测试的单元在其自身边界之外访问的所有内容都需要用模拟对象或代理对象替代。然而,这种方法的缺点在于,模拟对象需要被维护,以确保其行为与实际实现同步。因此,单元测试通常也以被测试的单元可以访问其他单元的方式实施。如果测试明确针对不同单元之间的交互,那么它们就不再是单元测试,而是集成测试。实际上,集成测试通常也会使用与测试驱动程序相同的框架,并使用模拟对象来替代尚未实现或对测试无关的组件。

Просмотреть файл

@ -0,0 +1,125 @@
## 15.4 软件测试的设计和实施
前面的章节介绍了测试是什么和为什么测试,接下来我们将进一步探讨测试体系是如何设计和实施的。设计是软件开发中非常重要的一个环节,我们前面第六步中已经探讨过软件各个层次的设计:架构设计、概要设计和详细设计。而软件测试的设计,着眼于如何把软件中各个层面的问题找出来,并在开发的阶段中尽早地暴露问题。因此,在软件设计的阶段就应该引入软件测试的方案的设计探讨。测试方案的设计可以涵盖如下几个层次:
### 15.4.1 软件系统的可测试性
可测试性是指软件可以被完全有效测试的程度。在开发设计和实现的过程中,通常可以采用如下的思路来提高软件系统的可测试性:
1. 选择更加模块化和解耦的设计,引入设计模式。
2. 简化测试环境的搭建流程。
3. 启用依赖注入。
4. 选择简明且易封装的算法。
5. 定义清晰且易于测试的接口。
6. 使用测试“钩子hook仅仅为了测试方便而写的额外的功能
这些手段很多需要在架构设计、组件设计阶段就开始考量。因此一个最简单和普遍的提高可测试性办法就是让开发或测试人员在需求或设计评审中发出“灵魂拷问”“我们怎么来测试这个东西将开发可被测试软件的这个想法植入团队的大脑中。近年来随着软件测试在技术广度上的发展我们有了越来越多的开源工具和平台可以依赖似乎没有什么是真正不可测的了。测试数据可以批量生成软件电量消耗可以精确抓取微软的手机和电脑协同连接软件Phone Link测试过程中需要装有软件的手机和电脑进行同步协同操作二维码扫码配对也都通过软件模拟或硬件支持的手段解决了不仅可测而且可以自动化地测。
更进一步,可测试性不仅关乎测试本身和软件架构,更关乎从用户和商业角度出发的软件设计合理性,“如果一个功能都没办法测试(或很难测),这个功能真的有必要存在吗?”这个时候我们不妨问问,这个功能的边界、给用户带来的价值、触发条件、衡量成功与否的标准都定义清楚了吗?这些要点都关乎测试的**预期**或者说“Expected Outcome”。因此我们在产品设计阶段引入测试的讨论对于产品的成功也有很大意义。
### 15.4.2 整体的开发驱动模式
软件的开发首先应该是由外部的用户需求或商业需求主导的,所以高水平的测试人员需要理解软件功能的商业价值、设计的合理性,在测试的过程中帮助改善软件的设计。软件功能和需求的设计,和测试中要验证的“输出满足预期”,本质上是同源的,都是为了增加软件的质量、商业价值服务的。测试团队和产品团队本质上对于软件功能、质量有着相同的要求。换言之,当整个团队在需求理解和质量要求上高度协同一致的时候,测试也可以驱动开发。
测试驱动开发Test-Driven Development简称TDD是一种软件开发方法Development Approach它要求在编写实际代码之前先编写测试用例。开发人员通过先编写测试用例然后编写足够的代码以满足测试的需求。TDD实际在操作上逻辑很简单也是比较“符合直觉”的一种开发方式基本上就是在写测试、写代码、运行测试和重构代码之间不断迭代直到将程序的功能实现完整。在编码的过程中可能会用到“两顶帽子”类似的思维编码时切换思考角度在“测试功能”、“实现功能”和“重构代码”三种思考模式之间不断切换笔者觉得这非常有趣。
<img src="img/Slide11.SVG"/>
测试驱动开发有助于实现更高的代码质量鼓励开发人员编写更模块化、可扩展和可维护的代码形成更好的代码设计提高代码的可读性、可维护性和可重用性同时TDD通过提供全面的测试覆盖和及时的反馈增强了团队对于产品的自信心此外测试用例作为明确的需求规范充当“可以运行的程序文档”也促进了团队成员之间的沟通和理解。可谓好处多多。
然而是否要在团队里采用或推广这种开发方法是一个实践层面的复杂问题。文化层面上TDD要求团队成员具备测试和质量意识重视产品架构和和维护性测试、开发、产品团队之间有较好的协同和紧密合作产品层面上需要产品需求和功能定义清晰变动不宜过于频繁。因此TDD更适合具备一定规模的团队和长期稳定的项目。所以对于时间压力大、探索和创新型的项目以及更注重灵活快速的团队不能将TDD生搬硬套也没有必要强推一个成型团队转型TDD。这也许是国内互联网公司较少看到TDD实践的原因之一。当然这也和技术领导人的风格和企业文化主导思想有很大关系。
在微软工程师文化盛行所以有不少团队实打实的在用TDD笔者有幸和Microsoft Form产品研发经理聊天对方谈到TDD带来的好处和大家的热情眼睛里闪烁着兴奋光彩。在和一位阿里巴巴做保险业务开发的朋友聊天了解到因为产品涉及到支付、定损、保险精算和“真金白银”对整体代码测试覆盖率要求很高98%以上关键模块要求100%),测试团队和开发团队都要求会写代码、写测试、懂业务,与其被动的追赶覆盖率,不如直接采用测试驱动,边测边写。
总之测试驱动开发是一种经典的开发方法不必强求不妨一试。和测试驱动开发并列的开发驱动模式还包括行为驱动开发Behavior-Driven DevelopmentBDD和验收测试驱动开发Acceptance Test-Driven DevelopmentATDD其中ATDD将测试更加后置在交付用户之前或发布之前其重点是验收测试用例的设计这里限于篇幅不再过多赘述。重要的问题是在软件开发的实践中我们打算把测试放在什么地位重要性和环节时间点这个问题的答案会很大程度上决定软件的质量情况和测试工具、开发系统的采用。
### 15.4.3 测试的需求和目标
很少有人会问,为什么要做软件测试,这件事似乎在专业的软件团队里是与生俱来就要做的事情;但经常能听到团队的测试人员抱怨,“我们的产品研发团队根本就不重视测试”,“测试的地位低”等等声音。笔者认为这些“牢骚”其实往往是测试人员的妄自菲薄或者“有恨无人省”的委屈怨言。
测试的出发点应该从商业角度和用户角度的现实需求出发求真务实暴露问题让软件质量的真相浮出水面。比如一个软件产品要在中国上线那要符合遵循《中华人民共和国个人信息保护法》PIPL而一个软件系统内部的数据流处理是否违背了个保法的原则需要通过测试验证手段结合网络数据流监测或抓包工具像探针一样插入“黑盒”内进行测量才能知晓。在美国医疗仪器设备软件产品要遵循FDA美国食品药品监督管理局所指定的要求标准FDA对其下注册的软件产品的软件测试流程有非常严苛的要求会派审核人员去软件开发团队对测试流程进行督导和盘查确保软件实现了声称的规范水准。
以上提及的例子是典型的从实际出发的软件测试需求有着明确的目的和外部需求。“符合预期”可以是非常宽泛的提升软件的CMMI成熟度也可以是测试的一个出发点。在上一小节我们也提及了从目的出发的测试的分类方法可用性、可靠性到安全性、合规性可能会出现问题的角度都可以形成相应的测试需求对应到相应的测试方法。
### 15.4.4 测试技术方案选型
“Test Pass”测试通过是软件开发的一个重要的反馈信号或里程碑好的测试工具、系统或技术方案应该具备较高的稳定性环境部署方便运行过程和结果清晰简明等特点在保证测试结果有效性的基础上其应该能够帮助研发团队更快、更高效地达到Test Pass从而将产品开发推动到下一个阶段。此外在选择测试工具和技术方案时还可以考虑以下因素
- 技术栈和平台测试方案一般首先依赖于项目所使用的技术栈和平台。单元测试方面Java主流框架有`Junit`、`TestNG`、`Mockito`等C#有`MSTest`、`xUnit`、`nUnit`等Web UI测试可以用`Playwright`、`Selenium`;移动端跨平台方案`Appium`;云测试系统`Hydra Lab`Android端用`Espresso`iOS app使用`XCTest`。
- 测试需求和目标:测试的需求和目标对于测试方案的制定有很大的决定作用,确定要测试的功能、性能、安全性等方面的要求,以及所需的测试覆盖范围和深度。比如,安全性要求高的系统需要设计穿透测试,运用逆向工程、模拟黑客攻击来测试系统的“防御力”,而受众小、处于孵化器的项目则没有必要将问题复杂化。
- 团队技能和经验:优先根据团队成员的技能和经验,选定大家相对比较熟悉的测试工具和技术,确保能够有效地应用和支持所选方案。
- 开发环境和工作流程选择与现有环境和工作流程相协调的工具和技术以便实现无缝的集成和自动化。微软Azure DevOps平台有很高的灵活性支持多种主流平台、测试工具的集成。
- 可用资源和成本效益:评估可用的资源和预算,对照考虑工具和技术的成本效益,来确定是否有足够的资源来支持和维护所选的测试工具和技术,以及它们是否能够提供预期的价值和回报。
- 社区支持和生态系统:还可以综合考虑测试工具和技术的社区支持和生态系统,优先选择受欢迎、活跃的工具和技术,以便能够获得广泛的支持、文档和资源,并从社区的经验和最佳实践中受益。
开发团队可以综合考虑以上因素,结合项目的具体情况和需求,选择适合的测试工具和技术方案,来实现高效、可靠的测试和质量保证。
### 15.4.5 开发和测试团队的分工和流程
在传统的瀑布模式下,开发团队在完成开发后将软件交付给测试团队进行测试。开发团队负责设计、编码和集成,而测试团队负责执行测试用例、发现和报告缺陷。在这种模式下,开发和测试是连续的但分离的阶段。敏捷开发模式秉承“小步快跑”的理念,强调开发团队和测试团队之间的协作和整合。开发团队和测试团队一起参与每个迭代周期,共同制定需求、设计、编码、测试和验证,鼓励开发和测试团队在整个开发过程中密切合作。
一般而言,开发团队的需要负责:
- 设计和实现软件的架构、功能和特性。
- 编写高质量的代码,并进行单元测试。
- 解决开发过程中的技术问题和挑战。
- 提供必要的技术文档和支持。
而测试团队的责任包括:
- 制定测试策略、计划和测试用例。
- 执行各种测试(如单元测试、集成测试、系统测试、验收测试等)。
- 发现、报告和跟踪缺陷。
- 分析测试结果,提供质量评估和建议。
随着敏捷方法的兴起开发团队和测试团队之间的责任划分越来越模糊。其实根据上面的职责界定也可以看出各项职责之间都有着几乎高度重合或者密不可分的联系比如设计软件功能和设计测试用例实质都是在描述对软件的预期执行测试虽然是测试团队的主要工作开发自己写代码难道不需要自测吗有的经验丰富的开发就是通过灵活运用TDD或者测试工具、代码检测工具实现功能的阶段就把测试的活都干了代码Pull request里面还附上了简明的“测试报告”一般叫How this is tested 或者 How I test it导致测试阶段完全挑不出毛病来虽然一般约定是开发负责写单元测试而测试人员也可以帮忙改进或创建单元测试来提升覆盖、发现缺陷。
会写代码的测试在国内叫“测试开发工程师”薪资比一般的测试人员要高很多这类职位在阿里巴巴、京东这样的大厂招聘页面上很常见国外叫“Software Development Engineer in Test”简称SDET或者“Quality Assurance Engineer”简称QAE。测试开发在越来越多的“入侵”软件工程师的地盘也许随着AI和大语言模型技术LLM辅助编程的崛起个体能效的提升开发和测试之间的边界会越来越模糊最终融合在一起。
总而言之软件产品的开发和测试是紧密联系的是对同一个问题的两个不同关注侧面开发工程师和测试工程师作为重要部分共同构成了软件产品团队共同为产品的成败负责。如果简单的把开发看成“实现功能的”把测试看成“保证没bug的”认为只有测试为质量负责那么开发就有可能在写代码上放飞自我认为开发应该为所有线上bug背锅那么测试就会变得形式化走马观花形同虚设。
另外从时间这个维度或者测试流程设计上看测试和开发团队之间如何避免“互相等”的情况也和权责、合作模式、开发流程密切关联。低效的情况无非就是测试人员无版本可测或者开发人员写完代码但却发现没人能马上测试或者迟迟没有测试bug产出或报告结果导致发版延迟。这种情况一般需要贯彻敏捷开发“小步快跑”的理念将功能拆解让代码实现和测试用例设计可以并行开发和测试可以“错峰”和衔接同时也需要管理者洞察这种“空窗期”通过整个产品团队范围进行人员资源的优化调配来解决。
最后,文化上,开发团队和测试团队之间的合作应该是紧密的,彼此互相支持、协作和沟通,团队领导需要建立良性文化,出了问题要一起反省,剖析改进,避免陷入相互甩锅的无效争执;成功优质的上线也要对整个产品团队的所有贡献者一同感谢。要相向而行,实现共同的目标:交付高质量的软件,让用户满意。
### 15.4.6 测试用例的设计
测试用例Test Case之于测试工程师犹如程序代码之于开发人员。测试用例是测试工作产出的最重要的“工件”之一。一个软件测试用例可以包含以下核心元素
- 用例名称Name用例的唯一标识符或名称清楚地描述了被测试功能或场景。
- 测试目的Objective明确说明了测试用例的目标和意图即要测试的具体方面或功能。
- 预设条件/前提条件Preconditions列出执行测试用例之前必须满足的条件或环境设置。
- 测试数据Test Data指定用于执行测试的输入数据包括必要的参数、配置和初始状态。
- 测试步骤Test Steps详细描述了按照哪些顺序和方法执行测试用例包括操作和预期结果。
- 预期结果Expected Results明确说明每个测试步骤的预期输出或期望结果。
- 优先级Priority指定测试用例的优先级以帮助测试人员在测试计划中确定执行顺序。
测试用例设计方法和技巧是软件测试中非常重要的一部分。当我们把软件的内部逻辑看做为一个“黑盒”的时候,可以采用以下方法和技巧来设计测试用例:
1. 场景法Use Case Testing根据用户使用软件的场景来设计测试用例例如登录、注册、搜索等。这种从用户使用场景视角出发的用例设计其实是比较符合直觉和常用的设计方法。
2. 等价类划分法Equivalence Partitioning将输入值划分为有效和无效的等价类从每个等价类中选择一个或多个测试数据作为测试用例。通过将输入值划分为有效和无效的等价类可以减少测试用例的数量提高测试效率。
3. 边界值分析法Boundary Value Analysis测试输入数据的边界值包括最小值、最大值、中间值等。这种方法是对等价类划分的补充。
4. 错误推测法Error Guessing凭经验列举出程序中所有可能有的错误和容易发生错误的特殊情况设计相应的测试用例。
5. 因果图分析Decision Table Testing通过绘制因果图来梳理一个程序中的输入输出组合明确测试预期结果和前置条件进而设计测试用例。
6. 功能图分析State Transition Testing or Functional Graph Analysis通过绘制功能图、系统状态迁移图来帮助测试人员理清软件系统的功能结构、状态变化并基于功能图进行测试用例的设计和分析。功能图一般由状态迁移图和逻辑功能模型组成。一系列状态及其依赖的输入/输出数据满足的“条件对”组成测试用例。
<img src="img/Slide12.SVG"/>
这里限于篇幅我们不再对每一个用例设计方法展开叙述。笔者认为这些设计方法的核心价值在于从不同的角度为用例设计提供了思路而其最终目的是服务于测试覆盖的完善、质量控制最终落脚到用户价值。比如我们从用户场景出发可以创建出登录、下单、结账等各类测试基本用例通过因果分析来明确预期输入输出通过等价类分析来丰富用例内容进而再通过错误推断和边界分析来全面覆盖逻辑角落corner case这些方法可以非常好地组合起来帮助完善测试。但是一定要明确我们的最终目标产出不是因果图不是等效类而是经过有效用例验证后的高质量软件产品。此外很多时候我们从产品设计和需求文档层面出发就可以明确很多输入输出预期其中可能就暗含了因果图功能图的逻辑体系。测试和开发人员在借助这些分析工具之前全面的学习产品设计和需求文档可能比仅凭分析的纸上谈兵有更大的意义。
从测试用例的组织方式上看单个用例的范围可大可小但一般会聚焦在一个功能点上同一个模块的多个功能点所对应的用例可以组合成为一个测试用例集Test Suite往往可以覆盖到一个场景scenario或者服务于一个特定的目的如冒烟测试用例集。在Azure DevOps系统中提供了各层次的测试对象的定义Test Plan可以包含Test Suite和Test Case代表了一次具体的测试执行计划。这些测试对象可以在Azure DevOps上方便的进行管理、关联和重用从而提高测试效率。
<img src="img/Slide13.SVG"/>
### 15.4.7 谁来测:测试人员的职业素养
DevOps和敏捷开发理念的崛起和流行让测试人员和开发人员之间的权责边界变得模糊软件产品出了质量问题越来越多的是整个团队为之负责而不是简单地让测试人员“背锅”。这种模糊和融合也意味着对测试人员的要求更加综合。谁来测或者说测试人员的水平和心态都可以对测试执行成果产生很大的影响。软件测试团队的角色和责任包括设计可用性测试的测试场景分析测试结果并向开发团队提交报告创建测试设计、流程、用例和测试产品文档并按照设定的标准和流程进行测试。在笔者看来测试人员应该具备
1. 软件行业的商业意识。
2. 和用户换位思考的同理心。
3. 对于新技术的学习能力。
4. 对产品设计的基本理解。
5. 扎实的计算机和编程功底。
如果想走技术路线,测试人员可以深入学习软件开发知识,熟悉更多的测试工具,增加自己测试“探针”触及的深度,掌握自动测试、效能测试、穿透测试等。同时,也可以通过对产品和业务的理解,逐步拓宽自己的视野、提升思维,为产品交互逻辑发现和解决问题,创造价值;甚至逐步发展“老板思维”,展现自己的商业逻辑上的见解,成为测试管理者,为公司优化流程,实现利润最大化。
总之,测试人员不要妄自菲薄,假设“测试不受重视”,出于一些外界的成见给自己的能力和成长设限,从而错失发展良机。软件质量关乎着软件的成败和生命线,从质量出发,或者从团队能效、自动化出发,测试工作都大有可为。

Просмотреть файл

@ -0,0 +1,118 @@
## 15.5 软件测试在微软
微软是毫无疑问的软件行业巨头在全球有超过18万员工很多产品线活跃用户数都是亿级别或者十亿级别因此微软非常重视软件测试和软件质量保障其在测试领域的实战和发展历程也十分有参考意义和代表意义。
### 15.5.1 发展历程
如果想了解微软是如何进行软件测试的有一本书《微软的软件测试之道》How We Test Software at Microsoft是我们通过搜索引擎很容易定位到的。这是一本由前微软公司的测试专家Alan Page、Ken Johnston等于2008年合著、2009年翻译在国内出版的一本软件测试方面书籍。该书探讨了微软在软件测试领域的实践经验和方法并分享了他们在微软测试团队所采用的测试策略和技术。《微软的软件测试之道》是一本重要的软件测试指南对于想要了解和改进软件测试实践的人员来说具有很高的参考价值。然而这本书毕竟距现在“年代久远”软件行业发展迅速微软也在2010年后历经组织变革和业务战略调整。
实际上微软曾经设立过SDETSoftware Development Engineer in Test这一职位专门负责撰写测试代码、驱动工程自动化和建立质量控制系统但在2015至2018年期间微软进行了多次组织架构和角色调整逐步将SDET测试开发职位与SDE开发职位进行合并逐步取消了SDET这一个头衔。
因此为了促进更紧密的跨职能的团队合作如今的微软已不再设立专门的SDET职位而是将大部分测试工作融入到开发工程师的角色中。曾经在2008年微软测试和开发人员的占比几乎是1:1而今天“纯粹”的测试工作一般由外包人力承担。专职测试人员在人数上相对于开发的少了很多小于10%),主要负责手工测试、增量验证、探索测试等测试内容的执行,在微软内部仍然扮演着重要角色。
这当然不意味着微软不重视测试和质量方面的工作《微软的软件测试之道》一书的作者也在这些变革发生后表达了自己的看法这一变革突出了对于用户需求和团队成员技能多样性的重视通过融合提升团队敏捷性让软件工程师的技能更全面从而更灵活、更能适应变化。微软依然保留了Software Quality Engineering这一专业化分工人员占比小同时Quality也比Testing的责任范围更大"Software Quality Engineering",软件质量工程,是一个更广泛的领域,它涵盖了软件开发和测试过程中的质量保证、质量控制和质量改进等方面),负责确保软件的质量和稳定性。
<img src="img/Slide14.SVG"/>
这种“逆分工”的变化趋势并非微软独有Google和Facebook也在同一时期完成了类似的转变。这一变化一方面明确了开发团队应该同时负责和推动自动化测试的搭建提高效率并为质量负责另一方面也反映了软件开发流程和商业模式的演化。早期互联网基础设施并不发达的时候软件通过软盘、光盘等实体介质分发销售、拷贝所以软件分发、更新的灵活性都比较差软件如果无法在分布前充分测试导致遗漏严重的Bug、漏洞一起刻入发行版光盘中可能会造成非常难以处理的线上事故造成“覆水难收”的困局直接攸关软件的成败和生死。所以软件交付需要极高的计划性和严格的质量把控投入大量软件测试。
然而,随着互联网的迅速发展,以下几点变化,是这一融合的重要背景:
1. 软件分发基础设施的完善:软件产品、各类应用通过网络分发、“打补丁”的成本在逐步降低,且发布平台、分发渠道也变得越发完善。
2. 用户数据收集渠道的完善收集线上用户反馈和诊断数据的渠道越来越通畅和多元期初可能以邮件沟通为主用户使用软件遇到问题就通过邮件联系开发团队后来各种应用内问题反馈第三方的反馈平台、诊断数据平台、灰度测试平台、实验控制平台使得软件团队可以“分包”一部分测试给愿意承担更大风险、提前尝鲜的内测Alpha/Beta用户更早地以更小的代价发现软件问题并着手修复。
3. DevOps持续集成系统的完善CI/CD系统例如微软的Azure DevOps可以很容易地将各种类型的自动化测试嵌入到软件研发流程中成为整个工作流的一部分自动触发。
总之,这种趋势和整个软件工程基础设施的升级密不可分,同时也蕴含了对软件工程人才综合能力的更高要求。软件工程师团队需要应用各种手段、更强大的工程能力高效地交付高质量的产品。通过将测试技能融入开发过程中,微软希望工程师团队能够综合参与和统筹需求分析、流程架构设计和编码,更好地理解软件系统和功能,进而更好地设计测试和质量保障方案。此外,这种整合也寄希望于加强开发团队对自己开发的软件产品质量的责任感,加强团队协作。
> 咬文嚼字的讲“程序员”的主要活动应该是写产品代码“测试人员”则负责执行测试任务所有参与软件交付的人员都是“开发人员”。然而在一个敏捷团队中每一个成员都应关注于交付具有业务价值的高质量产品。软件开发工程师SDE应该跳出框架去思考着眼于整个产品和产品的生产流水线。
### 15.5.2 微软的测试实践
在上文中提到的团队整合的大背景下微软内部的软件测试实践在各个产品团队的工程师Software Development EngineerSDE们的主导下呈现出百花齐放的态势不同产品研发团队各自有自己的测试实践方案。因此很难说微软目前在测试上有一套统一标准的流程或者说有具体的最佳实践。处于不同成熟度阶段的产品、或不同的技术栈、前端或后端、不同的商业模式2B或2C采取的测试策略、模式和目标都不尽相同。不过微软各个团队在工程师主导、敏捷开发、持续集成等理念上具备共识基础也最大程度上在复用同一套基础设施在软件测试采用了很多共性的策略和方法以下是一些比较常见的实践。
#### 1. 持续集成和敏捷测试
微软绝大部分产品研发团队都在Azure DevOps或GitHub平台上进行开发、验证集成和发布。Azure DevOps简称ADO平台内置支持的敏捷开发方法可以方便地实现持续集成和持续交付流程。这意味着软件的功能和改进会定期地集成到主干代码中自动在代理机器Build Agent通常为连接至平台流水线的物理或虚拟机器上完成构建并自动化触发测试流程来进行验证。很多团队还会使用Azure DevOps中的测试计划功能来创建和管理测试计划Test Plan、测试套件Test Suite和测试用例Test Case。Azure Test Plans一般用于组织手动测试的信息和记录执行定制测试需求、跟踪测试进度和与其他团队分享测试用例也可用于自动化测试。
Azure DevOps中的“Pipeline”构建任务流水线是CI持续集成和CD持续部署的核心组织单元可以帮助团队串联开发构建任务实现测试的集成和自动执行。这点和Jenkins、Travis CI等持续集成系统很相似不过ADO的功能更丰富、更灵活易用。ADO和GitHub也可以无缝集成是一个综合性、完整度很高的DevOps开发系统几乎可以覆盖从软件计划到发版的全流程广泛地被微软各个团队采用
在代码提交或者创建Pull Request后Azure DevOps可以自动触发“Pipeline”运行我们可以在其中内嵌软件测试任务自动运行包括单元测试、集成测试和其他自动化测试。有了这样的平台之后我们可以灵活的选择在各个关键环节插入合适的测试流程来让代码改动可能引入的不同程度的问题适时暴露从而时刻“拱卫”软件质量。
> 这里有几个问题:一般有哪些关键环节?什么叫“合适”的测试流程?如何理解“不同程度的问题”?又何谓“适时”暴露?这是几个层层递进的问题,涉及到软件开发中质量、效率和成本之间的平衡,我们将在下一个章节“高效测试”深入探讨。
<img src="img/Slide15.SVG"/>
在一次常规的开发、发版流程中不考虑存在紧急热修复hotfix、A/B testing、或商务合作内测自动或手工测试可以介入验证的几个关键的时间点包括
1. 开发人员创建Pull request之前进行本地编译和测试验证。
2. 创建Pull request之后代码合入开发代码主干之前。
3. 代码合入主干之后,或主干上签入了新的改动之后。
4. 在主干分支进行定期测试验证,比如每小时一次或者每天两次。
5. 从开发主干签出发版节点之后。
6. 发版版本构建完成后,部署到内测环境之前。
7. 发版版本部署到内测环境之后,部署到生产环境之前。
8. 在生产环境发布之后,进行回归测试和持续监控。
至于具体如何选择时机,和执行什么程度的测试,可以考虑如下的原则:
1. 测试覆盖率:较早的测试时间点可以在问题进入主干前发现和解决,但由于频次高、效率成本高,无法覆盖所有功能和路径。较晚的测试时间点频次更低,可以进行更全面的测试,包括集成测试和端到端测试。
2. 问题修复成本:较早的测试时间点发现的问题修复成本较低,因为问题可能较小且影响范围有限。较晚的测试时间点发现的问题可能会很难排查、对整个产品计划造成较大的影响,修复成本更高。
3. 发布进度和风险:较早的测试时间点可以尽早发现问题并提前解决,有助于确保发布进度。较晚的测试时间点可以降低发布到生产环境中出现问题的风险。
4. 团队协作和沟通:早期的测试时间点需要开发人员和测试人员之间更密切的协作和沟通,确保及时修复问题。较晚的测试时间点可能需要更多的测试资源和时间,以进行全面的测试。
5. 整体质量控制:结合多个时间点的测试可以提高整体质量控制的效果。早期的测试时间点可以发现和解决明显的问题,较晚的测试时间点可以验证整体系统的稳定性和一致性。
综合考虑上述因素,微软研发团队里的常见的实践是把他们结合起来:早期的测试时间点(相对高频次)侧重于单元测试、集成测试和代码审查,以尽早发现和解决问题。较晚的测试时间点(相对低频次)侧重于系统测试、端到端测试和用户验收测试,以验证整体系统的质量和功能。这样可以兼顾质量控制的全面性和有效性。
通过提供全面的功能和集成Azure DevOps将敏捷测试流程“集约化”提高了协作效率。它支持手动和自动化测试团队可以利用Azure DevOps的各项功能来实现软件测试的自动化、跟踪、协作和报告。并帮助高效交付高质量的软件因而在微软内部广泛采用。
#### 2. 自动化测试
微软非常注重自动化测试由于专职的测试人员比例逐步降低且多通过外包团队执行有可能开发团队和外包团队不在同一个国度反向“倒逼”研发团队充分利用各种测试框架和工具来执行自动化测试来保证产品质量。自动化测试当然好处多多可以提高测试效率、减少人为错误。如上文提到微软的开发团队可以使用Azure DevOps中的自动化测试功能来运行和管理自动化测试用例。
奉行测试金字塔的原则研发团队实施自动化测试会针对不同层次、不同阶段地执行包括单元测试、集成测试、系统测试和用户界面测试等进行综合验证。Azure DevOps以下简称ADO平台的pipeline可以在物理机、虚拟机或基于云测试的代理容器上配置测试环境执行基于Selenium、Appium、NUnit、MSTest、playwright和Visual Studio Test Professional等各类测试任务。ADO通过插件平台“Visual Studio Marketplace”提供了广泛的第一方和第三方的各类Pipeline任务插件实现第三方测试工具和服务集成。Pipeline运行的代理Agent也支持灵活的配置、镜像复用为测试环境创建和管理资源、配置环境参数、部署应用程序和数据库等提供方便。通过ADO的内置的测试环境管理开发团队可以更好地控制和管理测试环境、配置测试环境变量和测试数据集以确保一致性和可重复性的测试和其在受控且可重复的环境中进行。
微软内部基于其在GitHub上的开源方案 Hydra Lab 搭建的内部云测试服务就实现了物理设备上云全球共享测试资源。Hydra Lab也提供了ADO插件在ADO平台上可以方便地为流水线集成测试定义和部署任务完成和持续集成系统的无缝兼容。除了测试运行本身的自动化之外利用Azure DevOps平台微软的开发工程师们还会力争在如下两个测试结束后的环节完成自动化
- [测试结果展现和分析自动化]构建流水线运行测试的自动化测试的结果将在任务结果页呈现为开发人员提供即时反馈。测试结果、覆盖率、缺陷趋势等关键指标可以通过Azure DevOps的仪表板和报表进行展示和共享。Azure DevOps还提供错误分析、趋势可视化等功能以深入方便开发团队了解的测试活动。
- [缺陷管理和跟踪自动化]Azure DevOps支持缺陷Bug和开发任务Work Item管理当测试结果出现问题的时候平台可以配置自动创建Bug开来捕获、跟踪测试中反映出的问题。测试人员或开发者可以将其与相关的测试用例和测试结果关联起来实现缺陷和相关测试之间的追溯。
关于自动化测试在微软的更多实践我们将在下一个章节“高效测试”进行更深入的探讨和案例呈现这里主要想给读者一个概要性的认知微软一直在依托平台建设和测试基础设施的完善来努力推进全流程的自动化并且已经取得显著成效。这也包括引入AI、LLM、图像识别等技术来使自动化测试进一步智能化。自动化测试可能短期无法完全替代手工测试Manual Test但未来的软件测试一定是想着更高效、更自动、更智能的方向发展的。
#### 3. 自测、内测和用户反馈
当一个公司的工测试人员来越少时我们可以通过测试“众包”的方法首先让开发团队、公司员工广泛的参与到软件产品自测活动当中“公司员工自己应该是自己产品的第一批小白鼠”其次建立内部测试用户Alpha/Beta用户群助我们试用和测试早期版本发现问题。内测用户群通常愿意更早的体验新功能。对风险有更高的接受度。这种方法相当于把内部的手工测试的力转嫁转移给了公司内部员工。内测用户的身上。只要我们能够建立有效的用户反馈渠道。收集他们在测试体验中的问题就可以很大程度上提高发现软件缺陷的效率。
在一个团队的集中于测试的资源变得越来越少的情况下,我们可以先采用内部"众包"的方法来解决测试验证软件质量的问题。这是提高测试效率的另一个思路:找到一群愿意“免费”承担风险、帮忙测试和验证产品新功能的群体。具体而言,这样的群体大概有这么几波人:
1. 开发团队本身;
2. 公司同事;
3. 该软件用户中的“发烧友”通常也叫Alpha/Beta用户。
微软内部一般一个完整的产品团队都能达到百人规模而全公司员工有近20万人。所以对于微软而言如果妥善经营第一波和第二波群体是庞大的而且公司内部同事之间的沟通渠道是非常顺畅的。我们可以建立一定的渠道和技术提升产品在公司内部的知名度让开发团队和公司员工们广泛参与到软件产品的自测活动中。从立场上讲每个产品开发成员都应该成为自己产品的第一批“小白鼠”此乃“分内之事”而公司内部的员工资源则是“近水楼台”可能也关心和乐意试用公司内部的其他产品可以进一步帮忙扩大测试的覆盖范围和深度。其次建立内部测试用户群包括Alpha/Beta用户他们将在早期版本中试用和测试软件并帮助我们发现潜在问题。这些内测用户通常对新功能有更高的兴趣和接受度他们愿意成为早期采用者并提供反馈。通过建立这样的用户群我们可以将一部分手工测试的工作转移到公司内部的员工身上他们将成为测试团队的延伸。
从本质上讲专业的黑盒测试、探索性测试都是在通过不同的视角验证产品这种“视角”本身蕴含着巨大的价值。开发人员对自己开发的产品、功能往往缺失“外部视角”。“众包”测试的妙处在于通过相对安全的“人海战术”提供了多样化的视角“多线程”地去探索软件的“逻辑黑盒”找到和暴露问题。同时也提升了产品和新功能在开发人员、公司同事、内测用户群范围内的知名度是一个一举多得的聪明的办法在微软内部非常常见。笔者在微软经常收到Microsoft Teams、Office等团队发来的内测邀请邮件发现有趣的产品就试一试如果正巧发现了问题就跑到Windows Feedback Hub或者内部的Yammer、Teams Channel上吼一声。
这种方法的关键前提是要建立一定的有效用户反馈渠道。通过收集内测用户在测试过程中的问题、诊断信息和建议我们可以更快地发现软件缺陷并着手修复。很多国内的互联网企业在推出新功能之前向长期维护的Alpha/Beta内测用户QQ群发出测试邀请并实时在群里沟通问题只要合规合法这种沟通渠道能带来意想不到的收益确保了新功能的稳定性和用户满意度。
当然,为了确保这种"众包"的有效性和高效性,还有一些技巧和注意事项需要考虑:
1. 提供清晰的测试指导:特别是针对开发团队自测的情况,有的时候测试需要一定的环境配置,为了确保测试参与者能够执行准确和一致的测试,明确定义被测试的软件产品功能、目标和范围,包括确定要测试的功能、预期的测试结果和所需的测试资源,提供清晰的测试指导可以帮助团队在真实的环境中进行测试。测试指导也可以包括如一定的测试用例、测试步骤和相应的预期结果等。
2. 注重用户体验和反馈:测试"众包"不仅仅是为了发现软件缺陷,也是为了提供更好的用户体验。因此,鼓励测试参与者从用户角度出发,关注软件的易用性、界面设计和功能完整性等方面。虚心收集用户各方面的反馈和建议,并视情况采纳为改进软件的重要依据,让反馈掷地有声,也是增进社区和自测团队的积极性的好办法。
3. 建立沟通和反馈渠道:建立一个开放和透明的沟通渠道,使测试参与者可以随时提问、报告问题或分享意见。这可以通过电子邮件、聊天工具、在线论坛或定期会议等方式实现。
4. 激励参与和奖励机制为了鼓励测试参与者积极参与测试活动可以考虑设立一定的激励和奖励机制。例如给予发现bug最多的同学“捉虫达人”的称号并提供一定的礼品测试参与者奖励或奖金或在公司内部设立测试竞赛和排名等。这将提高测试参与者的积极性和参与度。
在微软,测试内部“众包”活动一般被叫做"Bug Bash",在很多产品团队广泛采用。通过充分利用公司内部的资源和智慧,建立提供清晰的测试指导、大家实时沟通交流,激励参与和奖励测试参与者,加强了大家对内部产品的了解和团队间的联系,有的时候还会有“吐槽大会”的效果,十分有趣也很有意义。当然,测试"众包"并不能取代专业测试团队,而是一种补充和增强的方式。专业测试人员负责既定测试策略的制定执行、高级测试技术的应用和质量控制的监督。通过合理结合专业测试和内部众包测试,可以实现更全面、高效和质量的软件测试。
#### 4. 安全、无障碍和合规测试
微软作为一家体量巨大、服务众多个人和企业主体用户的软件服务提供商,保护用户隐私、数据安全,重视产品体验的无障碍,既是企业文化和道德的体现,也是商业责任的一部分,并在这些领域投入了大量的资源和实践。
1) 无障碍测试
为了让微软的软件产品和服务对于所有人群都更易用,微软遵循了 W3C (万维网联盟) 制定的 WCAG (网络内容无障碍指南),在全公司内提供了无障碍测试的基础设施、工具和流程机制,来确保产品在视觉、听觉和运动方面都能提供良好的用户体验。微软开发了 Accessibility Insights、Accessibility Developer Tools、Accessibility Testing Services等工具内部还会建立评价体系鼓励各个产品达到金牌标准。笔者的团队产品每次在评比中获得无障碍金牌评级都要为此小小的庆贺了一番。
2) 合规测试
微软软件开发中的合规Compliance一般包括安全和数据隐私保护两个方面首先要确保软件产品和服务符合各国家地区适用的数据隐私、儿童保护等相关法律、法规和行业标准比如 GDPR (通用数据保护条例)、PIPL等。可以说很多法律条款的要求也是对产品需求的直接要求可以转化为测试用例。比如PIPL要求“用户给予数据授权之前应用程序不应有任何网络通信行为”就提供里比较明确的软件行为预期形成测试用例。安全方面微软使用了一套名为 SDL (Security Development Lifecycle) 的流程并提供了内置在ADO持续集成系统的工具如静态代码分析、构建依赖扫描和资源如安全培训课程体系将软件安全的要求和检验渗透到软件开发的各个阶段需求分析、设计、实现、验证、发布和响应监控从而确保每个阶段都有相应的安全活动和最佳实践。从软件测试的角度看微软很多团队都会实施渗透测试、漏洞分析、网络扫描服务、安全审计等有的团队是内部通过自动化测试完成有的则聘请外部的专业公司完成。
通过这些实践,微软可以提供更安全、可访问、隐私保护和合规的产品和服务,面向全球用户提供专业的软件产品。
以上只是微软在软件测试方面的一些常见做法,实际上微软内部不同团队、不同产品有着多样化的确保产品的质量和用户体验的方法。下一章我们将讨论如何“高效测试”,将有机会进行更多探究。

Просмотреть файл

@ -0,0 +1,21 @@
### 思考与练习
1. 测试的角色Test需要独立出来么如果不需要会存在什么样的问题需要解决如果需要独立出来的测试角色怎么才能发挥作用有些成功的产品团队或软件公司认为独立的测试角色不需要存在你怎么看
2. 如何避免测试成为“走马观花”式的流程?从事测试工作的团队成员应该具备哪些职业意识和素养?
3. 软件测试的分类思路taxonomy是怎样的
4. 如何设计有效的测试用例?有哪些思考方法?什么样的用例是好的测试用例?
### 参考资料
[1] 《构建之法》,邹欣,人民邮电出版社
[2] 《微软的软件测试之道》, Alan Page / Ken Johnston / Bj Rollison著张奭 / 高博 / 欧琼 / 赵勇译,机械工业出版社
[3] 《致命Bug软件缺陷的灾难与启示》金钟河/叶蕾蕾,人民邮电出版社
[4] 《软件测试之困:测试工程化实践之路》,肖利琼,人民邮电出版社
[5] 《软件测试的艺术》张晓明译Glenford J. Myers著机械工业出版社
[6] 微软开源智能云测试平台Hydra LabGitHubhttps://github.com/microsoft/HydraLab
[6] 软件测试Wikipediahttps://en.wikipedia.org/wiki/Software_testing
[7] 软件测试基础Microsoft Learning https://learn.microsoft.com/en-us/shows/Software-Testing-Fundamentals/
[8] 微软合并测试职位的原因Linkedinhttps://www.linkedin.com/pulse/20140806183208-12100070-why-did-microsoft-lay-off-programmatic-testers/
特别鸣谢林刚、谢定坤、Kevin Huang、Weiwei Shi、方斌、万敏、杨威、李英霞等各位微软首席技术专家和经理在微软测试发展历程上提供的知识分享和内容支持。

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 81 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 48 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 50 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 57 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 39 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 194 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 30 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 55 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 42 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 73 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 504 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 54 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 81 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 37 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 77 KiB

Просмотреть файл

@ -0,0 +1,7 @@
# 第十六章 高效测试
上一个章节我们对软件测试的概念内涵、重要性进行了综合探讨,这一章,我们将继续聊“软件测试”,不过我们将聚焦在“高效”二字上。
我们谈及“高效”,一方面意味着要“稳、准”,同时也要“快”。将一切流程和测试都自动化驱动这件事,可能表面上可以加速流程,但是也可能引出测试稳定性下降(或者说测试结果可信度降低)的问题,英文叫 “flakiness”。比如自动化框架和自动化测试用例本身可能出问题导致用例失败而这个失败并不反映产品的质量问题。
所以如果真的想实现稳准狠的高效测试应该从产品特性和发展计划出发将各类测试技术手段有效结合组织和团队层面相应配合并搭上人工智能高速发展的列车建立智能高效可靠的测试工程体系达成“Test Excellence”。

Просмотреть файл

@ -0,0 +1,49 @@
## 16.1 一场关于自动化测试的大讨论
最近一次组织调整后木头所在的团队负责了一款新的产品的开发叫“Phone Link”和“Link to Windows”这是一款微软推出的手机和PC协同体验的跨平台应用方便用户在Windows上可以直接享用手机上的数据和功能实现跨屏互联。
### 16.1.1 让测试“自动"起来
星期一的组织站会上,木头的同事小陈接到“神圣使命”,请他负责给该应用搭建自动化测试系统。小陈犯了老大难,跑到木头的工位前来吐槽。
“咱们这个软件太特殊了需要电脑和手机配对后放一块用才能用起来。比如要在Windows的Phone Link上打开手机屏幕先得拿出手机扫码和电脑配对然后再到电脑上打开手机屏幕。一个测试用例要来回操作这个要搞成端到端的自动化可有点麻烦。”小陈眉头紧皱一边琢磨一边问。
木头点了点头,表示理解。“的确,咱们这个软件系统,涉及到跨系统跨设备,可测试性上有些挑战。”
小陈叹了口气然后继续说“而且呢对这种复杂场景进行自动化测试估计本身就会有很多的麻烦和不稳定的情况我刚刚写了个python脚本试图去驱动跑了三次都是一些脚本和驱动层面的奇奇怪怪的错误。这东西能自动化测试当然好可以提高效率和质量眼下没有靠谱的方案要不咱们还是手工测试吧更可靠一些。”
旁边的老张本来一直在敲键盘疯狂输出,这会儿听见聊得有趣,主动加入进来:“凭我十年工程经验观察,你这活不好干。”小陈心想:“这还用你说。”
“BUT你首先要明白自动化测试Test Automation就是让测试自动起来可不只是UI自动化测试。你刚刚讲的端到端测试其实是在讲UI测试的自动化。领导让你搞的是自动化测试没限定在UI测试对吧”老张讲的兴致勃勃。
小陈若有所悟,说道:“嗯,张哥说的有道理。我的思路确实应该打开。不过,打开了思路,又有点不知道具体要干什么了...”
“可能要从现在的产品开发测试的实际情况出发从需求出发把当前没有自动化的测试变成自动的你看看现在大家是怎么跑单元测试的是不是自动化的再看看咱们测试团队现在手里有什么手动测试用例另外有没有聚焦在软件性能上的测试是否可以自动化等等。”老张边想边说“后端有没有API测试压力测试的用例没自动的都让它自动运行起来。”
木头接起话茬,说道:“还别说,老张思路很赞啊,这么脚踏实地一想,还是有很多事情可以做。”
“好像单元测试已经自动化在跑了目前单元测试不通过的代码修改是无法合入到主分支的。后端的API测试我还不太熟悉。性能测试可能也要基于一些用户场景吧。感觉还是需要从UI测试的自动化方案上突破。”小陈又把问题拉了回来。
老张说“我能理解你的想法不过还是有很多方案值得一试不一定一开始就直接搞手机和PC端到端的UI测试。单一端的冒烟测试或者集成测试和一些针对典型安全问题的漏洞扫描测试都可以探索。”
木头看到小陈的眉头越皱越紧心知老张给的选项有点太多了微微一思忖说道“其实端到端的自动化测试也可以搞我之前有朋友搞过跨平台的自动化测试方案也有的好像叫Appium听说是封装了统一的接口可以兼顾浏览器、Windows、iOS、Android的UI测试。”
小陈的眼神终于闪过一丝光彩“你说的测试框架叫什么Appium是么我去学习一下。”
木头继续说:“是的。老张说的很有道理,你如果使用这个框架,可能也是从冒烟测试、简单的用户场景开始做起,一步步把自动化体系搭建起来。”
老张也发表总结陈词:“没错,小陈你一步步来,这个事情不好做,但是大有可为。可能也要考虑考虑,领导让我们做自动化测试,无非是为了提高测试效率,并且通过自动化的手段不断的为产品发现问题,保证一些固定场景的可靠性。所以提升一定高度的讲,你做的事情意义重大啊。此外,这个事情的不好做,还有一个层面。你刚刚提的是技术上、产品上测试的问题。流程上和团队合作上也有挑战,这方面我是过来人,比如,自动化框架搭好了,谁来负责丰富测试用例,谁来负责维护:比方说,后面软件功能改了,自动化用例没有相应调整,导致自动化测试运行出了问题怎么办之类的,都是问题...”
老张当然是一片好心,热心分享“经验之谈”和“大智慧”,却不可避免的让小陈的头越听越大。
“到饭点了,咱们去吃饭吧!”木头看出来小陈面露难色,及时转移话题,为这场自动化测试真理问题的大讨论按下了暂停。
### 16.1.2 挑战背后的机遇
距离上一次自动化测试大讨论已经有月余小陈针对于本部门产品“Phone Link”和“Link to Windows”搭建的自动化测试框架已经小有规模能够定时运行一些基本的冒烟测试、性能测试检测到问题后能自动发出邮件报告小陈还运用了创新的技术手段把手机扫码这一难题攻破了大家交口称赞。团队里也有成员向小陈寻求自动化测试支持小陈也把测试结果汇总成邮件报告分享给团队。一切比最初预想的顺利。不过老张在最初提到的问题比如测试可能运行不稳定、团队合作模式的建立都依然是遗留挑战。感激之余小陈经常和木头、老张进行饭聊在团队的自动化推进道路上寻求启发。
<img src="img/Slide4.SVG"/>
随着越来越多的实践、尝试和思考,小陈逐渐感觉到,软件测试像是一个围绕软件行为预期、质量情况的命题,客观评判软件“好不好”,而自动化测试是一个双重命题:既要评判软件“行不行”,又要自动评判,要“快”,帮助整个团队提高测试的可行性,提升“人效”,把宝贵的开发人员的精力从重复性的工作中解放出来。自动化测试的核心依然是测试:如果是无效的测试,自动化起来也没有任何意义;不能为了自动化而自动化,如果搭建了一套自动化的流程,结果维护起来的成本还高于手动测试的执行成本,而收益又没有明显差异,那就需要斟酌自动化的必要性。
“如果计算机能自己理解软件、探索软件、识别问题,从而对软件进行测试就好了,也不用维护自动化的测试用例,一切会容易很多。”一次午餐时,小陈对木头和老张说。

Просмотреть файл

@ -0,0 +1,36 @@
## 16.2 从手动到自动
上一章的内容已经触及到了很多关于测试效率的话题软件测试是一个包含众多子类型和实践的领域这其中不乏重复性的工作。比如每次发版前执行的回归测试、每次修改代码后运行的单元测试和冒烟测试等等。这些既定的、有明确的的输入和预期输出定义的测试可以比较方便地进行自动化。在瀑布流开发时代当开发和测试周期转化相对低频测试更趋向于在相对长的周期内“一次性”的时候将测试自动化起来并不是一个十分重要、核心的议题。当敏捷开发、极限编程等强调快速迭代、频繁交付和及时反馈的开发理念和实践流行起来后测试的频次明显提高软件复杂度也加速提升重复的执行一些测试变得“反人性”从效率和方法上也都“很low”。
> PractiTest提供的软件测试年度报告中在过去的一年中有51%的手工测试被自动化测试所替代,但是自动化测试依然无法被当做解决测试问题的“银弹”。
### 16.2.1 狭义自动化与广义自动化
简言之自动化测试就是把测试自动“跑”起来是利用软件工具和脚本来执行测试任务和验证软件系统的过程它是持续集成和持续交付CI和CD Continuous Integration 和 Continuous Delivery的核心概念和重要构成。有的关于自动化测试的著述中将“自动化测试”和“测试自动化”两个概念进行了区分认为自动化测试仅仅指“测试用例运行”的自动化而“测试自动化”指测试全流程的自动化包括对测试的环境准备Setup、执行Execution、结果分析Analysis、报告Report、环境清理Cleanup和其他辅助流程Help的全面SEARCH全流程自动化。这有点像“Automated testing”和“Test automation”之间的区别区分出了“狭义”和“广义”。本书不再进行这样的区分自动化测试即“Test automation”指广义的软件测试全流程自动化这就让我们可以探讨的内涵更加丰富而且全流程的自动化也是高效软件开发、时代发展的要求。
<img src="img/Slide5.SVG"/>
因此,自动化测试不再是软件测试的一个单一分类,而是一个发展方向,一个对测试的全面“加成”、“赋能”,而且是从深度和广度两个方面上:从深度上,按照上一章的测试分类中的所有测试都可以自动化;从广度上,测试的从测试环境准备、测试数据生成到结果分析的全流程也都可以自动化:
- 不同的“端”移动端Android和iOS、桌面端Windows和Mac OS、浏览器、服务端等等。
- 不同的测试类型UI测试、性能测试、可用性测试、无障碍测试等等。
- 不同的流程和环节:测试环境配置、测试数据生成、测试结果分析、测试报告、结果可视化等等。
- 测试平台化:测试任务调度、测试设备管理、测试稳定性提升。
> 上一小节的故事中“Phone Link”和“Link to Windows”项目的单元测试白盒测试已经是自动化的状态了而更偏向于黑盒测试的UI测试、端到端测试还没有自动化跑通而且该测试涉及到多个平台Windows和Android还涉及到物理设备Android手机扫二维码问题的解决而小陈将框架搭建起来后将测试失败后自动发出错误报告给团队的功能也做了出来这就覆盖了测试报告的自动化不要小瞧这个自动报告的功能这个功能对于开发团队非常有用是串联整个自动化和持续集成的关键的“最后一公里”而且可以大大提升小陈工作的可见度visibility和影响力impact可谓一举多得。
笔者相信软件自动化测试领域是大有可为的。当下这个领域的成熟的框架和工具已经非常多但还没有一个框架、解决方案或平台能通吃这个领域更多的是在某一个子命题下深耕。同时从深度上看探索型测试被认为是手工测试的“皇冠”具有很高的专业性、需要刁钻的思考角度探索型测试人员常常能发现一般手工测试无法发现的严重问题因而通常被认为无法自动化。那么事实如此吗随着AI、AIGC、LLM、计算机视觉CV和强化学习技术RL的发展也许有一天探索型测试也能被自动化驱动。
### 16.2.2 一定要自动么?
在上一小节小陈、木头和老张的讨论中,我们已经可以大致了解自动化测试对于一个开发团队的意义。更确切的说,一个团队要做自动化测试,大多出于以下几个原因:
- 提高效率:自动化测试可以自动执行大量的测试用例,比手工测试更快速和高效。它可以在较短的时间内完成大量重复的测试工作。
- 提高测试覆盖率:自动化测试可以覆盖更广泛的功能和测试场景,确保系统的各个部分都得到测试。
- 提高测试质量:自动化测试可以减少人为错误和疏忽带来的问题。它可以按照预定义的标准和规则执行测试,减少人为判断的主观性。
- 提升持续集成和交付能力:自动化测试可以与持续集成和持续交付流程集成,帮助团队更频繁地进行集成和交付,从而加快软件交付速度。
在考虑一种测试需求或类型是否要自动化、还是采用专职测试人员进行手工测试的时候,我们可以从以下方面综合考虑:
<img src="img/Slide6.SVG"/>
此外,测试的自动化还能带来更长远的价值:当我们能利用好自动化实现了软件产品的持续集成和持续测试,下一步的软件测试的工程化就已经初具雏形,可以进而考虑更高集成度的工程系统方案,点亮整个“技能树”:比如考虑利用容器化来构建测试环境,或者引入机器学习来实现测试数据或用例的自动生成。这对一个纯手工的测试团队是无法触达的。

Просмотреть файл

@ -0,0 +1,100 @@
## 16.3 移动应用的自动化测试
2007年苹果公司发布了第一代iPhone开启了智能手机和移动元年并推出了App Store成为第一个真正成功的移动应用市场。随后随着Google Android的入局移动应用Mobile Application市场加速发展。2014年前后移动手机出货量超越PC同年微软提出“Mobile First, Cloud First”战略强调了移动设备的普及和智能手机的快速发展对于用户的重要性并通过云计算提供无缝的跨设备和跨平台体验满足用户在移动环境下的多样需求。随着3G/4G网络的普及移动市场的用户规模不断增长并继续扩大其对互联网使用的主导地位。
移动应用开发也逐步成为软件开发的主旋律之一新技术层出不穷、百花齐放从最初的Android的Java技术栈、iOS的Objective-C、和移动浏览器的JavaScript主导到今天Kotlin、Swift、Flutter、React Native等原生和跨平台技术的融合迭代移动应用开发依然在快速发展和不断创新。
### 16.3.1 移动应用自动化测试的特点
移动应用开发出现在DevOps和敏捷开发理念普及之后所以自动化测试和持续集成的实践在移动领域成为“标配”和“常规操作”相应的平台一般都有原生的技术支持。因此以其独特的复杂性、时代要求移动应用的自动化测试也呈现出以下特点
1. 丰富的平台测试工具根据移动应用的平台iOS、Android和技术栈选择适合的自动化测试工具。常见的移动应用自动化测试工具包括Espresso、XCUITest、Playwright等。选择合适的自动化测试工具。以下是笔者汇总的常见移动或跨平台测试框架以及一些基本的参考信息2023年7月数据
| 框架名称 | 支持平台 | 黑盒or白盒 | 所属社区 |
| :-------------- | :--------------------------------------------- | :---------- | :-------------------------------------------- |
| Espresso | Android | White&Black | Google Android 官方测试框架 |
| XCTest | iOS | White&Black | Apple iOS/Mac OS 基于XCode平台的官方测试框架 |
| Xamarin.UITest | iOS and Android | White&Black | Microsoft Xamarin跨平台应用技术社区研发和主导 |
| Playwright | Cross-browser web应用自动化移动Web应用 | Black | GitHub 52.6K stars |
| Selenium | Web applications and websites | Black | GitHub 21.1K stars |
| Appium | Android, iOS, Windows, Web应用 | Black | GitHub 16.6K stars |
| Nightwatch.js | Web applications and websites | Black | GitHub 11.4K stars |
| Detox | Android, iOS | Gray | GitHub 10.4K stars |
| Robot Framework | Web, Android, Windows (with tools lib support) | -- | GitHub 8.2K stars |
| Airtest | Android, iOS, Windows, Web基于游戏场景定制 | Black | GitHub 7.2K stars |
| maestro | Android, iOS, ReactNative, Flutter应用 | Black | GitHub 4K stars |
| WinAppDriver | Windows App | Black | GitHub 3.2K stars |
> 可以看到,移动测试框架种类繁多。开发者可以根据自己的平台需求、测试策略、社区活跃度需求等因素进行综合评定,选择最适合自己的。
2. 考虑跨平台、硬件兼容性如同浏览器应用需要考虑不同浏览器平台的兼容性移动应用的自动化测试需要考虑平台系统平台和手机硬件兼容性。相较于苹果设备安卓平台碎片化更严重不同的设备型号、操作系统版本和屏幕尺寸这种系统定制的自由度和体验的碎片化比如不同系统的应用权限管理的位置可能各自有一套逻辑让移动和开发的动开发和测试的复杂性都上升了一个台阶。如果你的应用在需要多个平台上运行比如同时开发iOS和安卓应用或使用混合应用开发框架如React Native、Flutter那么就更需要确保自动化测试覆盖多个平台和设备。
> 选择在真机还模拟器运行移动端应用的自动化测试是一个永恒的问题。真机和模拟器在运行测试方面各有优势。真机往往性能更好、运行速度更快而且和用户实际体验更为接近。而模拟器定制性强系统环境干扰因素少资源权限和灵活度更高最重要的是成本低一般无需采购硬件设备。这里笔者的建议是经费允许的情况下能选真机选真机上手更方便而且优先选择谷歌自家出品的机器原生支持更好。但如果打算利用灵活度和定制性更高的模拟器那么自己去调试模拟器也是可以的有的开发人员把模拟器玩出了花样做出成熟方案后开公司去了比如Arnaud在2011年前后创立的Genymotion
3. 移动场景的性能要求相比于桌面端电脑设备移动设备的硬件限制和环境变化都会更多。一般而言移动应用的内存、存储空间、电池电量、网络环境以及CPU占用都和桌面端、浏览器端的应用在要求上更苛刻。虽然移动端设备的性能现在正在逐渐追赶PC手机内存RAM也来到了12GB时代苹果公司的M系列芯片也下沉到了移动端。但没有发生变化的是移动设备必须便携和具备持久的续航。而所有的资源消耗最终都可能会关乎耗电量和设备的续航。
> 当然如果有一天手机上可以配备核燃料电池有取之不尽的电量能源那么性能消耗也许不再是一个瓶颈但手机CPU、GPU散热依然会是一个问题不然会引爆核燃料电池。
此外移动场景下的网络环境也更复杂如果用户覆盖足够广横跨亚非拉美欧大陆可以考虑搭建自动化测试能够模拟不同类型的移动网络例如2G、3G、4G、Wi-Fi和边缘网络以验证应用在不同网络环境下的表现。
总之对于移动应用性能测试的意义很大如果能够自动化运行在开发进程中不断进行自动回归验证及时发现问题regression那么自动化的价值会得到凸显。
4. 独特的交互方式移动应用的交互方式与桌面应用和浏览器有很多不同之处手机大多是通过一块触屏完成几乎所有的交互此外一部“小小”的手机上还配备着诸多IO输入输出设备麦克风、震动马达、陀螺仪、摄像头等用于实现不限于多点捏合、拖拽、长按、滑动、震动反馈、屏幕方向感应、语音输入输出、生物信息识别3D面容和指纹等、光线感应、运行状态感应等等交互方式。此外还有基于后置摄像头的扫码、拍照、AR增强现实交互等纷繁多样的创新交互近年出现的折叠屏手机上连屏幕铰链都成为了交互方式新变量。
所以还真的别看手机体型不大里面的IO设备可着实不少创意、玩法繁多。有些场景尤其是基于摄像头的AR、扫码、面容识别等等不搭建一间测试实验室Test Lab提供工业级别的管理还真的是很难进行全自动化的测试。
关于移动应用的自动化测试特性,我们不再进一步详细展开。以上四个方面已经概括了软硬件层面绝大多数的特殊性。这些要点即使特性,也引出了移动应用测试的挑战:
- 测试本身的稳定性不高High Flakiness测试无法在本机上运行中间依赖的环节多驱动层、连接层、测试执行层黑盒多。
- 移动测试运行环境特殊Environment Diversity需要“跑”在移动设备上而移动设备是一个广阔的集合各类系统、各类配置、各类形态。
- 几乎无限可能的交互方式Limitless UX Complexity移动场景下的交互创新千变万化层出不穷为测试带来了新的挑战。
- 性能很重要Performance Matters测试需要深入的性能层面。
总之移动测试需要HELP接下来我们将从一个实际的案例出发尝试将移动应用的自动化测试流程化、体系化于DevOps开发系统进行集成给出敏捷开发场景下的综合解决方案。
### 16.3.2 搭建移动应用自动化测试体系
搭建一套完整的移动应用自动化测试体系是实现持续集成的重要一环,我们希望借此确保每次代码提交都会触发移动应用的自动化测试,并将测试结果综合分析和反馈给工程系统,在一定的标准上保障代码质量。下面我们将这个体系拆分成关键的模块,然后结合一个移动应用开发的案例,了解其运作方式:
假设我们正在开发一款新的移动应用。开发者会在**代码仓库**中创建和维护源代码。每当开发者提交新的代码到代码仓库,**持续集成系统**就会自动触发,开始一个新的**构建任务流水线**的“线上任务”。
构建任务流水线首先会从代码仓库拉取最新的代码,然后在构建任务管理和执行系统的控制下,进行编译、静态代码分析、单元测试等一系列操作,最后生成可部署的应用程序,将其与测试用例、测试需求一起交给**测试管理系统**。
然后,**测试设备管理平台**会根据需要,为即将进行的测试任务分配合适的测试设备。**测试任务分发和管理系统**会根据预先定义的测试策略,创建并分发各种测试任务。接着,**测试设备和环境控制系统**会根据测试需求,调整设备的状态和环境配置,如网络连接、电池电量、地理位置等。
一切就位后,**移动设备测试驱动**会启动并运行应用程序,而**测试任务执行器**会按照指定的测试脚本进行操作,如点击按钮、滑动屏幕、输入文本等。在测试过程中,**测试日志和结果记录器**会持续收集和记录应用的运行情况,如运行时数据、错误日志、崩溃信息等。同时,**录屏和截屏系统**会记录应用的视觉表现,以供后续分析。
所有的测试结果最后会汇总到**测试结果分析系统**进行分析。该系统会识别问题、计算测试覆盖率、性能基准等,并生成测试报告。如果在测试过程中发现了任何问题,测试管理系统会将这些问题发送给**问题发现和跟踪系统**来记录,并追踪其解决过程。
<img src="img/Slide7.SVG"/>
利用上面的体系架构我们可以梳理清楚完整的、现代化的移动测试自动化系统的周期和组件关系用以支持快速、自动、系统地进行应用测试确保移动应用的质量。接下来我们将简单介绍利用开源方案Hydra Lab搭建上述测试管理系统。
### 16.3.3 使用Hydra Lab搭建移动云测平台
上文中我们介绍了一套移动测试自动化的工程方案。其中代码托管Code Repo、测试运行框架Test Runner/Framework和持续集成系统(DevOps System or CI/CD System)等部分已经有了非常完善的开源或商业解决方案JenkinsJUnitAzure DevOps等可供复用。然而在测试设备管理、测试任务分发和测试任务调度等方面我们还缺乏一个平台能够帮助我们将这些重要的测试流程服务化从而真正做到全流程自动化。我们调研了市面上一些比较成熟的商业化移动云测平台。这些平台大都提供了全面的功能且收取的费用并不高。但是该领域还没有一个成熟的开源方案能够支持更高程度的测试运行定制化和更灵活的测试设备管理方案。因为手机硬件发布更新迭代快有时开发者需要将自己手中的定制化测试设备比如企业定制Android扫码器或者最新发布的手机接入到测试云服务中并与DevOps系统联动集成第三方商业化的平台目前无法提供这样的定制化和安全可控服务。
微软于2023年初开源了Hydra Lab填补了该领域开源解决方案的空白。它基于Spring Boot和React构建支持包括Appium、Espresso、XCTest等多个测试框架致力于提供一站式的、跨平台的云测试服务。这款框架集成了测试运行部署、测试设备管理、低代码测试等功能支持Docker部署、开箱即用。Hydra Lab的初衷是为移动跨平台应用的开发团队提供快速、自我管理的云测试基础设施提高开发效率和质量保障能力。具体来说借助Hydra Lab开发团队可以直接利用已经采购的测试设备搭建一套内部的持续测试的工程化系统也可以通过配置 Hydra Lab Agent 将自己手头的测试设备接入到已有的 Hydra Lab Center节点上。Hydra Lab目前的主要特性包括
1. **分布式测试设备管理**基于center-agent分布式设计实现可扩展的测试设备管理。
2. **测试任务管理**Hydra Lab提供了全面的测试任务管理功能方便开发者追踪和调整测试任务的状态和进度。
3. **测试结果可视化**:提供测试结果数据图表、录屏展示等。
4. **广泛的测试支持**Hydra Lab支持Android Espresso、Appium、XCTest、maestro并且借由Appium可以实现更多跨平台Windows、iOS、Android、浏览器的测试。
5. **智能测试**Hydra Lab还支持无用例的自动化测试如Monkey test和智能探索型测试。
6. **测试稳定性监控**Hydra Lab在Docker端集成了Prometheus和Grafana可以实时监控测试设备状态和测试任务运行状态支持在测试设备掉线、任务失败自动发邮件报警。
关于Hydra Lab智能化的探索以下是一段Hydra Lab开发者团队的自述
> 不同于一般的测试框架Hydra Lab 旨在提供一套测试工程化解决方案,或者说是一套开源云测平台,我们希望它方便地能够与 DevOps 系统、编译系统或 GitHub 等开发工具或平台结合给开发团队带来低成本的测试全流程方案。同时我们将智能化引入其中大家可以在这个项目中看到一些自动化生成测试用例的模块、方案以及相关的prompt。工程化和智能化是Hydra Lab的两个核心关键词而工程化是智能化赋能的基础一旦有了工程化的平台很多痛点的解决方案都可以沉淀在这个平台中。比如UI自动化测试任务可能会出现一些不稳定的情况突然找不到某个元素或者出现一些意外遮挡情况。这种情况下的测试任务失败可能没有反映真实的质量问题。而有了 Hydra Lab 这样的平台级方案,我们可以对这类 flakiness 做识别重新运行任务从而提高稳定性。这同时也相当于我们把识别和处理测试不稳定因素的经验沉淀到了Hydra Lab开源工程中一人贡献全社区受益。
搭建Hydra Lab云测平台大致分成三个步骤
- 将Hydra Lab管理中心服务management center service的docker image部署到云服务器或者云计算服务容器上。
- 在测试机器上启动 Hydra Lab 代理服务agent service并将其注册到管理中心。
- 通过调用Hydra Lab管理中心服务暴露的 RESTful API 运行测试。
该平台还提供了一个Uber版本方便一键部署作为试用体验尝鲜
```bash
docker run -p 9886:9886 --name=hydra-lab ghcr.io/microsoft/hydra-lab-uber:latest
```
在Hydra Lab服务部署好后开发者可以通过Hydra Lab提供的Gradle插件或Azure DevOps插件的方式触发测试任务的运行。更详细的内容可以在其GitHub平台上提供的Wikihttps://github.com/microsoft/HydraLab/wiki上进一步学习了解包括定制化的功能、部署方式等等。

Просмотреть файл

@ -0,0 +1,92 @@
## 16.4 测试工程化
有了自动化测试的“能力加成”整个软件测试过程可以变得更加流水线化Streamlined。但是软件测试是一个涵盖众多测试类型、测试技术的领域如果在软件生产车间中从设计到发布上线之间的软件生产流程中有效的嵌入各种软件测试使其成为一个有机结合的工程体系就是我们本节“测试工程化”想探讨的问题。测试工程化是一个在软件工程领域中逐渐发展起来的概念并不是一个“学术名词”没有一个公认的“定义”不过这对于软件开发和测试工程师来讲完全不是一个问题。
测试工程化是将软件测试纳入整个软件开发过程中的一种方法,就是为了提高测试效率、质量和可持续性,让产品质量时刻出于验证基线的相对安全标准之内,让大家可以早点安心下班,具备非常实惠和实际的意义。我们先回到本章最初的故事中,体会下测试工程化这个“非学术命题”下,要解决的一些实际问题。
### 16.4.1 自动化测试体系成形之后
小陈给Phone Link产品体系搭建起初步的自动化测试之后和多个功能团队对接 受到了各路好评成就感爆棚心情大好。看到木头在公司的英文名叫Wood给自己也起了个英文名Nathan翻译过来叫“内森”胸有成竹之意他和木头开玩笑说“你品品你细品”。两人正聊着邻居团队的小郭找过来说道
“小陈啊不对内森咱们现在往主分支里写个代码合入之前要跑单元测试还要跑端到端的全量的UI测试一次验证下来不算编译都要40分钟大伙们都有点受不了。”
“哦现在要40分钟吗那再加上编译时间前后一共要一个多小时了是么”小陈问道。
“是啊有的时候莫名其妙要到一个半小时。有时候等半天跑过了其他同学过来代码评审提一条建议这一修改又是等好久现在PR拖几天进不去是常事。”
“这问题挺严重为什么会跑40分钟呢”小陈沉吟道。
“我之前在Windows团队一个验证跑两个小时是常事为了质量宁可错杀不能放过。”木头过来先圆个场接着说“小陈你看看这个40分钟的测试是不是没必要作为每次合入都验证的内容咱们团队规模也不小一天30多个pull requests可能测试系统也负载不过来吧。”
大家聚到电脑前检查了测试流程除了1500个大大小小的单元测试10多分钟跑完还有30多个“事无巨细”的UI测试用例平均每个要跑不到1分钟加起来一次跑20多分钟。大家一起盘了盘这些测试用例里面有些很基本的验证也有些很细枝末节的corner case的验证还包括一些性能验证方面的测试用例。
“这个测试用例集合里面杂七杂八的用例有点多。”木头说道“谁没事加了这么多case有的写的还挺复杂这函数调用有的我都没见过。”
“有的是功能团队写功能的时候加上的还有一部分性能相关的、bug回归测试貌似是实习生小刘加的。”小陈回答“可能用来检验每个代码改动不太合适。”
“那是相当不合适!”老张突然出现在围观队伍里,吼了一声,把小陈吓了一跳。
老张接着说“高频验证高频低频验证低频。这里面有的case根本不用放在CI或者BVT里面后置一些放到发布前的验收测试都行了。”
小陈惊叹于老张每次一出口都可以把自己说蒙,好像在听软件开发领域的“道德经”,回过头来愣住盯着老张。木头静静的“欣赏”着两人的互动三秒后,开始继续“破冰行动”:
“老张讲的过于精辟,很有道理,我来给翻译翻译。”木头稍稍一顿,接着说:“就是说,高频的验证环节应该验证高频的用户场景的用例,比如每次代码合入请求都会触发的验证测试,不太适合验证一些用户低频场景,比如这个用例,打开设置菜单,滑动到底,进入隐私条款,滑到底,打开隐私条款内容等等,这个用例太细致,也是用户使用过程中比较低频的操作场景,放到验收测试或者某些全量回归测试就行。”
“懂了,所以什么时机做什么测试,是一门学问。”小陈说:“我得把这事情理清楚,回头用一些文档界定一下,不然大家写自动化的测试用例,不清楚放在哪里。”
“对喽,搞测试工程,要讲究策略的。”老张一副“孺子可教”的样子,继续老气横秋的说道:“质量把控肯定要严格,但是依然要和效率做平衡,每改一行代码都把整个软件颠来倒去测一遍肯定不合适。测试的策略就暗含着对风险的评估,而风险评估又对应着一个产品开发团队的优先级。测试工程里面需要运用多种测试来构建一套在效率和质量平衡点上的体系,让大家可以安心地早点下班,哈哈。”老张说完,一帮人里只有他自己在笑。
“小陈咱们这次责任范围可以晋级你以后就不只是咱们团队自动化测试的负责人了是整个测试的负责人了哈哈哈。”依然只有老张自己在笑不过这次因为老张在对着小陈说小陈迫于面子压力也干笑了一声。老张继续说“你可以把咱们手工测试、工程师内测、alpha/beta用户测试都盘点一下建立一个工程化的测试体系。”老张是湖北人心想这事情如何跟九头鸟挂上关系略微一顿接着说道“起个名就叫Hydra Lab九头蛇啥都能干让这些流程Just In Time岂不妙哉。”
小陈知道老张说的很有道理“Hydra Lab”也听起来是个很棒的名字不过对于他画的这个“大饼”的确有点吃不消。木头又一次加入到讨论中几人转战食堂饭聊逐渐越扯越远“就说不远的未来有一个办公楼里一个人影没有不开灯只能看见几个亮着的屏幕、听见机器嗡嗡作响。全自动写代码几个不同人格的AI自己开发自己测自己发版自己上线你说吓不吓人。”“吓人太吓人了。”“好孩怕。”“全是小陈搞出来的人家从测试发家搞自动化、工程化、智能化再从测试驱动开发最后赢家通吃了。”“太强了给大佬夹菜求带”“你们可太能扯了逗死我了。”几个人聊得好不风趣。
### 16.4.2 测试工程化要点分析
测试工程化的概念是建立在现代软件工程的敏捷开发、DevOps等理念之上的综合了测试策略、自动化测试、持续集成和持续交付、质量度量等方面是将测试纳入软件开发全程的方法力图为软件开发提供可持续的、高效的质量保证。
至于如何纳入,首先,测试和验证的流程应该和“变化”绑定,这种变化不止于代码修改,还可能包括:
- 上线和发布:软件交付给一个用户群体。
- 版本变化比如线上用户软件从v1升级到v2。
- 做实验:一个新的功能开启。
- 内部依赖变化把类库从1.1升级到1.2。
- 外部平台的变化比如用户的设备操作系统大范围从Windows 10升级到11。
等等,总之,变化可能不止源于自身,有可能来自软件的“四面八方”。而这些变化隐含了风险。任何成功的测试工程化流程都需要一个明确的测试策略和计划。这涵盖了确定测试目标、范围和优先级,并根据项目需求以及风险评估来确定测试的重点和覆盖范围。
此外重复性任务和回归测试通过编写可靠的自动化测试脚本进行自动化然后这些脚本将集成到持续集成和持续交付CI/CD流程中。测试环境和数据管理也是必不可少的。需要建立适当的测试环境包括硬件、软件和网络配置并对测试数据进行有效管理如数据准备、数据脱敏和数据回滚。一旦测试环境和数据准备好测试便可以集成到CI/CD流程中。这确保每次代码提交都会触发相应的测试并将测试结果反馈到版本控制系统和构建工具中。
与此同时测试人员、内测团队如运营人员应与开发人员紧密合作响应反馈进行持续集成、测试优化和缺陷修复。测试工程化流程还应包括持续监控和反馈机制例如建立监控和日志系统以便收集和分析生产环境中的运行数据和问题提供反馈并及时发现并解决性能问题和异常。如果有条件有需求还可以制定质量度量和报告标准Baseline用于对测试结果和软件质量进行定量评估并生成清晰的测试报告以供决策者参考。适当的培训和知识分享、建立适当的文档和知识库也大有裨益。
总结起来测试工程化是一个复杂命题但和软件工程的各方面相呼应而且越来越模式化。笔者认为最终和AI、机器学习的融合是不可避免的测试团队应该保持密切关注能掌握和应用起来是最好不过的。
#### 16.4.2.1 “Just In Time”的自动化测试
自动化测试可以在软件开发的多个阶段被引入,“纳入”的时机安排原则上和“测试金字塔”的理念很相似。测试金字塔原则大致可以描述为,根据测试覆盖范围和稳定性的不同,将测试分为不同层级,形成金字塔形状。底层是单元测试,中层是集成测试,顶层是用户界面测试。金字塔原则鼓励更多的测试放在底层,减少顶层的测试,以提高测试速度和稳定性。以下简单罗列一些常见的自动化测试类型,以及它们可以接入的开发阶段和时间点:
1. **单元测试**:一般每当代码有任何变化,例如新增或修改代码时,就可以触发全量的自动化单元测试。目标是确保每个代码单元(如函数或方法)按照预期进行工作。
2. **集成测试**:简言之,当单个代码单元被组合在一起时,进行跨单元或模块进行的测试就叫集成测试,用以检测不同组件间的交互是否存在问题。集成测试可以每次提交代码时自动运行,也可以定期运行。
3. **冒烟测试**冒烟测试目标是看看改了之后还能否“通电冒烟”确认新的改动没有破坏软件的基本功能。通常在每次构建后进行称为BVT(Build Validation Test)。
4. **性能测试**通常在BVT之后或者和回归测试并行进行目标是评估软件系统的性能表现。有时会结合一些压力场景进行也有通过一些“长途测试”Long-haul Test来暴露问题。通常在每个主要的版本发布前或者当系统架构发生重大变化时进行。
5. **回归测试**:当系统中有新的功能添加或者现有功能被修改后,进行回归测试。目标是确保这些更改没有引入新的错误或重新引入旧的错误。可以在每次构建后或部署前进行。
6. **验收测试**:验收测试的目标是全面验证软件系统是否满足业务需求和用户期望。在每个冲刺结束时或新版本发布前进行。
<img src="img/Slide8.SVG"/>
每个测试类型的频率可能会根据项目的具体需求和实际情况进行调整要综合评估投入产出比ROI测试用例的覆盖情况、被验证功能的优先级和就近原则什么被修改了、什么可能受到影响了就着重测试什么。这个刚刚故事里老张提到的“Just In Time”的测试很像但在一个代码行数百万级的复杂的软件系统中即使在设计层面无论多么“松耦合”、“幂等”“通过修改的内容去推断出什么测试需要被运行”依然是一个终极难题这已经超越了白盒视角来到了“上帝视角”需要全面分析软件内部的依赖关系、逻辑路径和演进情况。这也许真的是一个AI才可能解决的问题。
<img src="img/Slide9.SVG"/>
#### 16.4.2.2 软件自测和内测
软件的自测和内测的含义没有公认定义。在本章节中,统一口径为:自测指开发团队自己对自己开发的产品进行测试的过程,内测指开发团队请自己的软件社区内部用户进行测试的过程。本章最初假定了软件自动化测试是指测试全流程的自动化,那么自测和内测,也可以作为测试工程化的一部分,并进行一定程度的自动化。
上一章中我们提到在微软团队自测和号召公司同事试用和自测软件几乎已经成为了微软质量控制流程和文化的一部分这样的活动一般叫做Self-hosting或Bug Bash。同时在上一章我们也已经提到了一些活动组织的技巧和提高测试效率的技术手段这里不再赘述。其实鼓励参与感和方便的工具、友好的测试环境搭建指南是最关键的让大家快速上手、乐在其中、有获得感。这类活动一般可以定期举行也可以在特定时间点如功能实现完成后Code Complete之后进行。另外工程师在开发过程中自己写的单元测试、集成测试也是自测的重要部分。
软件内测也称为Beta测试是指在软件正式发布之前将软件提供给一部分用户进行测试的过程。这样可以让开发者及时发现并解决软件中的问题提高软件质量。内测用户群体通常是由开发者或公司组织和维护起来的也有用户自发形成的。他们会在使用过程中反馈问题和建议帮助开发者改进产品。其中的一些技术要点包括
- 招募测试用户:招募一组用户来测试软件,包括目标用户和广泛的用户群体,并建立面向他们的软件分发渠道。
- 部署测试版本:向测试用户分发软件的测试版本,让他们在真实环境中使用和评估软件。
- 收集反馈设置问题反馈渠道并能通过该渠道收集到详细的诊断报告如Bug报告、错误信息、堆栈信息等。
- 问题追踪和管理建立问题追踪系统如Jira、GitHub Issues、Azure DevOps Bug来记录和跟踪测试用户报告的问题并确保问题得到适当的解决。
- 修复和更新:根据测试用户的反馈和问题报告,修复软件中的问题,并更新软件版本。
有些面向国内软件的内测用户依靠QQ群来维护分发就是想群里发安装包文件如果用户一侧发现了软件崩溃也是让用户把堆栈提取出来以文本的形式发消息到群里这就比较原始自动化和工程化程度不高对于“小”软件、“小社群”也许简单有效但如果是管理上万人的内测社群就非常吃力了这时我们可以依赖软件分发平台来向对应渠道的用户提供内测版本比如Microsoft Store的分发平台就原生支持Flight 航道的功能,可以定义航道的优先级和目标用户,实现多渠道分发。

Просмотреть файл

@ -0,0 +1,90 @@
## 16.5 从自动到智能
2023年是人工智能发展的有一个里程牌年份ChatGPT横空出世再次点亮了AI赛道曙光。在这个智能化加速的时代软件应用的广泛普及和不断增长的软件复杂性对软件测试提出了更高的要求。过去几十年我们目睹了软件测试的自动化发展。然而随着人工智能AI和生成式人工智能AIGC的快速发展软件测试被智能赋能成为了一个必然的方向很多企业和开发团队已经走在探索的道路上。
回顾过去软件测试的自动化已经极大地改善了测试效率和质量。自动化测试工具和框架的出现使得测试人员能够快速执行大量的测试用例减少了手工测试的繁琐工作。然而随着软件系统越来越复杂测试环境的多样性增加传统的自动化测试面临着挑战如UI变化频繁、新功能的探索性测试等。强化学习、生成式AI、AIGC以及各类Copilot“副驾驶”工具、Auto-GPT、LangChian等相关技术的飞速发展使得在AI赋能下提高测试的全面性和深度具备更高的可行性为软件测试带来了新的机遇和可能性包括且不限于以下方面
- 测试环境的模拟生成。
- 测试数据生成。
- 智能探索型测试。
- 测试用例生成和优化。
- 测试结果分析解读。
- 测试智能调度和重试:提升运行稳定性提升。
- 基于测试结果的诊断建议。
- 对话式测试体验的构建。
...
未来随着AI技术的不断进步和应用智能化将在软件开发生命周期的各个阶段发挥更大的作用一方面借助一些基于LLM技术下的软件测试场景的prompt engineering技术智能化测试将推动自动化测试更加自动另一方面软件测试也在从自动化时代迈向智能化时代“测试智能体”将有能力更好地理解和分析软件系统从代码到界面、白盒到黑盒从大规模的测试数据中挖掘出隐藏的缺陷模式和异常行为降低自动化测试用例的维护成本进一步减少测试人员的工作量和时间成本。
总之我们可以期待智能化测试在未来的软件开发中发挥更重要的作用。接下来我们将在有限的篇幅里展开探讨几个智能测试的想法和实践探索启发读者在该领域前行成为先驱trailblazer
### 16.5.1 智能探索型测试
用手工方式对软件进行的黑盒UI测试是笔者认为测试这个领域内最接近用户视角的方式。这种方式既可以非常按图索骥也可以是充满创造性的探索型测试。在2010年前后微软团队出品的《探索式软件测试》这本书中讲这种测试的深入剖析出了哲学的意味提出多种不同思路Money Tour卖点漫游, Landmark Tour地标漫游, Obsessive-Compulsive Tour强迫症式漫游, Saboteur破坏性漫游等等的漫游测试来快速穷尽用户视角下的应用使用路径、用户场景暴露问题。在自动化测试中有一种类型的测试叫随机测试其英文是Monkey Test执行测试的是一只猴子。这来源于想法“如果让一百万只猴子在一百万个键盘上敲一百万年从统计学角度他们最终就可能写出莎士比亚的话剧”。当我们大量执行随机测试的时候就是在应用这种“猴海战术”。
但试想,如果这个猴子聪明一点,能理解应用程序的界面或者接口,并能实施相对合理的交互,是不是不一定要依赖“猴海战术”,可以在更短的时间内发现问题?在人工智能、机器学习、大语言模型快速发展的今天,更聪明的猴子已经成为可能。智能探索型软件测试具有以下优势:
- 自主学习能力:测试代理通过强化学习算法不断优化测试策略,提高测试效率和准确性。
- 自动化和持续性:智能测试代理可以自动执行测试,并且可以持续地进行测试,减少了人工测试的工作量和时间成本。
- 边界情况探索:通过探索系统的边界情况和异常情况,智能测试代理能够发现更多的错误和潜在问题。
智能探索式测试的可行思路是利用计算机视觉、屏幕元素识别和自然语言处理的技术,解析和理解屏幕上的元素或者程序接口的语义,然后做出交互动作。这是一种黑盒视角的智能测试,基本的思路为:
1. **Start**:启动软件和测试智能体。
2. **Extraction**提取软件UI、接口信息API描述、UI截图以及DOM元素信息
3. **Comprehension**:识别软件界面或交互接口,运用模型进行理解,得出解析值(向量)。
4. **Decision**:将识别结果(即解析值,也或包含动作历史、反馈信息)向量交给决策模型,得出动作向量。
5. **Action**:执行动作向量中描述动作。
6. **Evaluation**执行动作后触发软件变化也可能没有变化然后重复2。
<img src="img/Slide10.SVG"/>
这是笔者团队提出的简单流程该抽象模型很像马尔科夫决策过程中涉及的概念决定下一步动作Action或策略Policy的包括当前的状态State也可能会包括之前的路径轨迹Trajectory。但是这个问题和强化学习所要解决的问题可能并不完全相同。探索性测试可能是有多元目标的而其中对于测试覆盖率的追求是一个很复杂的指标对于测试智能体而言我们可能无法事先知道应用内有多少状态、多少界面甚至开发团队也不清楚。因此这比一般的强化学习问题更复杂我们很难设计出合理的反馈函数使得模型收敛。而即使一个模型针对于一个应用收敛了对于一个全新的应用又可能遇到截然不同的情况。以强化学习和图像识别为驱动的黑盒视角下的智能探索型软件测试是一种新兴的测试方法把应用程序当做“游戏”来“玩”和探索在这种测试方法中强化学习被用作一种自主学习的方法使软件测试代理能够通过与系统进行交互来学习和改进测试策略。这样的想法在很多学术研究机构和大学的论文中也有论述但目前还没有看到成熟的可以应用于软件工业领域的完整方案。
此外智能探索还有更简单的思路即把应用内部的状态跳转看做一个状态转换图State Transition Graph然后采用深度优先或者广度优先的基本思路去遍历这张图。这种方法简单可行相当于简化了上文提到的Decision决策的步骤采用了基于简单策略或规则的方式选取元素进行交互使得探索的过程可解释性更强灵活度更高。
总体而言采用模型进行决策的思路Model-based更接近“聪明的猴子”的概念而采用固定策略、算法或规则Rule-based更可控、更容易实现。此外借助于近期的LLM、ChatGPT的快速发展我们是否可以借助他的力量提出更有趣的方向LLM-based动作决策体系或者结合LangChain等相关技术当我们可以把软件接口表示比如DOM文本、截屏图像向量序列化成prompt的时候上述Comprehension的流程是否也可以让LLM参与进来这两个问号就留给读者进行探索了。
### 16.5.2 测试用例生成
在大语言模型的赋能下,白盒测试视角的测试用例生成,尤其是针对局部、单个类的单元测试用例的生成,已经非常成熟了,一些常见的思路如下:
1. **生成测试用例描述:** 可以让模型帮忙生成特定函数或方法的测试用例描述。
2. **生成测试代码:** 对于一些常见的编程语言,如 Java、Python 或 JavaScript你可以告诉模型直接生成可执行的测试代码。
3. **提供测试覆盖率建议:** 还可以让模型生成关于如何提高测试覆盖率的建议。我们可以给大语言模型一个已有的测试套件,并让模型给出增加测试覆盖率的建议。
4. **边界条件检查:** 模型可以用来生成针对特定函数或方法的边界条件测试。
5. **生成异常测试用例:** 模型可以用来生成检查特定函数或方法异常行为的测试用例。
这方面比较流行的ChatGPT、GitHub Copilot已经非常成熟读者可以用自己手头的代码试下提示词一般形如“针对如下由三个破折号分割的代码内容请生成若干单元测试提供较高的测试覆盖率---<代码内容>---”。这里笔者就不再举例赘述。可以看出来这种方法的最大限制来自于提示词Token数量的上限在代码体量较大的情况下想生成高质量的跨模块的集成测试代码基本很难实现。
此外我们是否有可能利用大语言模型的特性辅助黑盒视角的测试用例生成我们以移动应用的UI测试为例探讨一些可能的思路。上文的智能探索测试的讲述中我们提出应用内部的状态跳转看做一个状态转换图State Transition Graph那么如果我们可以通过智能探索测试绘制出这张状态转换图再通过一定的剪枝算法将其转化为树的数据结构我们就可以以叶子节点作为一个用户场景、测试用例的终点将交互的路径作为测试用例序列化出来。
我们前面小节提到的 Hydra Lab 就对这一思路进行了实现,总结来讲就是:先探索,再利用。先通过一些策略探索和漫游一个软件,然后转换理解,形成数据结构,即“状态转换图”,最后再利用这些结构化的数据,作为后续探索和用例生成的基础。这就相当于,对软件黑盒内部逻辑进行了总结提炼,完成了一次“有损压缩”。这也很像一个测试人员第一次用一个软件,一定会先探索理解,同时在旁边整理一个信息图,这在测试领域被称为“功能图”或“状态图”,然后再设计用例;这非常自然和接近人的操作。如果我们能用计算机做这件事情,就能自动化地完成探索,绘制状态图,并生成测试用例。
最后我们可以把这个信息作为prompt提示词的一部分来利用大模型进行用例生成整个过程充分自动化和智能化仅需要较少人工干预对生成的内容进行校验和调试这也能让相应的测试用例、测试流程随着应用内部的变更进行调整和兼容。
### 16.5.3 测试结果分析
软件测试的一大挑战在于测试结果的解读和分析。以用户界面UI测试为例一次测试的运行可能会产生大量的应用日志内容、捕获测试异常信息、生成测试的最终结论。在UI测试过程中为了更好地理解测试过程和结果我们甚至可能会截取软件的屏幕图像或录制整个测试过程的视频。简而言之测试过程会产生海量的诊断信息和数据。
现在问题来了能否利用大语言模型的能力深度分析这些庞大数据中的异常情况为我们提供明确的结论LLM能否告诉开发者这次测试的异常是源于哪个模块以及如何修复它更进一步能否在分析代码的同时给出一些具体的修复建议这些都是我们需要探索的问题。整体来看我们认为测试结果分析和大语言模型的结合可以从以下四个方向进行深入探索
1. **测试异常可靠性推断:**通过大语言模型的分析我们可以对测试结果的可靠性进行推断理解测试异常是否是偶发事件、被测应用的Bug还是存在其他系统性的问题。
2. **测试失败原因分析:**大语言模型可以帮助我们理解测试失败的原因,从日志中提取关键信息,定位出导致问题的代码模块,甚至是具体的代码行。
3. **测试失败修复建议:**结合源代码分析,大语言模型可以为开发者提供针对性的修复建议,从而帮助他们更有效地解决问题。
4. **性能测试数据分析、异常检测:**对于性能测试,大语言模型能够分析大量的性能数据,检测出性能的瓶颈,提供优化建议。
总的来说,大语言模型在处理复杂、多源的测试数据方面有着天然的优势,如果我们能有效地利用这些优势,相信能够为软件测试带来实质性的提升。
### 16.5.4 智能测试以AI为对象的测试
咬文嚼字地讲智能测试和测试智能化是两个截然不同的概念。智能测试或者说智能体测试是指对AI、智能体、机器学习模型或智能应用进行测试验证其有效性、召回率等指标的测试这是一个近年来逐步受到越来越多关注的新兴方向。以下是针对人工智能Artificial IntelligenceAI、智能体、机器学习Machine LearningML模型等智能应用的测试存在一些前沿实战和技术
1. 数据集测试:测试训练数据集和测试数据集的质量、多样性和覆盖度,以确保模型在各种情况下具有良好的性能。
2. 边界条件测试:测试模型在边界条件和极端情况下的行为,以评估模型的鲁棒性和稳定性。
3. 强化学习测试:针对强化学习算法和智能体的测试,包括对策略、价值函数和环境模型的验证和评估。
4. 可解释性测试:测试模型的解释能力和可解释性,以理解模型的决策过程和推理过程。
5. 对抗性测试:随着对抗性攻击的出现,对抗性测试变得越来越重要,用于评估模型的鲁棒性和安全性。
6. 自适应测试:随着模型的在线学习和自适应能力的增强,测试需要考虑模型的持续更新和迭代过程。
7. 对抗性测试:通过构造对抗性样本或攻击来评估模型的抗干扰能力和安全性。
8. 模型评估和验证:使用评估指标和度量标准来评估模型的性能、准确性、召回率、精确度等。
目前,随着人工智能和机器学习的广泛应用,对智能应用的测试需求越来越重要,我们既要保证其能满足用户需求,还要保证构建 Responsible AI即可信人工智能。研究者和学术界也在积极探索新的测试技术和方法以应对智能应用的特殊要求。该领域挑战之一是测试数据的获取和准备这些数据代表了正确价值的导向是评价标准的核心。

Просмотреть файл

@ -0,0 +1,34 @@
### 思考与练习
1. 自动化测试可以完全替代手工测试吗?手工测试的优势有哪些?
2. 让一个手工测试的团队开始逐步践行自动化测试,需要做好哪些准备工作?
3. 你能从技术栈、测试方法的角度谈谈服务端的自动化测试和客户端的自动化测试有什么不同吗?移动应用的自动化测试有什么新特点?
4. 如何理解测试工程化?测试工程化和智能化的关系是什么?
5. 人工智能技术可以从哪些角度赋能自动化测试?
6. 以下关于软件测试的想法,你认同吗?为什么?
- 写测试用例必须根据spec所以是很机械的。
- 自动化测试没什么技术含量。
- 测试人员不需要写代码。
- 用Debug版本测试更容易发现问题。
- 大公司都是自动化测试。
- 在实际环境中的测试效果最好。
- 这个版本改动不大,随便测一下局部功能就可以了。
### 参考资料
[1] 《构建之法》,邹欣,人民邮电出版社
[2] 《微软的软件测试之道》, Alan Page / Ken Johnston / Bj Rollison著张奭 / 高博 / 欧琼 / 赵勇译,机械工业出版社
[3] 《软件测试之困:测试工程化实践之路》,肖利琼,人民邮电出版社
[4] 微软开源智能云测试平台 Hydra LabGitHubhttps://github.com/microsoft/HydraLab
[5] 打造更聪明的猴子:开源云测框架 Hydra Lab 的智能化测试实战InfoQ
https://www.infoq.cn/article/YaUjY3klLG6iT7cWvPAy
[5] Playwright enables reliable end-to-end testing for modern web app, https://playwright.dev/
[6] Appium Documentation, Appium, https://appium.io/
[7] Xamarin.UITest Microsoft Learn https://docs.microsoft.com/en-us/appcenter/test-cloud/frameworks/uitest/
[8] State of Testing 2023 PractiTesthttps://www.practitest.com/state-of-testing/
[9] Reinforcement Learning for Automatic Test Case Prioritization
and Selection in Continuous Integration, Helge Spieker / Arnaud Gotlieb / Dusica Marijan / Morten Mossige https://arxiv.org/pdf/1811.04122.pdf
[10] Exploratory Performance Testing Using
Reinforcement Learning Tanwir Ahmad https://ieeexplore.ieee.org/document/8906705
[11] How can AI and ML help you design better exploratory testing scenarios? Linkedin https://www.linkedin.com/advice/0/how-can-ai-ml-help-you-design-better-exploratory

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 81 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 73 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 55 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 42 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 69 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 76 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 67 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 76 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 67 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 96 KiB

Просмотреть файл

@ -0,0 +1,3 @@
# 第十七章 质量保障
前两章,我们探讨了软件测试的涵义、重要性和技术手段,这个领域可谓包罗万象。然而,站在软件质量的高层次视角上看,软件测试只是一种手段,保障软件的高质量才是最终目的。本章,我们依然将以一个源自真实开发场景的故事开启对软件质量保障的探讨,力图帮助大家理解软件质量保障的含义、意义,并探讨一些常见举措和未来展望。

Просмотреть файл

@ -0,0 +1,71 @@
## 17.1 发版“作战室”的故事
发版“作战室”也就是Shiproom在微软指软件发布的决策会议、讨论室主要产品经理或项目经理研发负责人、功能负责人一起探讨当前周期结束后基于目标版本代码“快照”构建出的软件产品是否符合预期和可以通过质量评估进一步上线发布。该会议具有很重要的“战略意义”所以笔者将Shiproom翻译成“作战室”。
### 17.1.1 “作战”会议上的讨论
近来木头在团队里承担了一项新角色由于他对团队产品代码和开发协作的方方面面都沉淀了很多经验领导推荐木头担任产品的发版主持人英文叫Shiproom Owner相当于这个作战室的指挥官或者核心参谋的角色。
今天上午9点55分木头提前来到会议室打开会议大屏幕将产品上线进度仪表盘投影到屏幕上为这次的Shiproom会议做准备。目前团队的产品是双周上线一个包含新功能“大版本”包含修复的“小版本”采用灵活上线的策略质量达标就可以随时上所以这个会议每周三次没有版本变得的时候后就跳过。不一会儿产品经理兼项目经理大刘TPMTechnical Programme Manager新功能负责人小李工程质量负责人小陈项目研发经理老付陆陆续续来齐聚会议室。
"大家上午好目前各位可以看到仪表盘上显示咱们有4个版本在不同的环境运行V1.2.2在内部自测环境上线到百分之20%V1.1.15目前在Alpha环境全量上线V1.1.14在Beta环境上触及到30%的用户生产环境上全量是V1.0.9。" 木头开始引导会议。
“小李请你先来介绍一下V1.2.2的新特性吧。”木头看向了新功能负责人小李。
小李报告道“我们添加了一些用户体验的优化措施并增强了一些功能模块另外有一位研发同学帮忙优化了软件的CPU占用。”
木头点点头,又看向了小陈,“小陈,你可以给我们汇报一下,这些版本的综合质量情况吗?"
小陈说道“对于V1.2.2我们已经完成了大部分的自动化的功能和性能测试但是我们在一项功能中发现了一个比较严重的bug我们看到有一定的几率大概每3到4次性能测试中有一次能触发应用在这个新功能方面的OOM。”小陈提到的OOM是指Out Of Memory即软件的内存使用超出了软件运行环境的内存使用上限。
木头皱了皱眉,“嗯,这个问题挺严重。小陈的建议是什么?”
小陈回答“我建议我们内部自测环境先回滚一个更健康的版本上这个环境下也有300多个用户。然后我们可以把修复bug的任务优先级提高尽快修复。”
木头点了点头“好这个bug貌似在仪表盘上显示出来了但是还没有在最高的优先级。”木头又看了一眼旁边大屏幕上的上线仪表由于这个bug目前定的是P2所以没有影响这个版本的健康状态仪表盘上还是“形势一片大好”的绿意盎然绿色代表版本质量状况是“健康”。“可能百分之30左右的复现概率有点高老付你对这个bug有什么看法
老付沉思了一会儿“这个bug会前小陈发出来了我们有在看之前版本没见过这个问题所以还真的是有可能是一个regression。目前还没有最终的原因分析结论但是我觉得调高这个bug的优先级没问题先定为P0的问题吧不修复没法继续上线。”
“OK谢谢老付和小陈的支持。”木头说“那我们先把这个bug优先级调一下吧。”
“改好了。”小陈说他是会议现场“唯二”带着笔记本的木头也在用笔记本投屏。不过小陈眼疾手快地打开bug直接调整了优先级接着说“你刷新一下仪表盘看看。”
木头猛按了一下F5“上线仪表盘”网页刷新了最新的OOM bug按优先级排序跃升已知bug榜单第一名同时bug关联的版本所属内部自测环境“Team Ring”由绿转红描述符由“Healthy”转为“Blocking”上线受阻
“这个看着挺吓人的哈,是不是内部自测用户也有爆出这个问题的?有没有影响他们体验?”木头问道。
小陈说“这个bug用户可能不太容易察觉到相当于应用程序在后台的时候会默默死掉导致新功能不能用但是在前台的时候可能感知不到。”
“了解但是这个问题肯定要在1.2版本解决,不然新功能挂了就白上了。”木头说:“可能老付这边看看这个问题,后续找到原因和方案也和大家分享下。”
“没问题我们研发后面举行一个Postmortem回顾和总结一下这个问题。同时我们看看是否可以在开发过程中、持续集成流程中引入相关的代码审查、静态代码分析和单元测试争取让它Fail Fast。后面如果这个问题复现有难度还要小陈协助下。”
“好嘞,没问题。”小陈回答。
“大刘,咱们目前的版本上线处理,有没有建议?”木头最后看向了大刘。
大刘回答“嗯1.2.2有问题那先回滚到上一个没问题的版本吧貌似要回滚到1.1.15?。”
“对。”木头回答。
“好的。后面这个新版本修复了也请告诉我一下我们有外部的合作客户很期待1.2版本的新功能。另外,既然每次测试可以发现一些问题,我们是否可以优化一下流程,小陈那边全测试完毕后再开始内部自测环境上线,毕竟咱们自测的用户都是同事,他们的体验也要重视。”大刘提议到。
“我没意见可以的。”小陈听到要把自己QA的流程进一步前置觉得机会很好马上表示赞同。
木头说“嗯这个议题可以讨论内部自测用户群20%上线和QA自动化回归测试同步进行我是知道之前咱们把这两件事并行的考虑主要是考虑到自动化测试还有一些不稳定因素有时候报出的问题不一定准确就用内部自测的用户运行情况做一个佐证。咱们会后讨论一下这个事情现在先看看关于上线各位同学还是否有其他问题。”
“Beta环境的1.1.14版本貌似有一个corner case的问题要修复对吧影响千分之一的用户目前在1.1.15修复了。”大刘问道。
老付接下话茬“是的我们在beta环境看到有很少的用户报出这个问题但这个如果上线到生成环境会影响生产环境300多万用户的体验以及相关量化指标所以及时进行了修复把修复的改动从主分支迁移到了相关上线分支1.1.15目前看不到这个问题了而且1.2的版本以及后续的版本都会包含这个修复。”老付转头对木头说“木头咱们1.1.15是不是就可以上beta了。”
“对这么重要的话题我差点忘了。我会后就操作上线需要老付和大刘你来在系统上审批通过下。”木头看到仪表盘上显示Alpha环境的1.1.15版本已经在这个环境下停留了5天有2000多日活用户没有新增问题数据指标都比较稳定觉得有把握继续上线。
“好的,没问题。”大刘和老付回答道。
“应该没有其他议题了,感谢各位参加!有相关问题随时找我。”木头一场紧张刺激的发版大作战会议就这样结束了。
### 17.1.2 软件发布和软件质量
一个成熟的开发团队软件发布的过程应该是对全团队透明的一个新版本最终一步步上到生产环境是整个开发团队辛苦工作开花结果的过程尽管这个过程包含着机遇与风险但一旦顺利达成是一件非常值得庆祝的事情。“Ship it!”是一句令人兴奋和期待的口号。
相应地一旦失败一个重磅的漏洞或bug逃过了层层检测落到了生产环境由线上用户报出来反馈给媒体那就不是开花结果而是“落地大瓜”。打击整个团队的信心危及到产品的成败。对于产品负责人和决策者一方面要重视软件质量保障未雨绸缪防微杜渐重视代码质量和相关流程的完善把这种文化推广到团队另一方面要鼓励大家把看到的问题讲出来并用一些量化的可视化工具呈现出来勇于面对问题而不是回避遮掩还原和讲出质量“真相”。质量的保障工具和自动化可以帮助加速但最终落在每一个团队伙伴对质量的追求和重视上。

Просмотреть файл

@ -0,0 +1,99 @@
## 17.2 软件质量保障概述
软件质量保障Software Quality Assurance简称SQA是一个比软件测试范围要更大、更泛的话题。从项目管理的视角上看质量保障是确保产品可以达到其客户或者雇主设定的交付标准所制定的流程。具体到软件开发软件质量保障是一系列活动包括规划、定义、控制、保障和改进那些影响产品质量的过程和相关活动覆盖了软件产品开发的整个生命周期从需求获取、软件设计和编码到测试和维护。一般认为测试是质量保障的一部分。
### 17.2.1 软件质量保障 V.S. 软件质量控制
为了进一步说明软件质量保障Quality Assurance的含义我们把它和另一个经常被提及的概念软件质量控制Quality Control进行一轮对比
- 软件质量保证是一种预防性活动,重在防止问题的发生,通过制定和实施质量计划、设置标准和流程、培训团队成员等方法提升软件开发过程的质量。它的目标是保证软件开发过程符合预期的质量标准,最大程度降低缺陷和问题的风险。
- 软件质量控制则更多是检测性活动,侧重于评估软件的质量并找出并修复其中的缺陷。它主要通过执行测试、代码审查、缺陷管理等手段来保证软件质量的达标。软件质量控制的目标是在软件交付前检测和修复软件中的缺陷,并保证软件满足预期的质量标准。
简单来说,软件质量保证着眼于预防问题发生,通过规范和改进过程来达成质量标准;软件质量控制则是在产品层面,通过检测和验证以发现和修复问题。敏捷软件开发中的软件质量内建"Built-in Quality",强调从一开始就把质量纳入到产品的设计和开发过程中,更接近于质量保障的范畴。
<img src="img/Slide4.SVG"/>
换言之软件质量保障的“终极目标”是使产品达到预期标准并通过流程实现“长治久安”而不仅仅是避免、发现或者修复缺陷。这个定位和软件测试以及软件质量控制都不同。可以认为SQA追求的是扁鹊长兄的“于病视神未有形而除之”。
### 17.2.2 软件质量的内涵
那么,质量保障这个“大问题”该如何分解到开发实践当中?首先,我们要保障“质量”,那就要明确软件的“质量”到底指的什么。在本书的最初我们提到过:
$$
软件 = 程序 + 软件工程 \tag{17.1}
$$
这就意味着,一个优秀的软件不仅仅是由其程序代码决定的,更在于软件开发和管理过程的质量和有效性。那么“代入”质量,我们可以得出如下的进一步公式:
$$
软件的质量 = 程序的质量 + 软件工程的质量 \tag{17.2}
$$
这就展开了“软件的质量”的含义。这里,软件质量被分解为“程序的质量”和“软件工程的质量”。这意味着,优秀的代码(程序质量)和优秀的开发、测试和维护流程(软件工程质量)是确保软件质量的关键。
<img src="img/Slide5.SVG"/>
笔者认为放到更大的时间尺度上质量最终要落到“人”上和团队的质量意识、文化密不可分在实际的操作上这个文化会体现在团队的流程设计的完善度、QA团队的话语权等等而并非虚无缥缈的政治口号。因此这里可以加一个“buff”
$$
长期的软件质量 = (程序的质量 + 软件工程的质量) * 团队的质量文化系数 \tag{17.3}
$$
优秀的团队质量文化,如开放的沟通、积极的学习、持续的改进等,能够有效地提升软件的质量。反之,如果团队的质量文化弱,那么即使程序的质量和软件工程的质量都很高,如果出现流程混乱、关注点缺失、优先级错配,就很难说质量可以“长治久安”。
上面的内容讨论中,我们尝试联系前面的公式,拆解了软件质量的概念。在我国的软件工程向拼质量的相关标准中,就分四个层面提出了过程质量、内部质量、外部质量和使用质量,来展开软件质量的内涵:
- **过程质量**:过程质量衡量软件的研发过程对于质量的保证程度,较好的过程质量意味着软件的研发过程是按照比较科学的方式方法进行,也就是我们上面说的“长治久安”。
- **内部质量**:内部质量是指软件研发过程中软件的质量,在这个过程中会产生的需求文档、概要设计、详细设计等文档和编码实现,这些共同影响内部质量。内部质量是由开发来把控。
- **外部质量**:外部质量指地是软件开发完成后,整体运行时暴露出来质量特性,外部质量的界定是由系统测试的来对软件进行质量评判的工作。
- **使用质量**:当软件交付用户后,由用户在使用时感受及目标的符合程度,简单来说就是用户说你的软件好不好,这就是使用质量。
前面的过程、内部、外部质量都可以由公司的内部人员来进行评估;而使用质量一般是用户或企业客户说了算。以上四个维度的质量和我们上面说的质量拆解法的异曲同工之处在于,两者都强调了质量既是一个“结果”,也是一个“过程”,因此需要体系化、标准化的手段来保障。
### 17.2.3 常见的软件质量标准
软件质量标准的定义是质量保障的起始点对于软件产品我们可以参考ISO/IEC 25010 系统和软件工程质量评估模型,来构建一个初步的质量标准框架:
<img src="img/Slide6.SVG"/>
我们选取一些比较常用的核心指标,并把它们按照不同的开发阶段来进行梳理解读如下:
- 开发期代码质量:
- 易理解性Understandability指设计被开发人员理解的难易程度。
- 可扩展性Flexibility软件因适应新需求或需求变化而增加新功能的能力也称为灵活性。
- 可测试性Testability对软件测试以证明其满足需求规范的难易程度。
- 可重用性Resuability指重用软件系统或某一部分的难易程度。
- 可维护性Maintainability当需要修改缺陷、增加功能、提高质量属性时定位修改点并实施修改的难易程度
- 可移植性Portability将软件系统从一个运行环境转移到另一个不同的运行环境的难易程度。
- 运行期产品质量需求:
- 性能Performance性能是指软件系统及时提供相应服务的能力包括时间Time Behavior一般和速率相关软件执行功能时的响应、处理时间和吞吐率
、资源利用Resource Utilization软件执行功能时所使用的资源数量和类型和容量消耗Capacity产品或系统参数最大限度满足需求的程度和服务的持续高速性相关三方面的要求。
- 安全性Security指软件系统同时兼顾向合法用户提供服务以及阻止非授权使用的能力。
- 易用性Usability指软件系统易于被使用的程度。
- 可伸缩性Scalability指当用户数和数据量增加时软件系统维持高服务质量的能力。例如通过增加服务器来提高能力。
- 互操作性Interoperability指本软件系统与其他系统交换数据和相互调用服务的难易程度。
- 可靠性Reliability软件系统在一定的时间内无故障运行的能力。
- 可观测性Observability指能够通过检查系统或应用的输出、日志和性能指标来监控、测量和理解系统或应用的状态。。
- 持续可用性Availability指系统长时间无故障运行的能力与可靠性相关联常将其纳入可靠性中。
- 鲁棒性Robustness差错防御是指软件系统在一些非正常情况如用户进行了非法操作、相关的软硬件系统发生了故障等下仍能够正常运行的能力也称健壮性或容错性。
<img src="img/Slide8.SVG"/>
同时,开发期的质量体现和运行期的质量需求是可以相互联系在一起的。比如:
- 易理解性和可维护性可以直接影响产品的性能和可靠性。如果代码的设计和架构不易理解,那么开发人员可能会在修改和优化代码时遇到困难,从而可能会导致性能下降、出现新的错误或增加错误修复的时间;
- 开发期的可测试性也可以直接影响运行期的可靠性和鲁棒性。只有当软件的所有部分都可以被有效地测试时才能保证在各种环境和条件下都能正常工作。较低的可测试性可能导致整体测试覆盖率无法突破瓶颈可能在面对非常规情况或者用户非预期的操作时出现无法预测的错误影响软件鲁棒性Robustness
- 开发期的可扩展性和可移植性也对运行期的可伸缩性和互操作性有着重要的影响,云环境下,高可扩展性更可能应对大规模的用户和数据增长。可移植性则保证了软件可以在不同的环境或平台上运行,使得与其他系统的交互成为可能;
- 开发期的可重用性可以影响到运行期的各个方面。通过重用经过严格测试和验证的代码,可以提高开发效率,同时减少出错的可能性,提高软件可靠性和安全性。
更多的标准之间的相互关联性、竞争性,可见下表:
<img src="img/Slide7.SVG"/>
### 17.2.4 软件质量保障的重要性
亚里士多德说过:“我们反复做的事情塑造了我们,因此卓越不是一种行为,而是一种习惯。”质量和卓越一样,不是可以简单完成的任务或清单,而是需要在开发和服务生命周期中持续、习惯性的投入。在微软,质量保障被认为是"卓越软件工程"Engineering Excellence简称EE的关键部分并提出质量开发生命周期“Quality Development Lifecycle”将对质量的重视和实践贯穿于定义、设计、开发、运维和学习精进的周期中。对软件质量的重视和“以用户为中心”的理念密不可分而不是一句空谈。
在上一小节的故事中我们能非常深刻的感受到开发团队对质量的重视项目经理虽然急切想要发版使得合作伙伴能尽快试用上新功能但这不能以牺牲软件质量为代价生产环境有严格的软件可靠性指标即使是只有千分之一的概率偶现问题研发经理也坚持修复后在发布QA工程师有很高的一票否决权这源于对软件质量情况的准确把控。开发团队有能力搞清楚自己开发的软件质量的“真相”是非常重要的这是质量内建和质量保障的立足点。
良好的质量保障体系可以提高开发效率,让开发中的逻辑问题尽早暴露,降低修复成本;高质量的软件可以提升用户满意度,和客户建立信任。这些都是软件繁荣发展的基石。下一小节,我们将探讨应用相关技术构建质量保障体系,并展望未来。

Просмотреть файл

@ -0,0 +1,127 @@
## 17.3 质量保障体系的构建
结合上一小节对于质量内涵外延的探讨软件研发团队建立有效的软件质量保障SQA体系一般涉及如下几个要点
1. **理解需求**:首先,质量保障团队要充分理解要开发的软件产品和服务所满足的外部需求,明白目标用户期待什么、关注什么。
2. **定义质量指标**:结合产品的需求和用户场景,设定符合软件产品实际情况的质量目标,这可以参考我们上一节提到的一些核心指标:可靠性、性能效率、可用性、安全性等。
3. **建立标准和过程**:这是保障质量的关键一步。我们需要为团队制定一套清晰的、可执行的开发和测试标准,从行为和范式上定义什么是“正确的”,什么是有益于软件质量的。
4. **实施质量保证活动**根据设定的标准和流程来将流程渗透到代码审查、自动化测试、性能测试的具体过程中尽可能利用内部DevOps系统平台将他们以自动化的方式实施。
6. **培训和教育**:让你的团队理解和重视质量保证的重要性,提供必要的培训,使他们能够执行质量保证的任务。
5. **持续评估、监控和改进**:通过收集和分析各类数据、用户和团队反馈来监控软件质量,并根据结果对研发流程进行持续改进。
笔者认为一个开发团队的QA体系并不是“设计”出来的也不是大家一起“头脑风暴”出来的。体系的建立需要团队在合作、演进乃至犯错的过程中总结提升进行。软件的“质量真相”可能是一个很好的团队讨论议题。团队成员坐在一起面对质量仪表和进度看板审视自己团队产品的状况从用户和验收的视角讲出软件质量的真实情况形成有效结论并设立一些仪式感的小程序来奖励讲出质量真相和提出好建议的同学。也可以从以下数据出发围绕一些关键的质量能效指标来展开话题比如软件开发完成Code Complete之后Bug的数量、修复Bug所用的时间、用户的好评差评以及软件能运行多久平均初次错误时间Mean Time To Failure平均无故障时间Mean Time Between Failure这些都是重要的质效参考。
如果团队在这些内容的探讨上没有透明度、开放度领导层也不重视那么产品很容易进入自嗨、皇帝的新衣的困局中。换言之我们需要质量真相的讲述者“We need the quality truth teller”。本章开篇的故事中如果没有小陈和木头追踪OOM的情况展示真相可能这个问题会被忽视而上线仪表盘在bug优先级提升后显示出警戒的红色也有利于将这一情况广播出来闻者足戒。
### 17.3.1 CMM能力成熟度模型与成熟度晋级要点
以上我们简要从要点和文化层面探讨了质量保障体系,更多集中在“势”和“道”的层面。然而,具体的体系还需要能够实实在在地驱动团队行动起来的流程、工具和数据。
那么要落实到“术”和“器”的层面我们还需要“法”CMM能力成熟度模型就可以作为一个重要的参考它的成熟度层级的定义也符合我们刚刚讲到的“演进”的概念。CMMCapability Maturity Model能力成熟度模型是一个过程级别改进的训练和评估模型旨在优化业务流程并达到更高效、更高质量的结果。这个模型最初是为软件开发工程设计的但现在已经扩展到多种领域包括产品开发和服务提供。CMMICapacity Maturity Model Integration能力成熟度模型集成是指将该模型应用到项目中的集成情况是一套理论体系包括模型、实施指导、工具系统、培训认证以及评定方法。由于CMMI在网络上结构化的公开资料非常多我们将不会赘述其概念而是基于该模型体系展开其对于软件质量保障的参考意义。
如下图CMMI将产品开发业务流程为五个成熟度级别从1初始级别到5优化级别
<img src="img/Slide10.SVG"/>
1. **初始级 (CMMI 1级)**
- **状态**: 新成立的软件公司默认在这一级别,过程无序、混乱。
- **特征**: 依赖个体能力和“英雄主义”来救场。项目成功通常依赖个别杰出经理和有经验的软件团队。CMMI没有针对1级的评估官方默认所有未进行CMMI评估的企业至少具备CMMI 1级水平。
- **问题**: 进度、预算、功能性和产品质量都是不可预测的。
2. **可管理级 (CMMI 2级)**
- **状态**: 在部门或项目组范围内有基础的管理体系。
- **特征**: 管理和控制已初步设置。项目有方针和规程,借鉴以往的成功实践。这样的的管理会快速帮助项目组或者部门提升开发工作的效率与质量,但是并没有在整个组织范围内推广开来。
- **问题**: 主要集中在项目级别,而不是组织级别。
3. **已定义级 (CMMI 3级)**
- **状态**: 组织范围内有统一、标准的管理制度。
- **特征**: 整个组织的软件过程已文档化并标准化有专职人员进行监督。CMMI3级是重要的承上启下的一环因为组织范围内的统一管理不仅有助于提高软件产品与服务的效能与质量其稳定的过程可以为进一步的量化管理提供标准的分析数据也帮助组织逐渐形成了管理的文化。
- **优势**: 有助于进一步的量化管理和文化建设。
4. **量化管理级 (CMMI 4级)**
- **状态**: 在稳定的基础上进行量化管理。
- **特征**: 收集数据建立基线与模型实现过程和产品质量的定量预测。CMMI4级之前主要是定性的方式进行管理而从4级开始组织在标准而稳定的过程下收集软件开发过程中的数据建立基线与模型开启企业的量化管理之门。量化管理不仅可以将隐形的软件开发过程通过数据显性的表达出来还能基于企业的历史经验在统计学方法指导下预测项目的进展情况。
- **优势**: 项目进展和质量可预测,有更多的度量指标。
5. **持续优化级 (CMMI 5级)**
- **状态**: 组织内部形成了持续优化的文化。
- **特征**: 不断寻求新技术和新方法,致力于绩效指标的量化提升。该级别最重要的是企业内部形成了自觉的持续优化文化。组织及其成员会不断寻求新技术、新方法,追求管理上可量化的绩效指标提升。这种文化,还为企业的管理变革和转型奠定了坚实的基础,帮助企业在取得阶段性胜利之后,跨越平台期,迈向下一个改进循坏的开始,促成进一步的成长。
- **优势**: 为企业的持续成长和转型提供了坚实的基础。
<img src="img/Slide11.SVG"/>
最后我们结合本章软件质量的主题总结出一个组织或研发团队在CMMI标准下的成熟度晋级要点包括
- **从1级到2级**: 主要关注项目管理的过程改进。
- 这个过程中组织的主要注意力应该在项目和具体的过程质量上,组织应该推动制定项目级质量保障计划,明确基础的质量指标和各个发布节点的检查清单;和开发团队协定代码编写的规范和约定,完善代码评审流程。
- **从2级到3级**: 主要关注组织级的过程全面改进。
- 该层面的注意点在于审视组织架构、权责定义和划分,如果必要的话要进行组织重构;完善软件质量的培训体系,鼓励大家重视质量;对于出现的线上质量问题,大家开诚布公地共同反思(切忌,这类会议一定要要建立坦诚和鼓励包容的氛围,不要搞成甩锅大会),并让大家意识到软件质量问题的严重性,并真正能从错误中学习成长,不断变强。
- **从3级到4级**: 着重于过程定量管理的改进。
- 这时团队在质量保障的意识层面是上下一心的,那么用数据和量化手段去进一步推进科学管理就比较顺理成章,团队就要关注质量数据收集和分析,从用户和外部要求出发,立足产品目前的实际质量情况,建立质量基线和模型,然后将数据用可视化的手段呈现出来,进而再实现对指标的持续监控。
- **从4级到5级**: 聚焦于技术革新和过程优化的改进。
- 最后团队可以关注不断利用新的技术创新手段如智能异常模式识别、数据预测系统、智能诊断分析持续改进让整个质量保障体系更加自动化和智能化也可以考虑一部分核心指标形成KPI或者OKR和团队的绩效挂钩更好的激励团队在质量上精进。
<img src="img/Slide12.SVG"/>
### 17.3.2 常用技术手段
在项目开发和实施的“术”的层面,软件质量保障的技术手段是比较多元的。这里笔者依据从代码编写、编译构建到上线的先后时间顺序,列出了一些常用的、和研发过程直接相关的技术手段,不再分别展开描述,仅作参考:
1. **集成开发环境的协同编程工具和助手**
由于我们谈的是“术”的层面就不再考虑设计层面的质量考量那么编写代码就往往会成为产品质量“形成”的起始点集成开发环境也就是我们常说的IDE就非常重要他们往往提供了内置的检测和代码生成比如Visual Studio的IntelliSenseIntelliJ的Code Inspection等还有最新的GitHub Copilot X在Visual Studio Code中提供的各种插件Copilot ChatCopilot Lab等这些工具和助手帮助工程师们做了很多工作包括程序代码的编写、调试和版本控制等。这些技术不仅关乎效率也关乎“第一手”代码的质量。
在版本控制层面笔者早年开发还和团队实践过利用Git Hook功能在代码提交、推送等时间节点上嵌入质量脚本进行质量检查的方案现在Jira、Jenkins等平台已经很成熟貌似很少有团队还在利用Git Hook做质量卫士Quality Gatekeeper了。
2. **静态代码分析和扫描**
这类技术一般在不实际运行代码的情况下自动地检查和分析源代码或构建产物中的机器码以查找可能存在的逻辑漏洞或编码不当之处。在持续集成流程中加入代码分析工具如SonarQube、Checkmarx、CheckStyle、Fortify、lint、errorprone等自动标记出可能的代码问题和安全隐患。目前这个技术下的各类成熟和开源方案比较多可以比较方便的集成到各类持续集成系统中。
笔者认为这类方案中非常值得借鉴和学习的是其中对于代码常见错误或违规Violation的定义这些定义是大量编码经验总结和分类之后汇总成的宝藏“错题本”定义了违规和错误的模式、危害和修复建议而且往往有非常详尽的说明和文档从中可以学到很多有价值的编码知识推荐大家去涉猎。
3. **代码评审**
即Code Review现在大部分团队都用上了Gerrit、GitHub、GitLab这类支持Code review workflow的平台来让人工代码检查合理地接入到研发流程当中大家可以在Pull request里直接针对相关的代码上下文反馈、建议、讨论和甚至聊天也可以吐槽和互喷
这项技术也很成熟了开发实战中的核心要点在于我们应该如何定义某个代码改动谁来评审多少人来评审。这些约定往往体现了团队的质量文化以及反映了开发团队人员的权责、资深情况。相关的技术实施一般通过代码托管平台的权责规则定义来实现例如GitHub Code Owners、Azure DevOps Branch Policy这样的功能模块。笔者所在的团队以前为了鼓励大家多多评审还尝试过利用平台所提供的API把团队所有开发的评审条数、PR贡献数做成英雄榜展示给大家十分有趣。
4. **软件质量仪表盘和异常监控**
质量标准仪表盘,或者叫“质量数据大屏”,并不是一项单纯的数据可视化的技术,它是团队建立质量标准、数据埋点和统计量化、可视化仪表设计、基线认同设定等工作搞定后的最终成果呈现,一般意味着这个团队已经有较高的成熟度。
如果一个质量仪表盘视图能量化地呈现团队开发的软件产品的质量真相,从而帮助团队作出可靠的定性判断,那么它对于这个产品和团队的价值是不可估量的。产品质量情况需要透明度,一个缺乏用户质量感知的团队是无法生存下去的。
Azure DevOps平台就支持构建Dashboards功能可以较好地展现当前团队关键bug数量和优先级等核心信息再结合一些线上数据如宕机率、应用卸载率、差评率监控手段就足以驱动团队向持续优化的方向演进。对于新成立的团队也可以尝试使用Grafana和Prometheus等开源工具进行实时性能和错误监控。
以上几个技术无法涵盖整个软件质量保障体系下的技术生态近年来可观测性和ELK stack的概念的火热也说明了该领域的重要性。在微软各个团队采用不同的手段保证质量有的项目没有专门的QA是PM/Dev兼任这种组织主导下的质量保障更多融入于生产过程中更灵活而有QA的组织会有更明确的分工、职责和程序可以清楚地看到有两股驱动力在打磨产品。但不管是哪种模式各个团队都会采用静态代码分析一类的自动化手段提高效率采用威胁建模Threat Modeling来进行风险暴露和评估使用扫描工具来检查关键信息和秘钥泄漏由专门的产品安全团队检查代码的安全性进行全面的安全性检查。
### 17.3.3 未来展望
进一步讲,一个理想的质量保障体系,可能涉及到软件开发、团队合作的诸多方面,以下是一段“蓝图”的描述:
假设你是一位全栈产品经理专精用户体验熟知我们的客户、系统且能定义关键指标。你理解应用与服务间的互动与协定使用自助工具获得所需答案。昨天你刚和团队一同庆祝达到5000万月活跃用户的重要里程碑与客户公司高层共享喜悦。今晨你打开我们的服务质量Quality of Services仪表板看到
- 应用和平台关键服务水平目标SLOsService Level Objectives的视图。理想体验的用户端设备比例创纪录的达到了99.5%。
- 上次重大缺陷进入生产环境已经54天。你记得参加的缺陷原因分析以及改善异常检测的解决方案。
- 绿色标识代表成功的自动化测试运行及覆盖范围包括单元、组件、集成、压力、UI和长期测试。
- 事件部分显示服务在昨晚的Beta环境中根据端到端的性能SLOs自动回滚了部署。这个构建需要复查。
- 发布部分证实已发布的功能和应用版本满足所有发布条件,包括可靠性、性能、检查表和记分卡。顶部显示一些“待定”功能,直到满足质量标准,持续集成系统中明确了下一步及负责人。
- 客户反馈问题部分显示,有新的质量问题在内部被报告。你点击查看受影响的用户总数、各个用户的“服务稳定系数”,自动分析显示消息节点出现问题。用户的“服务稳定系数”低于预期目标时,会自动生成包含诊断数据的错误报告。
- 客户反馈部分显示最大的10个请求都是新功能需求。其中一条关于与外部游戏厂商集成的想法引人注目。总体情感得分和词云显示用户喜爱最新的应用版本。
- 商业指标部分显示了基于参与度、使用情况、可靠性、性能和应用评级的最新预测。联系质量洞察与商业指标需要大量工作,但现在已经行之有效。
在这个“蓝图”中,我们可以看到一些现在已经广泛应用的测试工程化、持续集成和持续交付、代码审查和静态代码分析、数据驱动的质量保障、用户为中心的反馈处理系统和自动缺陷分析等质量保障技术和流程。
在未来AI和大语言模型一定会大举赋能软件质量保障推动质量智能化时代的到来越来越多的团队达到 CMM “持续优化”的成熟度的成本降低、可能性不断增加:
1. **软件质量保障智能化**: 随着AI和机器学习技术的发展我们预期它们将在软件质量保障中扮演更重要的角色。例如AI可以用于预测哪部分代码最可能出现缺陷或者用于自动化地生成测试用例。不限于以下方面
- 智能代码生成。
- 代码质量智能分析,代码质量“格式刷”。
- 智能代码评审助手将直接参与到代码评审环节中辅助对代码风格、规范化、潜在bug提出针对性建议。
- 工程化测试用例智能生成方案。
- 代码逻辑可视化和模块链路分析,诊断建议。
- 智能日志分析、监控预警。
2. **基于云的质量保障**: 随着云计算的普及,基于云的质量保障服务(如云测试、云构建等)将得到更广泛的应用。
3. **更大规模的自动化和集成**: 随着DevOps和自动化工具的进步我们预期在质量保障流程中的自动化和集成将进一步扩大可以处理更大的代码模块的设计、重构本根据团队的风格、约定进行定制化支持。
最终在AIOps、LLM等智能技术的赋能下软件的质量保障是否可能在特定领域可以实现一站式服务我们只需要写代码系统能够自动构建、分析、扫码、测试问题自动出具综合质量报告并提供修复建议就像前一章小陈老张在食堂聊的“无人办公室”一样工作这听起来很不可思议但似乎在越来越近。

Просмотреть файл

@ -0,0 +1,16 @@
### 思考与练习
1. 本章开篇发版作战室故事中的团队讨论中体现了哪些软件质量保证的手段和流程你认为这个团队属于CMMI的哪个成熟度等级
2. 你会如何说服团队领导真正重视软件质量并愿意为之投资人力物力资源?
3. 假设我们团队的所有研发工程师都能做到写代码没有Bug和任何实现缺陷是不是我们就不需要软件质量保障了
4. 服务端质量体系和客户端软件质量体系在构建上是否有很大差异?他们之间的联系是什么?
### 参考资料
[1] 《构建之法》,邹欣,人民邮电出版社
[2] CMMI institude, https://cmmiinstitute.com/
[3] 微软开源智能云测试平台 Hydra LabGitHubhttps://github.com/microsoft/HydraLab
[4] 系统与软件质量模型全国标准信息公共服务平台https://std.samr.gov.cn/gb/search/gbDetailed?id=71F772D81641D3A7E05397BE0A0AB82A
[5] System and software quality modelsISOhttps://www.iso.org/standard/35733.html
[6] 打造更聪明的猴子:开源云测框架 Hydra Lab 的智能化测试实战InfoQhttps://www.infoq.cn/article/YaUjY3klLG6iT7cWvPAy

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 81 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 58 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 66 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 38 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 68 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 41 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 71 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 117 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 99 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 77 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 80 KiB

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 86 KiB