-
对服务质量的自信可以用过去的系统可靠度和未来的系统可靠度来衡量。前者可以通过抓取和分析历史性监控信息来获得,后者可以用基于历史数据的预测来量化。为了让这些预测信息足够准确,必须满足下列条件中之一:
(a)在这段时间内,该系统完全没有改变。包括没有任何软件更新以及服务器数量变化,这意味着未来的行为方式应该与过去的行为方式类似。
(b)可以充分描述整个系统的所有改变,这样可以针对每个系统变化引入的不确定性进行分析。
-
软件测试的类型:传统测试和生产测试
(a)传统测试:
1)单元测试:单元测试(unit test)是最小、最简单的软件测试形式。这些测试用来评估某一个独立的软件单元,比如一个类,或者一个函数的正确性。
2)集成测试:通过独立的单元测试的软件组件被组装成大的系统组件。工程师通过在这个组件中运行一个集成测试(integration test)来检验该组件的功能的正确性。依赖注入(dependencyinjection),利用类似Dagger这样的工具,我们可以创建出复杂依赖的mock(测试中替代真实逻辑的伪组件),用以方便地测试某个系统组件。
3)系统测试:系统测试(system test)是一个在未部署的系统上运行的大型测试。某个组件的所有模块(Module)都会被装载到系统中(例如通过集成测试的软件服务器)。
系统测试包括以下几种类型:很重要的是,每个测试都有成本,时间成本和计算资源成本。时刻关注这些测试的成本,是软件开发效率提升的重要因素。
- 冒烟测试(smoke test):也被称为理性测试,如果该测试不通过,那么其他更昂贵的测试可以不用运行了。
- 性能测试(performance test):确保它不会在没人知道的情况下逐渐变慢
- 回归测试(regression test):保证之前的Bug不会重现
(b)生产测试:也被称为黑盒测试。生产测试对运行一个可靠的生产环境来说是必要的。
- 变更发布与测试
- 配置测试:比较目前测试通过的版本和自动化系统的目标版本可以暗示我们生产环境目前与实际工作相差多远。
压力测试:理解系统和组件的性能边界
(1)数据库容量满到什么程度,才会导致写请求失败。
(2)向某应用每秒发送多少个请求,将导致应用过载并导致请求处理失败。
金丝雀测试:
(1)一小部分服务器被升级到一个新版本或者新配置,随后保持一定的孵化期。
(2)并不真的是一个测试,而是一种结构化的最终用户验收测试。
-
将测试的重点集中在用最小力气得到最大收益的地方。可以先从如下的问题开始:
(a)是否能够将源代码按重要程度分出优先级?用研发管理和项目管理的行话来说,如果所有任务都是高优先级的,那么它们就也全是低优先级的。是否可以将要测试的系统组件按重要度排序(用什么标准来衡量重要度都可以,关键要排序)?
(b)是否有某些函数或者类是非常关键的,或者对业务运营极为重要的?举例来说,涉及计费系统的代码通常对业务来说是很关键的。同时计费代码也经常可以从其他部分很干净地剥离开进行测试。
(c)哪些API是其他团队需要集成使用的?有时最终用户级别的测试能够找到的问题比想象的要严重,因为它们可能会迷惑其他开发团队,使他们写出错误的(或者只是效率低)API客户端代码。
-
优先处理构建问题。原因在于:
(a)如果问题引入系统之后,又有新的变动,修复会更难。
(b)不工作的代码会对团队造成影响,因为它们必须手动绕过这些问题。
(c)定时地每晚构建和每周构建将失去意义。
(d)团队响应紧急发布的能力将会受到严重影响,甚者非常复杂和困难(例如,发现代码中以及依赖中的安全漏洞等)。
- 有时候敏捷性需要靠稳定性来驱动。如果每次代码构建的结果都坚如磐石非常可靠时,开发者才能迭代得更快!
-
SRE工具具有两个特点:
(a)这些工具的副作用基本处于被良好地测试过的主流API范围内。
(b)由于现存的验证和发布流程,这些工具基本不会对用户造成直接影响。
-
大规模测试:
(a)使用工具
(b)针对灾难测试
(c)速度
(d)生产环境与测试不一致
(e)允许测试失败
(f)集成:用单元测试测试某个配置文件可以提高可靠性之外,针对配置文件进行集成测试也很重要
(g)生产环境探针:1)发布测试可能将集成服务器包在一个前端服务器和一个虚假的后端服务器之间。2)探针测试可能将集成服务器包在负载均衡的多个前端服务器和一个真实的生产后端服务器之间。3)前端服务器和后端服务器通常有独立的发布周期,这些发布周期不会同步。