1.1.4 • Published 4 years ago

devops-web-test v1.1.4

Weekly downloads
3
License
MIT
Repository
github
Last release
4 years ago

devops-web-test

定制流水线式执行web自动化测试的工具。

推荐的目录结构

不同插件的默认值是按照如下目录结构来设置默认值的,也是我们推荐的目录结构。

  • project_path
    • DevOps
      • devops-app (用于DevOps执行自动化测试和输出测试产物)
      • matman-app (端对端测试)
      • mockstar-app (数据打桩)
      • README.md
    • src (项目源码)
    • test (测试用例)
    • package.json

接口文档

start(dwtPath, config)

启动自动化测试。

  • dwtPathStringDWT(DevOps for Web Test) 目录,流水线式执行web自动化测试和输出测试产物的路径,如果插件传入了相对路径,则是相对于该路径而言
  • configObject,配置参数
    • config.workspacePathString,工作区间的路径,即项目的根目录,如果是 git 项目,则是 git 仓库的根目录
    • config.outputPathString,测试产物输出目录,默认为 path.join(dwtPath, 'output')
    • config.pluginsArray,插件列表,启动测试之后,会依次执行插件的生命周期事件(init - > beforeRun - > run - > afterRun)

BasePlugin

插件的基础类,所有的插件需要继承它。启动测试之后,会依次执行插件的生命周期事件(init - > beforeRun - > run - > afterRun)。

constructor(name, opts)

  • nameString,插件的名字
  • optsObject,插件的配置,不同插件可能有不同的区别
    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当其为函数时,会传入参数 testRecorder

async init(testRecord)

初始化插件

async beforeRun(testRecord)

运行自动化测试之前执行

async run(testRecord)

运行自动化测试

async afterRun(testRecord)

运行自动化测试之后执行

shouldRun(testRecord)

判断是否应该运行该插件

PluginProject

工程项目插件,即我们原始的工程,自动化测试时,我们可能需要安装依赖和构建等操作。

constructor(name, opts)

  • nameString,插件的名字,默认值为 pluginProject
  • optsObject,插件的配置,不同插件可能有不同的区别
    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当为函数时,接受 testRecord 参数
    • opts.rootPathString,项目根路径,默认值:由于我们推荐 DWT 路径为 DevOps/devops-app ,因此默认值为 path.join(dwtPath, '../../')
    • opts.usePortBoolean,是否需要端口,有些开发场景时,启动项目会使用一个端口,例如 webpack 构建项目时使用热更新模式下,就需要一个端口,默认值:false
    • opts.portNumber,端口号,如果设置了 opts.usePorttrue,若没有传入,则会自动找到未被占用的端口
    • opts.installCmdString|Function,安装依赖时执行的命令,当其为函数时,会传入参数 testRecorder,默认值为 function (testRecord) { return 'npm install'; }
    • opts.buildCmdString|Function,构建项目时执行的命令,当其为函数时,会传入参数 testRecorderport ,默认值为 function (testRecord, port) { return 'npm start'; }
    • opts.buildCompleteCheckFunction,检查构建是否完成,会传入参数 data ,代表的时控制台输出,在某些场景下,可以通过判断某些输出,来判断构建已经结束,如果返回 true,则将强制结束构建,默认值为 function (data) { return false; }

async init(testRecord)

初始化插件,需要处理的事情包括:

  • rootPath 修改为绝对路径

async beforeRun(testRecord)

运行自动化测试之前执行,需要处理的事情包括:

await this.clean(testRecord);

async run(testRecord)

运行自动化测试,需要处理的事情包括:

// 进入项目中安装依赖
await this.install(testRecord);

// 获取 project 的端口号
await this.findPort(testRecord);

// 构建项目
await this.build(testRecord);

async afterRun(testRecord)

运行自动化测试之后执行,需要处理的事情包括:

await this.clean(testRecord);

async install(testRecord)

安装依赖,执行 this.installCmd 命令

async build(testRecord)

构建项目,执行 this.buildCmd 命令

async clean(testRecord)

清理,需要处理的事情包括:

  • 清理端口号 port,避免该端口号被占用

async findPort(testRecord)

获得可用的端口号,并存储在 this.port

PluginUnitTest

单元测试项目插件。

