用 jest + gitlab-ci 搭建前端UI自动化测试环境
前言
下面以 github创建仓库为例 测试领域中比较麻烦的就是前端UI测试
gitlab地址: https://gitlab.com/yunqiangwu/devops-test.git
前置要求
- 拥有gitlab账号(公司内部的也可以)
- gitlab 已经配置了 CI Runner(具体方法百度)
功能实现效果
- 修改过测试用例后push触发自动测试
- 测试完成后生成测试报告
- 测试报告部署到 git pages 上
- 发送邮件通知测试结果,以及报告查看链接
先看下我在实际项目中的效果,下面是我收到的自动化测试完成后的邮件:

预览地址
自动化测试报告
测试覆盖率报告
创建项目
1 2 3 4 5 6 7 8 9
| mkdir devops-test cd devops-test npm init
cnpm i jest jest-report nightmare --save cnpm i babel-jest babel-plugin-import babel-plugin-transform-class-properties babel-plugin-transform-decorators-legacy babel-plugin-transform-runtime babel-preset-env --save-dev
|
重点依赖库介绍:
- jest 测试框架
- nightmare 浏览器运行库
- jest-report 测试报告生产库
配置jest环境
- 在
package.json
的 scripts
中叫如 test 命令
1 2 3 4 5 6 7 8 9 10 11 12 13
| { "name": "devops-test", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "jest e2e.js" }, "author": "",
}
|
- 创建
jasmine
配置文件 项目根目录/tests/jasmine.js
配置测试超时时间
1
| jasmine.DEFAULT_TIMEOUT_INTERVAL = 12000;
|
- 在
package.json
中添加两个字段 babel
和 jest
,这样就能跑 es6 的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| { "name": "devops-test", "version": "1.0.0", "babel": { "presets": [ "env" ], "plugins": [ "transform-decorators-legacy", "transform-class-properties", "transform-es2015-destructuring" ] }, "jest": { "testResultsProcessor": "jest-report", "setupTestFrameworkScriptFile": "<rootDir>/tests/jasmine.js", "testMatch": [ "**/?(*.)(spec|test|e2e).js?(x)" ] }, }
|
编写测试用例
测试github
登录功能<rootDir>/src/e2e/test-github-login.e2e.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| import Nightmare from 'nightmare'; import { helperBuilder } from 'jest-report';
describe('Login', () => { let page; beforeEach(() => { page = Nightmare({ show: true }).viewport(1024, 768); page.goto('https://github.com/login'); });
it('should login with failure', async() => { const reportHelper = helperBuilder('Login', 'should login with failure');
reportHelper.monitorPage(page); await page .type('#login_field', 'mockuser') .type('#password', 'wrong_password') .click('input[type="submit"]') .wait('#js-flash-container > div > div'); await page.screenshot(reportHelper.genPicturePath()); const text = await page.wait('#js-flash-container > div > div') .evaluate(() => document.body.innerText) .end(); await page.end(); expect(text).toContain('Incorrect username or password'); });
it('should login successfully', async() => { const reportHelper = helperBuilder('Login', 'should login successfully');
reportHelper.monitorPage(page); await page .type('#login_field', '正确用户名') .type('#password', '正确密码') .click('input[type="submit"]') .wait('#your_repos > div > div.boxed-group-action > a'); await page.screenshot(reportHelper.genPicturePath()); const title = await page .evaluate(() => document.title) .end(); await page.end(); expect(title).toBe('GitHub'); }); });
|
运行测试生成测试报告
1. 执行命令npm test
,运行测试脚步

2. 生成测试报告
生成的文件路径默认是 `<rootDir>/dist/test-report`
3. 测试报告效果


