每次做测试架构师,会面临测试工具的问题。尤其是在System Verification部门,他们的case是在仿真用户对产品的使用,产品的功能不断添加,但是用户的行为却是可遵循的,而且是复杂的,是各种行为的组合。不断地重复测试,似乎是在浪费测试人员的时间。在这种情况下,自动化测试工具成为提高测试效率,解放测试人员的法宝。
  如何开发测试工具,有很多需要注意的地方。
  记得我刚去WiMax部门做测试架构师的时候,WiMax功能测试组需要软件组帮他们做一个截获正常报文,产生错误报文的工具。我和测试人员交流的时候,测试人员说这个工具很不好用。我再去询问软件人员,他们很惊讶。说已经完全按照需求实现了功能,该做的都做了,怎么不肯用呢?我具体看了看他们的实现,发现基本功能确实都实现了,可是确实没办法用。测试人员不仅仅需要这个软件实现截获和修改报文的功能,更需要在实际的测试过程中灵活地使用它来实现整体的测试。软件人员没有做过测试,无法正确地理解测试人员的需要,再加上两个部门一个在15楼,一个在16楼,交流很不通畅,才造成彼此无法理解,做不出真正需要的东西。我和软件人员坐在一起,仔细地告诉他们我需要怎样来用这个工具,需要他们提供什么样的接口,测试人员该如何接入和管理这个软件,哪些配置要图形化,哪些配置要被自动化工具调用,需要什么样的输出,哪些状态实时显示,哪些数据需要统计,哪些log需要输出到统一的log文档中,等等。他们才恍然大悟,原来截获和修改报文只是很基本的需求,还有那么多事情要做。
  所以,开发测试工具,理想的情况是找一个既精通开发,又精通测试的人来做。但这样的人比较难找。更普遍的办法是让软件人员和测试人员紧密合作,互相理解,才能够真正完成可用好用的产品。
  在我看来,一个好的自动化测试工具,需要注意以下特点:
  第一,必须将数据、配置和功能分开
  第二,尽量使用已有的稳定的公开库
  第三,使用c,java还是tcl,python,各有利弊
  第四,封装基本功能,提供调用接口,用于测试人员的二次开发
  第五,尽量采用统一的可直接编辑的格式用于记录数据、配置和log
  第六,不要求大求全,也不要采用过于复杂和灵活的测试框架,要有针对性,简单为上
  第七,图形界面友好,符合测试人员的使用习惯
  第八,注重系统效率,要采用多进程以利用多核CPU
  第九,提供测试结果采集、统计和log分析页面
  第十,要考虑如何容纳已有的测试case
  我们曾经使用过Mobile Metrics的测试套件,据说这个公司只有9个人在开发和维护这个产品,但这个测试套件功能强大,比一般大公司100个人做出来的东西还要好,是我们学习的楷模。这个套件是用c和java写的,底层调用和报文处理都是c,以提高系统性能。用户界面都是java,非常友好。提供了众多的接口调用,封装粒度合理,测试人员可以用非常简单的java语言实现非常复杂的测试行为,如入网、退网、handover等等。提供标准的java调用,让测试人员方便地使用其他标准功能,如产生随机数,条件语句,循环语句,网络连接,文件读写,报文分析等等。
  还有Spirent的自动化测试套件,这个套件在使用界面上非常友好,配置和执行测试都很方便。我们曾经仿照它的模式来管理自己的测试case。但它不够开放,要想在上面做2次开发不是很容易,需要请Spirent专门派人来协助和培训。Spirent的测试套都是用Tcl写的,我们觉得Tcl在开发大型测试软件的时候有点难度,出了错很难查错,开发环境不够友好,不如c和java方便。Python近几年发展比Tcl快,可以调用的库很多,开发环境也友好一些了。但Tcl和Python的效率都要差一些。我们自己写的测试管理工具还兼容了原先大量使用的内部测试工具,可直接运行原来的case,只是将测试结果和log记录下来。这样不需要重写了。
  我们曾经研究过泰克的测试工具。泰克的图形化做得是面面俱到的,连设计一个测试流程,也只需要用鼠标拉来拉去,这样其实很限制灵活性,只能按照它所设定的模式来设计测试,二次开发很难。它的配置和数据也都是用自有的格式存储的,必须用它的工具来打开和修改。我个人不大喜欢这样的测试工具。
  我们公司内部也有一些自动化测试的工具,有些是自己开发的,有些是外包的。我也不大喜欢这些工具,因为功能很弱,图形化差,不灵活,也不能与时俱进。这些代码都是从头开始写的,比起外面那些开源代码和公开库,无论是质量还是数量,都差远了。
  顺便说说开发测试工具的流程。
  要开发一个测试工具,首先是要了解测试人员的需求。需求包括测试功能本身的需求,和如何使用工具的需求。
  然后是定义模块和接口。模块包括功能模块和输入输出模块。功能模块由上及下逐步细分,分到多细取决于功能的复杂程度和接口的数量。每个模块要尽量独立,减少彼此的依赖。画几个数据流程图,看看需要哪些接口,接口参数如何定义。定义接口的时候要考虑到扩展性。当然,扩展性和简单化,有的时候要进行取舍。我们没必要面面俱到,但至少要考虑近期的扩展需求。查找已有的库函数,尽量减少自己开发的工作量,尽量采用一些标准做法。输入输出模块要和测试人员一起沟通,给测试人员尽量多的调用接口以实现复杂的测试行为。输入输出模块往往是一个测试工具成败的关键,这常常是软件人员容易忽视的。如果是性能测试工具,必须要考虑硬件的承受能力。如果能够做到分布运行,那当然是好的了。
  测试工具的开发过程好是和测试人员pair-work的,让测试人员不断地使用工具以获得反馈。测试人员是测试工具的用户,来自用户的声音永远是重要的。自动化的程度是可以协商的,测试结果分析自动化往往是吃力不讨好的,自动化应该偏重于配置、执行和管理。出错处理是需要很小心的,尽量不要测试一出错停止测试,这个要让测试人员来权衡。
  其实测试工具的开发和普通的软件开发没有太多的区别,这么蜻蜓点水一下,似乎没有多大的帮助。只是很多公司都在面临如何开发和使用自有测试工具的问题,我也顺嘴谈一谈。