constructor(name, opts)

  • nameString,插件的名字,默认值为 pluginUnitTest
  • optsObject,插件的配置,不同插件可能有不同的区别
    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当为函数时,接受 testRecord 参数
    • opts.runTestPathString,执行单元测试的根路径,默认值:由于我们推荐 DWT 路径为 DevOps/devops-app ,因此默认值为 path.join(dwtPath, '../../')
    • opts.outputPathString,单元测试结果输出的路径,默认值:path.join(testRecord.outputPath, 'unit_test_report')
    • opts.coverageOutputPathString,单元测试的覆盖率输出的路径,推荐放在单元测试结果输出文件夹内,默认值:path.join(this.outputPath, 'coverage')
    • opts.testCmdString|Function,执行测试的命令,当其为函数时,会传入参数 testRecorder,默认值为 function (testRecord) { return 'npm test'; }
    • opts.coverageCmdString|Function,执行测试的命令,当其为函数时,会传入参数 testRecordertestCmdToExecute(实际执行的测试的命令),默认值为 function (testRecord, testCmdToExecute) { return 'npm run coverage'; }
    • opts.onBeforeTestFunction,在运行测试之前执行的钩子函数,会传入参数 testRecorderutil
    • opts.testCompleteCheckFunction,检查测试过程是否完成,会传入参数 data ,代表的时控制台输出,在某些场景下,可以通过判断某些输出,来判断构建已经结束,如果返回 true,则将强制结束构建,默认值为 function (data) { return false; }
    • opts.coverageCompleteCheckFunction,检查覆盖率是否完成,会传入参数 testRecorder ,由于生成覆盖率文件是异步的,某些时候需要实际去检查所需要的覆盖率文件是否实际已经完成,此时可以用该方法

async init(testRecord)

初始化插件,需要处理的事情包括:

  • runTestPath 修改为绝对路径
  • outputPath 修改为绝对路径
  • coverageOutputPath 修改为绝对路径

async beforeRun(testRecord)

运行自动化测试之前执行,暂无。

async run(testRecord)

运行自动化测试,需要处理的事情包括:

// 在运行测试之前执行的钩子函数
if (typeof this.onBeforeTest === 'function') {
    await Promise.resolve(this.onBeforeTest.call(this, testRecord, util));
}

// 启动测试
await this.runTest(testRecord);

// 获取单元测试覆盖率
await this.runCoverage(testRecord);

async afterRun(testRecord)

运行自动化测试之后执行,暂无。

async runTest(testRecord)

启动测试,执行 this.testCmd 命令

async runCoverage(testRecord)

构建项目,执行 this.coverageCmd 命令

PluginMockstar

mockstar 项目插件。

constructor(name, opts)

  • nameString,插件的名字,默认值为 pluginMockstar
  • optsObject,插件的配置,不同插件可能有不同的区别
    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当为函数时,接受 testRecord 参数
    • opts.rootPathString,项目根路径,默认值:由于我们推荐 DWT 路径为 DevOps/devops-app ,因此默认值为 path.join(dwtPath, '../mockstar-app')
    • opts.portNumber, mockstar 启动端口
    • opts.installCmdString|Function,安装依赖时执行的命令,当其为函数时,会传入参数 testRecorder,默认值为 function (testRecord) { return 'npm install'; }
    • opts.startCmdString|Function,安装依赖时执行的命令,当其为函数时,会传入参数 testRecorderport,默认值为 function (testRecord, port) { return 'npm install'; }

async init(testRecord)

初始化插件,需要处理的事情包括:

  • rootPath 修改为绝对路径
  • 自动生成唯一标识 this._processKey

async beforeRun(testRecord)

运行自动化测试之前执行:

await this.clean(testRecord);

async run(testRecord)

运行自动化测试,需要处理的事情包括:

// 进入项目中安装依赖
await this.install(testRecord);

// 获取 mockstar 的端口号
await this.findPort(testRecord);

// 启动 mockstar
await this.start(testRecord);

async afterRun(testRecord)

运行自动化测试之后执行:

await this.clean(testRecord);

async clean(testRecord)

清理,需要处理的事情包括:

  • 清理端口号 port,避免该端口号被占用

async findPort(testRecord)

获得可用的端口号,并存储在 this.port

async install(testRecord)

安装依赖,执行 this.installCmd 命令

async start(testRecord)

构建项目,执行 this.startCmd 命令

PluginWhistle

mockstar 项目插件。

