数据库测什么与怎么测
传说中有三个问题能直击灵魂:“你是谁?从哪来?到哪去?”
对于测试人员来说,“你是谁”这个问题已经解决了,剩下两个问题也随之变成了“测什么”和“怎么测”。
测什么
如果从代码开始,由内而外进行总结的话,数据库的测试,可以分为以下层次。
序号 | 测试项 | 说明 |
---|---|---|
0 | 代码静态检查 | 根据所选择的开发语言,可以根据已制定的开发规范选择相应的自动化检查工具,在代码合并到主仓库之前完成检查。 |
1 | 基于编译器的检查,sanitizers | 无论是传统一些的 valgrind,还是现在开始流行的 google sanitizers,都能够在产品走向生产环境之前,暴露出一些内存、线程等相关问题。 严格来讲这些问题的暴露是需要和丰富的测例库配合的,但由于 sanitizers 需要在编译时打开相关的选项,所以笔者选择将其放在紧挨着代码静态检查的地方。 |
2 | 单元测试 | 这是最贴近代码的测试形式,能一定程度保证被测试单元的质量,减少低级错误所引发的 bug。 |
3 | Assert | 如果说单元测试保证的是零件的质量,合理并必要的 Debug Assert 则能够通过检查关键变量是否为合理值,从而尽早地检查出零件组合之后存在的问题。 |
4 | 基本功能测试(冒烟测试) | 这个阶段的测试内容,主要是保证数据库能够像一个数据库一样运行,能够像一个数据库一样对用户的操作作出反应。 |
5 | SQL 逻辑测试 | 一般而言,SQL 逻辑测试是数据库测试的重中之重,因为如果 SQL 语句执行的结果有问题,数据库其他特性做得再好也没有意义了。 可以说数据库领域的新人和新产品是十分幸运的,因为市面上有很多成熟的开源数据库,在开源了代码的同时也开源了它们的海量测例,后来者可以直接用测例来验证自己的数据库产品。 |
6 | SQL 混淆测试 | 混淆测试即 Fuzz 测试,算是 SQL 逻辑测试的延伸,主要思路是通过分析语法树自动生成大量随机的 SQL 语句,对数据库解析器的解析能力进行考验。 现在主要有两种思路:一种是不关心语句执行结果,只检查解析器是否存在可能导致崩溃的 bug;另一种则是按照特定的算法生成语句,能够根据算法推断出语句的执行结果,再跟数据库实际返回的结果做比较。 |
7 | 压力测试 | 无故障场景下的稳定性测试,测试的手段一般都很简单,基本是通过其他工具程序模拟出长时间、高并发、高频率的客户端动作。 具体可以大致分为 CPU 资源紧张、磁盘资源紧张、内存资源紧张等几个测试方向,重点观察数据库在一般压力情况下和高压情况下,是否会出现语句执行结果出错、非预期的死锁、性能相关指标变化不符合预期等问题。 |
8 | 故障模拟测试 | 在没有数据副本的情况下,故障模拟测试一般都围绕着数据安全性进行,确认故障发生时已提交的事务数据不丢失,未提交的数据不能生效。 故障形式一般以通过 kill 命令杀死数据库进程为主。 |
9 | 性能测试 | 固定场景下测试并记录数据,待新版本发布时进行回归对比。 |
10 | 事务属性相关测试 | 事务的 ACID 四个属性,其中 ACD 三个属性都很好测试验证,剩下的 I 则无论是测试难度还是对数据库的重要性,都是四个属性中最高的。 基于传统的 ANSI 标准定义的隔离级,RC 和 Serializable 的定义清晰,相对比较容易设计测例编写测试工具;但 RR 隔离级则含糊得很,需要开发与测试人员共同参考一些比较新的论文,共同确认所研发的数据库 RR 隔离级具体能避免哪些问题,不能避免哪些问题。 |
怎么测
或者具体地说,我们需要编写怎样的测试工具。
序号 | 说明 |
---|---|
0-4 | 一般情况下更应该成为开发规范和开发流程的一部分,不需要专门由测试部门完成。 |
5 | 有很多开源数据库都拥有成熟的测试方案与工具,通用的思路是分别记录测试语句与正确的执行结果,然后通过程序自动化对比实际在数据库上执行的结果与正确结果是否存在差异。 相比于数量庞大的测例库本身,这类测试工具的开发成本显得十分小。 |
6 | 单纯生成随机 SQL 的工具,老一些的有 RQG(Random Query Generator),比较新的有 Sqlsmith,具体生成语句的规则不太相同,需要根据实际情况来进行选择或者基于某一个进一步开发。 |
7 | 可以验证 SQL 逻辑的工具,目前主要是 SQLancer,它的作者还发表了几篇论文讲解了原理。 |
8 | sysbench 和 JMeter 都是很常用很成熟的压测工具,根据具体的测试需求和测试条件,选择合适的测试工具。 |
9 | 单机环境的故障模拟是一件相对不复杂的事情,主要的工作难点集中于如何自动化判断故障发生时到恢复之后,数据库的状态是否符合预期,数据是否正确。 不同的数据库产品之间很难做出一套通用的方案,只能进行定制化开发。 |
10 | 现在主要的开源性能测试工具,基本都集中在测试逻辑本身(如 sysbench,benchmarksql)。在性能测试中,测试人员还需要记录系统监控信息、数据库的状态等,这些信息加上性能测试数据,都是在新版本发出后进行新旧版本对比的。 |
11 | 最终需要的是从测试逻辑出发,能够完成监控并记录,最终进行图形化展示与对比的一整套方案。 |
12 | 事务隔离级别的测试方案在开源社区中已有一些比较好的方案,比如由著名混沌测试工具 Jepsen 的作者编写的 elle。 测试人员需思考自家数据库产品是否需要这样的工具。 |
13 | 不同的数据库产品有不同的目标客户群体,而不同的目标客户群体也有不同的业务模型,不同的业务模型对事务隔离级的要求千差万别。 RC 隔离级别已能满足许多用户需求,而更高的隔离级别在开发和测试上都有很大提升。 |
14 | 测试人员应与开发人员共同对数据库产品进行量体裁衣,明确具体的测试需求,避免浪费不必要的人力。 |