# 质量

质量上的妥协是传统瀑布式软件项目的常见特色,主要归咎于项目最后才将所有程序集成在一起测试引发的高风险.虽然scrum通过迭代和增量开发极大缓解了风险,但事实是我们仍然不能杜绝软件中的每一个错误.

# scrum代码错误

我们先看看传统的瀑布管理是怎么以一个串行的方式来看待和处理程序错误的: 程序员编码构建产品 -> 测试人员测试产品 -> 测试人员发现并记录代码错误 -> 测试人员将代码错误移交至程序员解决 -> 程序员修复错误 -> 软件发布 -> 用户报告产品错误 -> 测试人员记录并复现错误 -> 测试人员将代码错误移交至程序员解决

如果团队想尽早,尽量频繁的递交可用的功能,那么特别重要的一点是,编程和测试必须紧密相连,而不是分成串行的两个阶段

# 新的定义

在探索一下新的scrum代码错误处理流程之前,我们可能要用到一些新的定义和原则:

定义1: 问题

  • 问题是指在sprint中发生的不满足完成标准(DoD)的用户故事密切相连的问题.所以,问题通常是在实现用户故事的那个sprint里程序员或做探索测试的测试人员甚至做展示的产品负责人发现的.
  • 问题不属于PBI.相反,问题可以看做是用户故事演进中验收标准的一部分.本质上,是说问题没有解决,用户故事就不算完成.所以,问题是实际用户故事的一部分,尽管和PBI相关,但它不是独立的PBI.

定义2: 代码错误

  • 代码错误之所以算是错误,必须是在用户故事已经完成并被产品负责人接受之后发现的.所以,代码错误通常是被用户发现(发布之后)或通过自动化回归测试发现的(在实现后续用户故事时).
  • 代码错误是一种PBI.用户故事是另一种PBI.代码错误和用户故事应该放入同一个产品列表里,用同样的方法估算工作量并放在一起排优先级.某个特定的代码错误可能与一个用户故事相连,但在跟踪和排优先级时,应该区别对待它们.代码错误虽然可以用用户故事的格式来表示,不过大多数情况下这个格式并不适用于代码错误.

# 新的原则

原则1: 消除不必要的文档

敏捷宣言的第一个原则是"可工作的软件高于详尽的文档",瀑布式工作中,测试人员和程序员花大量的时间把每个代码的错误的细枝末节仔细记录文档,这导致的一个弊端就是花在文档的细枝末节的时间可能比花在修改错误的还多. scrum尽可能依赖于事实交流,如果需要文档,尽量让文档再满足目的的前提下尽可能精简(尽可能用图或表)

原则2: 立即解决问题

我们回顾一下瀑布管理中串行处理问题的方式,其中发现问题及解决问题之间会有一个明显的时差,间隔时间越长可能越需要更多的精力去修改(可能程序员已经忘了原来的编码逻辑).问题发现的越早,修改它所需要的精力可能就越少,影响也越小.所以,scrum中测试和编程总是交织在一起的.

原则3: 不要半途而废

我们需要有一个底线,就是一个用户故事在满足完成标准之前对用户而言是不存在的.客户只对最后结果及获得的商业价值感兴趣,如果一个用户故事还没做完,就应该列入开发人最高优先级的工作任务,直到完全完成之后,才可以转向下一个任务.

# 探索性测试

探索性测试(ET)是敏捷世界里的一种重要测试方法,作为一个研究性的工具,它是用户故事测试和自动化回归集的重要补充。它是一种经过深思熟虑的测试方式,没有测试脚本,可以使你的测试超出各种明显已经测试过的场景。探索测试将学习,测试设计和测试执行整合在一起,形成一种测试方法。

探索性测试的基本过程

  • 识别软件系统的目的;
  • 识别软件系统提供的功能;
  • 识别软件系统潜在的不稳定的区域;
  • 在探索软件系统的过程中记录关于软件的信息和问题;

# 自动化

scrum与强大的自动化软件工程实践相结合后作用会有显著提高.自动化是一个很大的话题,关于自动化有很多层面,很多工具以及各式各样的工具组合,我们会关注几个紧密交织的关键性自动化实践,包括持续集成(Continuous Integration),测试自动化,构建/部署自动化以及持续交付(Continuous Delivery)等概念.

# 持续集成

持续集成是团队软件实践之一,成员把他们的工作频繁的集成在一起,可能每天会有多次集成,每次集成使用自动构建(包括测试)来验证,从而确保集成错误能被尽早检测出来.

简历和运行CI是开始自动化之旅的最佳起点,只有在日常工作中频繁消除小的集成问题,而不是在项目最后才与复杂的集成问题搏斗,团队才能把自己从压力中解放出来.

# 测试自动化

没有测试自动化,3-5个sprint后,手工回归测试的工作量将变得非常大,但是有些观点认为自动化需要投入更多的资源,使用哪个测试架构以及自己开发还是使用外部工具,都需要时间和研究来决定.

当然自动化测试的好处也有很多,例如:

  • 手工测试需要太长时间
  • 手工流程容易出错
  • 自动测试可以让人解放出来做他们更擅长的事情
  • 自动测试提供了更早,更频繁的反馈
  • 驱动编程的测试和实例可以有更多的用处及收益

# 单元测试

单元测试关注的是底层,独立的编程模块,这些测试应该通过测试驱动开发(TDD)来实现.测试驱动开发要求先写测试用例,然后再写测试用例需要的所有代码,并且仅限于测试用例需要的代码.这种纪律可以帮助程序员在考虑代码之前,先专注于代码必须实现什么,这可以保证代码简单且具有可测试性.

# 功能测试

功能测试的想法是能够测试和自动化某个用户故事的整个端到端的功能.这类测试不一定包括用户界面的测试自动化,因为测试UI层会额外增加成本.

# 集成测试

通常有称为"系统测试".集成测试是确保新功能在更广阔的生态系统中正常工作的测试.比如,开发中的产品也许需要和其他内部产品或第三方产品集成在一起.

# 性能测试

性能测试有时候也叫负载测试或压力测试.性能测试关注的是策略产品在压力下的表现.如果不是每个sprint都交付产品,那可能并不需要每个sprint都执行性能测试.但也不要让集成测试和性能测试的时间过长,否则发现的问题可能会回溯到最早的设计.