收银台自动化测试

875 阅读3分钟

一、需求背景

中台业务——收银台项目中,需要接入大量第三方充值渠道。但是由于第三方渠道具有高度的不可控性,且上线某个渠道之后,几乎不再去维护。 所以需要一个自动化测试方案,去保证这些充值渠道的可用性。

二、方案选择

充值流程

完成一个充值流程分为两步:下单支付
支付分为: 有表单+当前页完成支付无表单+跳第三方页面有表单+跳第三方页面三种情况。
根据这种情况,我们选择了单元测试+e2e测试方案。 单元测试调用原有下单逻辑,完成下单。e2e模仿用户完成一笔完整的充值操作。

技术选择

单元测试: 最开始尝试使用jest,但是jest不支持动态创建测试用例(因为我们的测试用例不确定,由查询后端获得),最终使用mocha作为测试框架。
e2e: 使用Selenium WebDriver

三、单元测试

单元测试流程图

1、单元测试CLI 的实现逻辑

CLI主要实现了:根据输入配置命令,测试指定的页面,并将输入的命令记录下来,方便下次直接读取记录进行测试。

实现逻辑:

  1. 读取用户输入的命令
  2. 记录命令到本地文件配置文件urlRecords.json
  3. 项目文件实现npm run test的测试命令,并能根据环境变量执行不同的操作。
  4. CLI调用node的child_process.exec('npm run test')方法,并根据不同的命令设置环境变量。如:
const childProcess = require('child_process');
childProcess.exec(`cross-env COMMAND=${someCommand} npm run test`, (error, stdout, stderr) => {})

5、当并发测试的时候,并发读取配置文件urlRecords.json,在调用child_process.exec('npm run test')的同时设置环境变量, 用于标志当前读取的第几条配置。那么项目就能根据环境变量读取指定的某条命令了。

2、npm run test 的实现逻辑

要求npm run test 能独立使用,也能结合CLI使用。

页面环境配置

a. 利用jsdom, 模拟浏览器环境。具体的,我们使用了增强版的jsdom-global,模拟一个以TARGET_ORIGIN为url的页面:

const options = {
  url: TARGET_ORIGIN,
  referrer: TARGET_ORIGIN,
  contentType: 'text/html',
  userAgent: 'node.js',
  includeNodeLocations: true,
}
const cleanup = require('jsdom-global')(undefined, options)

b. 重新定义浏览器环境下的方法或属性,以免在测试中出错,主要是你在代码中使用的那些。
如localStorage:

globalThis.localStorage = {
  getItem: function (key) {
    return this[key]
  },
  setItem: function (key, value) {
    this[key] = value
  },
}

c. 如果你在单元测试中需要使用cookie
需要在得到cookie之后,手动设置cookie到当前域名下:

  const cookie = `${your_cookie};Domain=${your_host}`
  document.domain = `${your_host}`
  document.cookie = `${cookie}`

d. mocha的调用方式
mocha可以通过命令行的方式调用,下面是一段shell script命令:

"test": "NOW=$(date \"+%s\") && env TS_NODE_FILES=true TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' NODE_PATH=./ mocha -r ts-node/register -r jsdom-global/register --file 'tests/setup.js' --exit -r ignore-styles 'tests/**/*.ts' --delay  --timeout 10000 --reporter mochawesome --reporter-options reportFilename=test-${NOW}",

(1)NOW=NOW=$(date \"+%s\") 定义了一个变量NOW,即当前时间。
(2)env TS_NODE_FILES=true TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' NODE_PATH=./ts-node的语法,允许mocha在运行中使用ts语法。
(3)mocha -r ts-node/register -r jsdom-global/register-r为手动引用模块
(4)--file 'tests/setup.js' 在执行单元测试之前先加载setup.js。 (5)-r ignore-styles 'tests/**/*.ts' 在执行单测时,忽略样式。
(6)--reporter mochawesome --reporter-options reportFilename=test-${NOW} 设置测试报告的文件名称,名称取用变量NOW

e. mocha主要的实现步骤

describe('充值页渠道档位动态单元测试', async function () {
    // 1. 调用登录,设置cookie
    // 2. 利用store查询档位、过滤可用的档位的方法

  beforeEach(async () => {
    // 1. 调用store的重置表单的方法
  })

   // 遍历渠道
  store.channelList.forEach((channelItem, index) => {
    it(`测试下单渠道: ${channelItem.payChannel}_${channelItem.payMethod}_${channelItem.subChannel}`, async function () {
        // 1.调用store的档位点击逻辑,没表单的直接下单成功
        if (store.currentFormId) {
          // 有表单逻辑,需要表单填充
          // 1. 根据store的内容,填充表单
          // 2. 根据store调用提交表单方法
        }
      assert.strictEqual(store.isOrderFailed, false)
    })
  })
  run()
})

f. mocha的测试报告上传处理
(1) 根据测试执行的时间,生成不同名称的测试报告文件(如:mochawesome-report/test-1606704987.html)。
(2) 测试报告的样式文件和字体文件只需上传一次到bs2(文件服务)。
(3) 维护一份记录文件,用于记录报告的信息(如,测试报告的访问url,渠道名,是否成功,上传时间)。
(4) 单个单元测试:测试完成时候,生成一份测试报告,并上传到bs2,操作记录文件,将记录文件上传bas2
(5) 并发单元测试:每完成一个测试就生成一份测试报告,上传到bs2,全部并发测试完成时再操作记录文件,将记录文件上传bas2
注意:上传bs2时候注意请求头设置,以免请求文件内容的时候当做文件直接下载。

g. 可视化展示测试报告
以get请求方式获取记录文件,可视化展示其内容。由于记录文件包含每一份测试报告的url,访问此url可以得到每个报告的详情。

四、E2E测试

e2e