constructor(name, opts)

  • nameString,插件的名字,默认值为 pluginWhistle
  • optsObject,插件的配置,不同插件可能有不同的区别
    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当为函数时,接受 testRecord 参数
    • opts.portNumber, whistle 启动端口
    • opts.getWhistleRulesFunction,获得 whistle 规则,需要返回格式为 {name: String, rules: String}
    • opts.configFileNameString,whistle 规则配置文件名,文件中包含了规则信息等,默认值为 test.whistle.js
    • opts.configFileString,whistle 规则配置文件路径,默认值为 path.join(testRecord.outputPath, this.configFileName)

async init(testRecord)

初始化插件,需要处理的事情包括:

  • configFile 修改为绝对路径
  • 自动生成唯一标识 this._processKey

async beforeRun(testRecord)

运行自动化测试之前执行:

await this.clean(testRecord);

async run(testRecord)

运行自动化测试,需要处理的事情包括:

// 获取 whistle 的端口号
await this.findPort(testRecord);

// 生成 .whistle.js 配置文件
await this.generateConfigFile(testRecord);

// 启动 whislte
await this.start(testRecord);

// 设置并强制使用指定 whistle 配置规则
await this.use(testRecord);

async afterRun(testRecord)

运行自动化测试之后执行:

await this.clean(testRecord);

async generateConfigFile(testRecord)

根据 this.getWhistleRules 获得的代理规则,生成一个本地的 whistle 配置文件。

async clean(testRecord)

清理,需要处理的事情包括:

  • 清理端口号 port,避免该端口号被占用

async findPort(testRecord)

获得可用的端口号,并存储在 this.port

async start(testRecord)

启动 whistle,启动命令格式为 w2 start -S ${this._processKey} -p ${this.port}

async use(testRecord)

使用指定的 whistle 规则配置文件,启动命令格式为 w2 use ${this.configFile} -S ${this._processKey} --force

PluginE2ETest

端对端测试项目插件。

constructor(name, opts)

  • nameString,插件的名字,默认值为 pluginE2ETest
  • optsObject,插件的配置,不同插件可能有不同的区别
    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当为函数时,接受 testRecord 参数
    • opts.runTestPathString,执行端对端测试的根路径,默认值:由于我们推荐 DWT 路径为 DevOps/devops-app ,因此默认值为 path.join(dwtPath, '../../')
    • opts.outputPathString,单元测试结果输出的路径,默认值:path.join(testRecord.outputPath, 'e2e_test_report')
    • opts.coverageOutputPathString,单元测试的覆盖率输出的路径,推荐放在单元测试结果输出文件夹内,默认值:path.join(this.outputPath, 'coverage')
    • opts.testCmdString|Function,执行测试的命令,当其为函数时,会传入参数 testRecorderwhistlePort,默认值为 function (testRecord, whistlePort) { return 'npm test'; }
    • opts.onBeforeTestFunction,在运行测试之前执行的钩子函数,会传入参数 testRecorderutil
    • opts.testCompleteCheckFunction,检查测试过程是否完成,会传入参数 data ,代表的时控制台输出,在某些场景下,可以通过判断某些输出,来判断构建已经结束,如果返回 true,则将强制结束构建,默认值为 function (data) { return false; }
    • opts.getWhistlePortFunction,获得 whistle 的端口号,默认值为 function (testRecord) { return 0; }
    • opts.matmanAppPathString,matman 应用的根路径,默认值:由于我们推荐 DWT 路径为 DevOps/devops-app ,因此默认值为 path.join(dwtPath, '../matman')
    • opts.matmanAppInstallCmdString|Function,matman 应用安装依赖时执行的命令,当其为函数时,会传入参数 testRecorder,默认值为 function (testRecord) { return 'npm install'; }
    • opts.matmanAppBuildCmdString|Function,matman 应用构建项目时执行的命令,当其为函数时,会传入参数 testRecorder ,默认值为 function (testRecord,) { return 'npm run build'; }

async init(testRecord)

初始化插件,需要处理的事情包括:

  • runTestPath 修改为绝对路径
  • matmanAppPath 修改为绝对路径
  • outputPath 修改为绝对路径
  • coverageOutputPath 修改为绝对路径

async beforeRun(testRecord)

运行自动化测试之前执行,暂无。

async run(testRecord)

运行自动化测试,需要处理的事情包括:

// matman-app 安装依赖
await this.matmanAppInstall(testRecord);

// 测试之前需要 matman-app 构建
await this.matmanAppBuild(testRecord);

// 启用 xvfb
await this.startXvfb(testRecord);

// 在运行测试之前执行的钩子函数
if (typeof this.onBeforeTest === 'function') {
    await Promise.resolve(this.onBeforeTest.call(this, testRecord, runCmd));
}

