让我们成为开源软件测试者

2017-04-25

随着开源软件的兴起,其使用范围也越来越广泛。开源软件本着“不要重复造轮子”的原则,与商业软件相比,拥有使用成本低、可定制性高等特点。然而开源软件在质量保证上仍然存在诸多的问题。本文将从开源测试工具、开源社区测试能力短板等方面来展示测试人员参与开源社区贡献的必要性。


1.开源测试工具概况

测试工具是质量保障中的“武器”,而测试工具的设计者则是精良武器的“兵工厂”。利用优秀的测试工具可以提高测试效率,发现隐藏较深的软件缺陷。根据测试工具的功能,我们将其划分为测试管理、缺陷管理、持续集成、功能测试、性能测试、测试框架、测试设计、安全测试等类别。下面列举了这些分类中一些典型的测试工具。

测试管理: TestLink, Testopia

缺陷管理:Redmine, Bugzilla, Mantis

持续集成:Jenkins, Buildbot

功能测试:Selenium, LTP (Linux Test Project)

性能测试:lmbench, Sysbench, Iperf, Fio

测试框架:JUnit, Autotest

测试设计:Xmind, StarUML, UML Designer

安全测试:Metasploit, Nessus, AppScan


在新的开源测试工具不断涌现的同时,很多曾经优秀的开源测试工具因为缺少必要的维护而无法持续进行新功能的添加和已有功能的增强与维护。Lmbench是一款优秀的linux性能测试工具,可以获取系统CPU、内存、磁盘、网络等资源的带宽和延时的性能数据。近年来由于缺少必要的官方维护,没有新功能添加,该工具在行业内的影响力在逐步下降。另一个例子是Rth,其是一款优秀的测试需求管理、测试过程跟踪的测试工具,由于多年来缺少必要的维护,该工具已经无法满足当前项目的需求,逐步淡出了大家的视野。早先原本使用该工具的程序员,不得不将目光转移到其他工具中,而熟悉新的工具需要额外的时间投入,增大了项目运作的成本。


2.当前开源社区测试能力的短板

本章我们以Kernel和Docker社区为例展示当前主流开源社区的质量保证中有待改进的方面。


2.1.Kernel开源社区

Linux kernel是迄今为止最为成功的开源社区,有很多一流的公司和程序员参与其中,平均每月的代码补丁合入量在一千以上,社区的代码量在千万行的数量级。面对如此庞大的代码量,做好质量保障工作是一个严峻的挑战。而目前社区没有精准测试方案,修改一行开发代码时不得不运行全量的测试用例才能充分保证质量。


操作系统运行分为内核态和用户态。当前内核态的测试用例和功能代码存放在一个Git仓库中,代码路径在kernel/tools/testing/selftests中。而用户态的测试用例与开发代码相对独立,单独存放在Ltp开源社区中。


Kernel社区采用的是迭代式开发。不幸的是,很多开发者在提交完功能代码后并没有同时添加文档和对应的测试用例。而社区也没有一种有效的机制保证文档和测试用例得到及时的更新。文档的输出相对滞后,使得很多内核的特性难以理解,很多时候其他程序员不得不通过阅读源码来推测该代码所实现的功能。而测试用例的滞后输出更为明显,很多内核特性在功能代码合入后的几个月甚至一年以上的时间都没有对应的测试用例。以user namespace内核特性为例,其是在2013年2月18日随内核3.8版本正式发布的,然而直到2015年5月21日,社区才拥有第一个该特性的测试用例。二者时间间隔在两年以上,也就是说,在这两年中使用该内核版本的用户都无法获取到有效的测试用例来验证该特性,版本的质量保证令人堪忧。社区中有很多类似的待测点,需要大家参与社区来补充必要的测试用例。


另外Kernel还维护着LTS的长期稳定版本,即在某一个特定的Kernel版本中不添加新的功能,只修改已有的软件缺陷。据笔者所知,因为测试资源的缺乏,在LTS版本发布前,并不是每个版本都进行源码编译、全量测试执行等测试工作。很多时候验证工作往往只包含源码编译和OS启动冒烟测试。这很可能导致大量软件缺陷遗漏到下游开发者手中。


2.2.Docker开源社区

Docker是当前流行的云计算开源工具,其社区也吸引了大量的开发者参与社区贡献。Docker社区采用的是测试驱动开发的策略,即在开发者提交功能代码时需要同时提交对应的测试代码和进行文档的修改。这种开发方式很大程度上解决了文档和测试用例滞后的问题。然而,Docker社区中并没有专职的测试者,测试用例几乎都是开发者提供的,他们更关注开发代码的质量,对于测试代码的质量就显得有点“漠不关心”了。用例在设计过程中往往缺少测试思维,使得输出的测试用例缺少边界异常点检查。开发者输出的用例几乎都是单点的功能验证,无法覆盖全面的代码路径,更缺少一些专项测试(性能测试、压力测试、长稳测试、安全测试等)。