添加项目到gitlab
1 2 3 4 5 6
| git init git remote add origin https://gitlab.com/yunqiangwu/devops-test.git git add . git commit -m "Initial commit" git push -u origin master
|
添加到持续集成
自动部署测试报告 到gitlab pages 网页
1
| cnpm i --save-dev gh-pages
|
在 package.json
添加 scripts
1 2 3 4
| "scripts": { "test": "jest e2e.js", "site": "gh-pages -d dist" },
|
配置邮件通知工具
<rootDir>/tool/emailnotice.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #!/bin/bash MAIL_FROM='supportman@yeah.net'
MAIL_TO_ARR_ARG=$1 MAIL_SUBJECT=$2 shift 2 MAIL_CONTENT=$* MAIL_CONTENT_FILE="/tmp/`/bin/date +%s`.txt" MAIL_SMTP='smtp://smtp.yeah.net' MAIL_USER='supportman@yeah.net' MAIL_PASSWORD='wu950429'
OLD_IFS="$IFS"
IFS="," MAIL_TO_ARR=($MAIL_TO_ARR_ARG) IFS="$OLD_IFS" split_1() {
MAIL_TO=$1 echo "发送邮件到:"$1 echo "From:${MAIL_FROM} To:$MAIL_TO Subject: $MAIL_SUBJECT
$MAIL_CONTENT "> ${MAIL_CONTENT_FILE}
curl -s --url "${MAIL_SMTP}" --mail-from "${MAIL_FROM}" --mail-rcpt ${MAIL_TO} --upload-file ${MAIL_CONTENT_FILE} --user "${MAIL_USER}:${MAIL_PASSWORD}"
}
for s in ${MAIL_TO_ARR[@]} do split_1 "$s" done
rm -rf ${MAIL_CONTENT_FILE}
|
gitlab-ci.yml 配置文件 .gitlab-ci.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| image: jonneywu/node-xvfb-cnpm
cache: key: "$CI_REPOSITORY_URL" paths: - node_modules - dist
stages: - test - email
test: script: - if [ ! -d node_modules ]; then cnpm i; fi - if [ ! -d node_modules/nightmare ]; then cnpm i nightmare; fi - export DISPLAY=':99.0' - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & - npm run test && echo test FAIL - kill -9 `ps -ef | grep Xvfb| grep -v grep|awk '{print $2}'` - npm run site stage: test only: - master artifacts: paths: - dist
email: script: - echo email - if [[ ! -n $MAIL_TO ]]; then export MAIL_TO=842269153@qq.com,yunqiang.wu@hand-china.com ; fi - export root_url=http://`cat CNAME` - export test_passed_rate=$(printf "%.2f" `cat dist/test-report/testResultData.json | jq '100*.numPassedTests/.numTotalTests'`)% - bash ./tool/emailnotice.sh $MAIL_TO '前端自动化测试' `echo -e " 测试分支: ${CI_COMMIT_REF_NAME} \r\n 提交人:${GITLAB_USER_NAME} \r\n 测试通过率:${test_passed_rate} \r\n 触发来源:${CI_PIPELINE_SOURCE} \r\n 测试环境:mockApi环境 \r\n\r\n预览地址: ${root_url}/index.html \r\n 自动化测试报告:${root_url}/test-report/reporter.html \r\n 测试覆盖率报告: ${root_url}/coverage/lcov-report/index.html \r\n"` stage: email only: - master artifacts: paths: - dist
|
注意事项
- react 开发是如果用了
css modules
的技术开发时,会把 class 名换掉 ,测试框架就无法通过 css selector
找到并操作 Dom元素,在开发时,可以为主要控制的dom节点给id
,data-custom
自定义属性,比如用户名输入框、登录按钮,
- 我这里的介绍的自动化测试,只是测试系统的功能交互是否能正常,如果需要靠自动化测试来判断UI界面的样式对比是符合要求,可能还是要靠人力测试,不过测试的目的保证系统功能成正常使用不出BUG。
参考
原文链接: http://blog.jajabjbj.top/2018/05/09/2018-05-21/
版权声明: 转载请注明出处.