测试的目的是为了识别一个产品中的问题和缺陷。而许多测试以能通过/通不过(pass/fail)所必须的度量数据的重要分析,来了解系统在测试时的情况。敏捷软件开发允许通过不断变更和动态的特性集合来完成特性的快速验证。当前的数据分析方法主要依赖于采用编译型或解析型编程语言(Perl、Python 等等)编写的静态脚本。虽然由于动态语言自身的快速开发周期,使用它们可以极大地促进分析过程,但与测试密切相关的个体人员在工作时往往无法得到进行必要修改所需的分析软件源代码或技能集合。
敏捷世界中的静态分析
测试团队通过对开发过程中的软件运行测试来识别问题。在传统瀑布式过程中,功能性需求会事先被知道,并按计划进行技术实现。敏捷开发则允许一个应用程序的功能可以随时变更来满足客户不断变更的需求。为了满足这些新的动态测试需求,新的测试方法学如雨后春笋般地涌现出来。测试及行为驱动开发方法学(Test and behavior-driven development methodologies)被发展出来支持这些短小的开发周期,并且使用新的动态和声明式环境配置工具,例如 Puppet 及 Chef 被用于快速部署和配置部署环境。
但关于非功能性需求的调查研究又怎样呢?功能性测试的天性就是“通过/失败”:特定的功能被正确实现了,或者没有被正确实现。
许多需求与生俱来就是非功能性的,成功或失败并不是简单地看是否能通得过一个功能性需求来判定的。加载和压力测试、性能测试及承载力判定是部分测试类型的示例,这些测试并不完全是二元性的,而是需要积极的调研和分析来确定一个应用程序是否满足非功能性需求。
当前的数据分析方法主要依赖于采用编译型或解析型编程语言编写的静态脚本(如 Perl、Python、Ruby,等等)。对于需要在大型静态系统或缓慢变化的代码基(codebase)上多次运行的分析来说,在开发分析工具和软件方面的投资是合理的,例如,因为这些工具会在很长一段时间里很有用,并可以帮助识别性能或稳定性问题的根本原因。然而对于一个快速的变更可能会同时发生在内容和容量上的代码基来说,花费在开发定制化分析工具上的时间通常会白白被浪费掉,因为测试团队在不断地追赶一个变动的目标。
虽然由于动态语言的快速开发周期,使得使用动态语言可以极大地促进分析过程,但当应用程序发生变更时,与测试密切相关的个体人员在工作时往往无法得到分析软件的源代码或所必需的技能集合。
在本文中,我描述了敏捷数据分析(agile data analysis)技术及工具,可以助力测试员及其他度量数据消费者采用适应性更强的方式解析结果。这些工具和技术使得数据分析更加具有交互性,并能最小化对持续脚本重写的需要。
为什么需要敏捷数据分析?
非功能性测试(Non-functional test)需要对被度量的系统有一个深入的理解,因为成功或失败这两种测试结果必须满足由系统操作特性所定义的条件才可以得到。缓慢的响应时间,服务器集群非线性的规模变动,过度的内存消耗(垃圾收集)或过度的网络通信量,等等例子都是在一个运行系统中可能被发现的不受欢迎的系统行为。要查找这些指示信号产生的最初始原因,需要对系统如何运作有一个更深入的理解。
我们执行数据分析来从运行系统中所获得的多个数据源头抽取信息,以便使这些不受欢迎的行为初始的触发原因得以被发现。对于已经建立,拥有固定需求集的产品,分析工具可以被编写为对多重数据来源进行关联,以使系统的健康状况得以被监控。但在敏捷开发中,由于代码基(codebase)要不断响应来自功能性需求或用户接口的变更,所以正在被开发的程序或系统在一次又一次的构建过程里也可能会发生动态的变更。这些用于解析所有数据来源的工具集同样需要变得敏捷。
但这对于需要敏捷化的工具集来说,其含义是什么?敏捷工具集的经典例子是 UNIX/Linux 自带的工具及设施。每一个工具可以执行一个狭窄定义的任务,而且这些任务可以串联在一起运用,使得无论是通过命令行或是 shell 脚本都可以用来执行无限可能甚至无法复制的任务,即便每一个任务都要求一个专门的应用程序。只需要了解如何组合它们的功能来解决特定的问题即可。因此,对于敏捷数据分析来说,首要的需求就是可组合能力(composability)。
敏捷数据格式
可组合能力的例子包括 UNIX 自带工具,可以在这些不同的工具之间传递文本文件。Microsoft 的 PowerShell 工具也同样是可组合的,但它传递的是操作系统能识别的 PowerShell 对象实例。那么在敏捷数据分析系统不同的组件之间应当传递什么类型的数据格式呢?
从运行系统中获得的数据可能源自多个不同的出处,具有多种不同的格式。一些例子包括:
非结构化日志文件(Unstructured log files)结构化日志文件(Structured log files)系统环境数据(System environment data)
CPU 占用百分比(Percentage of CPU that is busy)内存使用情况( Memory consumed)磁盘 I/O(Disk I/O)度量数据(Measured data)
数据表(Spreadsheets)基于 HTML 的报告(HTML-based reports)这些就是为了进行任意种类的数据分析,需要对数据来源进行语法分析和解析的例子。挑战是精简所有这些具有不同数据格式的数据,使之成为一个能在多种不同类型数据之间进行比较的形式。
举一个例子,假设一个加载测试(load test)要在一个服务器产品上进行,使用一个工具用于模拟多种不同浏览器用户。有多个开源和商业工具可以执行类似的加载度量。该工具为您提供每一个服务器访问申请的响应时间,而您想要了解何时服务器响应时间会超过一个特定的限定值。响应时间可以由于多种原因导致增加:并发用户的数量、过量内存消耗会导致的垃圾收集延迟、网络饱和,等等。
为了确定相应时间延迟的原因,检验以前面所提到的多种格式呈现的数据:来自操作系统、来自被测试的服务器,以及来自加载测试工具的数据。
可以尝试将数据格式进行标准化,例如采用 XML 或 JSON(通常用于产生自浏览器的数据)。XML 格式,由于高度格式化所以相对比较容易进行分析,但仍然需要明显的工作量来将文件中的数据都转化成为一个可以被其他工具进行解析的形式,或与其他非 XML 内容进行比较。可以被广泛支持的最简单的数据格式是矩阵表格;表格的每一行包含了一组关联唯一数据实例的属性。例如,对于加载度量,表格中每一行可以展现在测试过程中某一个特定时间点的相关数据。表格数据以例如逗号分隔值(comma separated value,CSV)磁盘格式直接输出到数据表和数据库。
分析师或程序员?
当软件应用程序变得更大更复杂时,自动化测试也就成为必需的了。甚至对于那些精于构建目的用于确定特定软件系统质量和健壮性的自动化复杂场景的专家来说,他们对于被测试软件的内部其实很可能是毫无了解的。这种黑盒测试(black box testing)并不需要编程,但可能对测试场景进行定义是个例外。
非功能测试可以同时被某一自动化测试集(test suite)所驱动,但测试结果无法按黑盒测试的方式来处理。如果我们的数据分析需要变得敏捷,会很少需要解析自动化非功能性度量数据的结果,或者根本无需编程,而只需要一个工具来组合及关联多个数据来源。
与编程相比,数据分析是一个不同的技能集,需要对被测试程序的架构以及从程序的多个组件或部署环境获得的其他诊断信息有更深入的了解。取决于所获得的数据的多少以及其复杂性,数据挖掘和静态分析技术对于解析数据来判断非功能性缺陷的源头来说是必须的。
为了使毫无编程技能的测试员及分析师能对一个不断演进的软件应用程序所产生的自动化度量数据进行分析成为可能,我们的敏捷分析工具应当是需要越少的编程就越有用。
对敏捷数据分析需求的小结
总的来说,对于敏捷软件项目执行灵活的数据分析,工具应当满足以下三个主要条件:
功能应当可以使用已有的功能组件进行组合而成(Functionality must be composable using existing functional components)在组件之间交换的数据应当以表格的形式展现给用户(Data exchange between components must appear to the user as a table)组件的组合方式应当可以只需要尽可能少的编程便可以完成(Composition of components should be done with a minimum of programming required)已有的分析工具,例如数据挖掘和业务分析工具集,满足这些需求。这些工具集意味着可以对非程序员提供开箱即用的数据挖掘和分析能力。
IBM SPSS Modeler 拥有非常理想的静态建模能力,可以用于分析大规模复杂数据集。在合适胜任执行软件应用程序数据分析的同时,它对于拥有复杂静态分析需求的大数据集来说也是有用的。
可用于更加适度分析任务的开源产品,可能更合适用于本文所描述的敏捷数据分析类型。一个更加流行的可获得的开源工具名叫 KNIME(查看参考资料中的链接)。
KNIME (the Konstanz Information Miner)
KNIME 是一个基于 Eclipse 框架,开发始于 2006 年,用于执行制药行业数据分析的工具。从那时起,它演进成为一个通用目的的数据分析、报表及集成平台。它是用于执行调查采用敏捷方法开发的软件非功能性能力最理想的基础数据分析平台。它满足前面所述的需求,通过使用图形化展示的工作流,使工作流的节点间以箭头彼此互相链接,来指示数据流向的方向。
通过连线这些节点在一起,您便可以实现数据分析任务,而只需要很少甚至完全不需要编程。所有分布在这些节点上的分析逻辑,可以用于消费来自外部的数据源(通过“reader”节点);转换内在数据;或组合其他数据来源。在每一个节点上,所操控数据的当前状态可以以一个数据表样式的显示形式进行检视,因此您可以验证数据是否针对特定分析任务被正确转换了。
图1. KNIME 桌面版示例
结论
在本系列下一篇文章中,将会展示构建一个简单工作流所需的步骤,如何导入数据到工作流中,以及如何执行通常用于分析基于时间的数据所需的逻辑。