很多开发者通常是为了应对测试驱动开发的策略被动的添加测试用例,很多重要的特性只使用有限的用例来进行验证。这很难保证软件发布后的质量。在近期发布的Docker1.12版本中,就出现了软件稳定性差的问题,引发了很多争论,社区又不得不亡羊补牢。


3.专业测试人员参与开源社区贡献的必要性

从心理学的角度来看,开发者不愿意看到自己编写的代码存在缺陷,也就没有足够的动力去发现软件缺陷。在版本发布临近、任务紧急的情况下,当开发者本人发现了自己编码中的缺陷,而解决该缺陷又需要大量时间并且自己不得不加班时,开发者有两种方式应对。第一种是积极的投入时间,加班加点把问题解决掉来确保版本发布的质量;另一种是保持沉默,默默的祈祷其他人不要发现这个缺陷。经过调查,绝大部分人会选择第二种方式,因为人性即如此,我们做任何事的时候都不要去轻易的挑战人性。而查找软件缺陷是测试者的本职工作,他们会尽最大可能的发现软件缺陷。一旦缺陷被发现,测试者绝不会保持沉默,这有助于最大限度的暴露软件缺陷。 除此之外,开发者设计的用例往往只限定在单元测试中,而集成测试、系统测试、验收测试往往需要测试者的参与。一些专项测试(性能测试、压力测试、长稳测试、安全测试等)也是测试者所擅长的,他们会站在用户的角度上思考软件的可用性、用户体验等方面的内容。


4.测试工程师参与开源社区的方式

(1)添加测试用例

测试用例的编写是测试工程师的本职工作。很多开源社区非常愿意吸收新的测试用例。在Docker社区中,相比于开发代码,测试代码更易于被社区接收。

(2)书写或补充文档

很多社区都因为缺少必要的文档,导致用户无法正确使用软件。开发者书写的文档往往会出现跳步和不准确的情况,需要测试者对文档的书写进行校正。

(3)修改软件缺陷或添加新功能

测试者也可以修复软件缺陷和添加测试所需的新功能,这包含一些可测试性的功能开发。

(4)测试待发布版本

测试待发布的版本来保证软件发布质量,这是测试者最重要的工作职责。

(5)补充专项测试方案

补充一些专项测试(性能测试、压力测试、长稳测试、安全测试等)来完善质量保证体系。

(6)提交软件缺陷和回答社区中的问题

社区往往会通过issue列表或邮件对已有问题进行讨论,测试可以提交缺陷或者回答其他人的提问来与社区进行互动。

(7)设计开源测试工具

测试工具往往存在于某个独立的开源项目中,参与这类社区的人中测试者居多。


5.新人参与开源社区的步骤

对于未曾参与过开源社区的新人,我们以向某个开源项目提交测试用例为例介绍参与开源社区的步骤。

首先,你需要熟悉开源代码维护工具,如Git。掌握代码下载、提交、分支创建的命令。之后要熟悉被测软件的功能,开始时可以以用户的方式来使用开源软件,掌握软件的使用方法。然后进一步熟悉软件的架构、实现原理、功能函数。再之后的任务是对社区已有的测试用例进行源码阅读,熟悉其测试的功能,寻找到已有测试用例中未覆盖到的软件功能点。针对这些功能点,就可以提交对应的测试用例。


不同的社区接收代码贡献的方式有所不同,Docker社区是通过pull request的方式接收新代码的,而Kernel社区则是以mail list的方式接收新代码。社区通常会有参与社区的引导文档来引导贡献者,读者在提交代码前可先阅读此类文档。


总结

贡献开源社区的方式有很多,读者可以根据自己的兴趣有针对性的投入到社区的贡献中。随着越来越多的人投入到社区贡献中,相信开源社区的质量保证必将拥有一个质的飞跃。


作者简介

孙远,资深工程师,就职于华为2012实验室中央软件院欧拉八部,硕士毕业,9年软件行业经验。目前在华为从事容器Docker项目的测试工作。工作涉及到功能测试、性能测试、压力测试、稳定性测试、安全测试、测试管理、工程能力构建等内容。参与编写了《Docker进阶与实战》的Docker测试章节。先前曾经就职于美国风河系统公司,作为team leader从事风河Linux产品测试工作。活跃于Docker社区和内核测试ltp社区,目前有大量测试用例被开源社区接收。

研究方向:容器技术、Docker、软件测试、自动化测试、测试过程改进


该文章已被51testing收录。

下一篇:无