什么是测试漏斗?

今天介绍我的一个开源工具: 测试漏斗(Test Funnel),Github 地址: https://github.com/slxiao/test-funnel。它是面向 Javascript 的测试选择器,可以根据代码改动情况,从测试集中动态选择 (过滤) 与代码改动有依赖的测试子集来执行,从而提高测试的针对性和效率,应用于持续开发和持续集成领域。

例如,一个 Javascript 项目有 200 个源文件,1000 个测试用例。如果开发者某次代码提交只修改了 2 个源文件,那么是大概率没有必要去执行全部 1000 个用例的,而很有可能只需要执行某几个或某十几个用例。

测试漏斗的特点

面向 Javascript 的这款测试漏斗,其特点有:

  1. 支持 Mocha 和 Jest 两种测试框架,

  2. 支持 CommonJS,AMD,ES6 等多种语法,

  3. 提供 API 和 CLI 两种调用方式,

  4. 支持一键完成测试发现,测试选择和测试执行工作。

测试漏斗的用法

安装命令为:

npm install -g test-funnel

测试漏斗的基本工作方式如下。首先,根据输入的用于对比的新旧版本号,计算发生改动的源代码文件列表。然后,根据输入的测试路径和测试文件名后缀,得到全部测试文件,并根据文件依赖关系算法,计算每个测试文件所直接和间接依赖的源文件列表。

最后,以依赖源文件是否发生改动为标准,来选择测试文件,并根据是否指定测试执行模块,来决定是返回选择结果,还是接着执行被选择的测试文件。

测试漏斗的 CLI 调用方式为:

Usage: test-funnel [options]
  #版本号
  -V, --version 
  #Git项目路径,默认为.                  
  -b, --basefolder <path>    
  #测试路径,默认为./test     
  -t, --testfolder <path>      
  #测试文件扩展名,默认为test.js   
  -e, --testfileextention <name>  
  #新提交的版本号,默认为HEAD~0
  -n, --newcommit <name>
  #旧提交的版本号,默认为HEAD~1    
  -o, --oldcommit <name>   
  #测试执行模块,可选为空/jest/mocha,
  #默认为空,即不执行测试      
  -r, --runner <name>   
  #帮助          
  -h, --help                   

测试漏斗的 API 调用方式如下:

var Funnel = require('test-funnel');

Funnel ({
    baseFolder: "./",
    testFolder: "test",
    testFileExtention: "test.js",
    newCommit: "HEAD~0",
    oldCommit: "HEAD~1",
    runner: ""
});

测试漏斗例子

一个测试漏斗使用示例如下:

......
compared versions: HEAD~0 HEAD~7
git changed files are: .npmignore,README.md,bin/cli.js,lib/api.js,lib/select.js,lib/util.js,package-lock.json,package.json
selected tests are: [ 'test/api.util.test.js' ] 
jest is used as test runner
start to run tests, command: jest --rootDir=test --testPathPattern=test/api.util.test.js
stdout:
stderr: PASS test/api.util.test.js
  ✓ Parse int variable should be ok (4ms)
  ......

Test Suites: 1 passed, 1 total
Tests:       6 passed, 6 total
Snapshots:   0 total
Time:        1.296s
Ran all test suites matching /test\/api.util.test.js/i.

done

测试漏斗的原理

从原理角度看,测试漏斗最核心的模块是文件依赖关系算法。这里使用了第三方库 Madge。针对一个 JS 文件,它采用与 babel 编译器相同的方式,生成抽象语法树(AST)。然后遍历 AST,基于模块导入关键字 (例如 import, require 等),得到直接依赖模块。接着采用递归方式,得到一级又一级的间接依赖模块。最后综合每步结果,就可以得到一个文件的全部依赖模块 (文件)。

下一步计划

目前,测试漏斗还有一些地方需要改进。例如,当前它只能处理 JS 文件的依赖性,下一步考虑支持 JSON,html 等文件的依赖关系。另外,测试漏斗还只支持单元测试和模块测试等白盒测试,针对 Javascript 黑盒测试的测试选择算法还需深入研究。

想要深入了解测试漏斗,可以点击https://github.com/slxiao/test-funnel跳转到 Github 项目主页。如果您对测试漏斗有任何想法和建议,欢迎在文末留言或在 Github 上报 issue。

我是肖哥 shelwin,一个高质量软件工程实践者和推动者。欢迎添加我的个人公众号测试不将就或关注同名博客,获得更多自动化测试, 持续集成, 测试开发,软件工程实践, Python 编程等领域的精彩原创文章。


↙↙↙阅读原文可查看相关链接,并与作者交流