// 启动测试
await this.runTest(testRecord);

// 停止 xvfb
await this.stopXvfb(testRecord);

// 处理测试覆盖率
await this.createE2ECoverage(testRecord);

// copy build to output
await this.copyBuildOutputToArchive(testRecord);

async afterRun(testRecord)

运行自动化测试之后执行,暂无。

async startXvfb(testRecord)

启动 xvfb,注意只有在 process.env.USE_XVFB 存在时才会处理

async stopXvfb(testRecord)

关闭 xvfb,注意只有在 process.env.USE_XVFB 存在时才会处理

async matmanAppInstall(testRecord)

启动 matman-app 的安装依赖,执行 this.matmanAppInstallCmd 命令

async matmanAppBuild(testRecord)

启动 matman-app 的构建,执行 this.matmanAppBuildCmd 命令

async runTest(testRecord)

启动测试,执行 this.testCmd 命令

async createE2ECoverage(testRecord)

分析并生成测试覆盖率数据

async copyBuildOutputToArchive(testRecord)

将端对端测试运行结果拷贝到归档目录中

PluginArchive

归档项目插件。

constructor(name, opts)

  • nameString,插件的名字,默认值为 pluginArchive
  • optsObject,插件的配置,不同插件可能有不同的区别

    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当为函数时,接受 testRecord 参数
    • opts.getPluginsFunction,获取插件,接受 testRecord 参数, 返回 { pluginE2ETest: PluginE2ETest, pluginUnitTest: PluginUnitTest, pluginWhistle: PluginWhistle}

其他的属性:

  • this.rootPathString,归档文件夹路径,值为 testRecord.outputPath
  • this.outputZipPathString,归档文件夹路径,值为 path.join(this.rootPath, 'output.zip')
  • this.indexHtmlPathString,归档文件夹路径,值为 path.join(this.rootPath, 'index.html')
  • this.indexHtmlDataPathString,归档文件夹路径,值为 path.join(this.rootPath, 'index-html.json')
  • this.testRecordPathString,归档文件夹路径,值为 path.join(this.rootPath, 'test-record.json')

async init(testRecord)

初始化插件,需要处理的事情包括:

  • rootPath 修改为绝对路径
  • outputZipPath 修改为绝对路径
  • indexHtmlPath 修改为绝对路径
  • indexHtmlDataPath 修改为绝对路径
  • testRecordPath 修改为绝对路径

async beforeRun(testRecord)

运行自动化测试之前执行:

await this.clean(testRecord);

async run(testRecord)

运行自动化测试,需要处理的事情包括:

// 保存自定义报告入口文件
this.saveOutputIndexHtml(testRecord, pluginMap);

// 保存 testRecord 内容
this.saveTestRecordContent(testRecord);

// 压缩下 output 目录
await this.compressDir(testRecord);

async afterRun(testRecord)

运行自动化测试之后执行:

await this.clean(testRecord);

async clean(testRecord)

清理,需要处理的事情包括:

  • 删除上次缓存的文件内容,即清空 this.rootPath 目录

getE2ETestReport(testRecord, pluginE2ETest)

获得端对端测试报告

getUnitTestReport(testRecord, pluginUnitTest)

获得单元测试报告

saveOutputIndexHtml(testRecord, pluginMap)

保存自定义报告入口文件

async saveTestRecordContent(testRecord)

保存 testRecord 内容

async compressDir(testRecord)

压缩保存测试输出文件

PluginCustom

自定义插件。

constructor(name, opts)

  • nameString,插件的名字,默认值为 pluginCustom
  • optsObject,插件的配置,不同插件可能有不同的区别
    • opts.shouldSkipBoolean|Function,是否应该跳过执行,当为函数时,接受 testRecord 参数
    • opts.onInitFunctioninit 方法中的钩子函数,接受 testRecord 参数
    • opts.onBeforeRunFunctionbeforeRun 方法中的钩子函数,接受 testRecord 参数
    • opts.onRunFunctionrun 方法中的钩子函数,接受 testRecord 参数
    • opts.onAfterRunFunctionafterRun 方法中的钩子函数,接受 testRecord 参数

async init(testRecord)

初始化插件,调用 this.onInit

async beforeRun(testRecord)

运行自动化测试之前执行,调用 this.onBeforeRun

async run(testRecord)

运行自动化测试,调用 this.onRun

async afterRun(testRecord)

运行自动化测试之后执行,调用 this.onAfterRun