Commit d018d3b3 authored by xie.qin's avatar xie.qin

README refined.

parent dbe304f5
# 一款小巧灵活的端到端Web自动化测试框架
关键词:
## 关键词:
- [Cypress](https://www.cypress.io/)
- [Cucumber](https://cucumber.io)
## 说明
```text
Cypress几年前还属于一个比较小众的Web测试方案,现如今已有替代Selenium成为Web自动化测试头把交椅的实力。
......@@ -16,5 +17,10 @@ Cypress几年前还属于一个比较小众的Web测试方案,现如今已有
- 并发执行
- 各大 IDE 均支持关键词高亮
用例参考:
## 用例参考:
[点击此链接](./cypress/integration/case-948.feature)
## 测试执行及结果展示:
- 运行命令: npm run cypress:run
- 测试执行完成后可借助插件 [multiple-cucumber-html-reporter](https://github.com/wswebcreation/multiple-cucumber-html-reporter) 在项目根目录运行命令 node report.js。结束后测试报告已生成在./cypress/reports/index.html。
- ![结果截图](./cypress/reports/result.png)
{
"baseUrl": "http://172.22.18.152/",
"env": {
"TAGS": ""
"TAGS": "@dryrun"
},
"retries": {
"runMode": 0,
......
......@@ -13,17 +13,17 @@
"uri": "case-948.feature",
"elements": [
{
"id": "end-to-end-test-case-948;case-948",
"id": "end-to-end-test-case-948;hello-world",
"keyword": "Scenario",
"line": 8,
"name": "case-948",
"name": "hello world",
"tags": [
{
"name": "@case-948",
"line": 1
},
{
"name": "@register",
"name": "@dryrun",
"line": 7
}
],
......@@ -36,7 +36,7 @@
"name": "Home page opened",
"result": {
"status": "passed",
"duration": 155000000
"duration": 555000000
}
},
{
......@@ -51,13 +51,58 @@
},
{
"arguments": [],
"keyword": "Then ",
"keyword": "Given ",
"line": 9,
"name": "Register with testData number \"case-948\"",
"name": "Home page opened",
"result": {
"status": "passed",
"duration": 121000000
}
}
]
},
{
"id": "end-to-end-test-case-948;case-948",
"keyword": "Scenario",
"line": 16,
"name": "case-948",
"tags": [
{
"name": "@case-948",
"line": 1
},
{
"name": "@login",
"line": 15
}
],
"type": "scenario",
"steps": [
{
"arguments": [],
"keyword": "Given ",
"line": 4,
"name": "Home page opened",
"result": {
"status": "skipped"
}
},
{
"arguments": [],
"keyword": "Then ",
"line": 5,
"name": "Get testing data file \"accounts.json\" and save in context",
"result": {
"status": "skipped"
}
},
{
"arguments": [],
"keyword": "Then ",
"line": 17,
"name": "login after input credential with testData number \"case-948\"",
"result": {
"status": "failed",
"duration": 17000000,
"error_message": "TypeError: Object prototype may only be an Object or null: undefined\n\nBecause this error occurred during a `after each` hook we are skipping the remaining tests in the current suite: `end to end test case 948`\n at Function.setPrototypeOf (<anonymous>)\n at eval (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:24470:39)\n at patch (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:24472:5)\n at patch (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:23878:3)\n at Object.eval (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:23870:18)\n at Object.eval (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:24205:4)\n at Object.256../clone.js (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:24205:17)\n at o (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:1:265)\n at eval (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:1:316)\n at Object.284.graceful-fs (http://172.22.18.152/__cypress/tests?p=cypress\\integration\\case-948.feature:49935:12)\nFrom previous event:\n at getRet (http://172.22.18.152/__cypress/runner/cypress_runner.js:141255:20)\nFrom previous event:\n at Context.thenFn (http://172.22.18.152/__cypress/runner/cypress_runner.js:141273:23)\n at Context.then (http://172.22.18.152/__cypress/runner/cypress_runner.js:141725:21)\n at Context.<anonymous> (http://172.22.18.152/__cypress/runner/cypress_runner.js:157781:21)\n at http://172.22.18.152/__cypress/runner/cypress_runner.js:156491:15\nFrom previous event:\n at runCommand (http://172.22.18.152/__cypress/runner/cypress_runner.js:156470:8)\n at next (http://172.22.18.152/__cypress/runner/cypress_runner.js:156613:14)\nFrom previous event:\n at http://172.22.18.152/__cypress/runner/cypress_runner.js:170476:77\nFrom previous event:\n at Object.run (http://172.22.18.152/__cypress/runner/cypress_runner.js:170471:21)\n at Object.run (http://172.22.18.152/__cypress/runner/cypress_runner.js:156667:15)\n at $Cy.cy.<computed> [as then] (http://172.22.18.152/__cypress/runner/cypress_runner.js:157821:17)\n at Context.runnable.fn (http://172.22.18.152/__cypress/runner/cypress_runner.js:158045:21)\n at callFn (http://172.22.18.152/__cypress/runner/cypress_runner.js:112798:21)\n at Hook.../driver/node_modules/mocha/lib/runnable.js.Runnable.run (http://172.22.18.152/__cypress/runner/cypress_runner.js:112785:7)\n at http://172.22.18.152/__cypress/runner/cypress_runner.js:164511:28\nFrom previous event:\n at Object.onRunnableRun (http://172.22.18.152/__cypress/runner/cypress_runner.js:164496:17)\n at $Cypress.action (http://172.22.18.152/__cypress/runner/cypress_runner.js:154154:28)\n at Hook.Runnable.run (http://172.22.18.152/__cypress/runner/cypress_runner.js:162243:13)\n at next (http://172.22.18.152/__cypress/runner/cypress_runner.js:113300:10)\n at http://172.22.18.152/__cypress/runner/cypress_runner.js:113344:5\n at timeslice (http://172.22.18.152/__cypress/runner/cypress_runner.js:107270:27)"
"status": "skipped"
}
}
]
......
......@@ -3,7 +3,8 @@
"name": "automation",
"password": "admin123",
"email": "automation@33.cn",
"mobilePhone": "13000000000"
"mobilePhone": "13000000000",
"authCode": 1111
}
}
......@@ -4,6 +4,10 @@ Feature: end to end test case 948
Given Home page opened
Then Get testing data file "accounts.json" and save in context
@dryrun
Scenario: hello world
Given Home page opened
@register
Scenario: case-948
Then Register with testData number "case-948"
......
......@@ -12,8 +12,11 @@ Then('login after input credential with testData number {string}', (caseNum) =>
cy.get('form').should('have.class', 'login-form').within(() => {
debugger
var data = testFile[caseNum]
cy.xpath('div[1]//input').type(data.username)
cy.xpath('div[1]//input').type(data.name)
cy.xpath('div[2]//input').type(data.password)
cy.xpath('div[3]//input').type(data.authCode)
cy.xpath('div[4]//button').click()
})
})
cy.url().should('include', 'home')
})
\ No newline at end of file
......@@ -2,33 +2,8 @@ const {After} = require("cypress-cucumber-preprocessor/steps")
// Asynchronous Promise
After(() => {
cy.log('produce cucumber reports.')
const report = require('multiple-cucumber-html-reporter');
report.generate({
jsonDir: '../../cucumber-json/',
reportPath: '../../reports/',
metadata:{
browser: {
name: 'chrome',
version: '60'
},
device: 'Local test machine',
platform: {
name: 'ubuntu',
version: '16.04'
}
},
customData: {
title: 'Run info',
data: [
{label: 'Project', value: 'Custom project'},
{label: 'Release', value: '1.2.3'},
{label: 'Cycle', value: 'B11221.34321'},
{label: 'Execution Start Time', value: 'Nov 19th 2017, 02:31 PM EST'},
{label: 'Execution End Time', value: 'Nov 19th 2017, 02:56 PM EST'}
]
}
});
return Promise.resolve()
});
\ No newline at end of file
......@@ -17,8 +17,16 @@
*/
// eslint-disable-next-line no-unused-vars
const cucumber = require('cypress-cucumber-preprocessor').default
const fs = require('fs');
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
on('file:preprocessor', cucumber())
on('after:run', (results) => {
if (results) {
fs.mkdirSync("cypress/.run", { recursive: true });
fs.writeFile("cypress/.run/results.json", JSON.stringify(results));
}
})
}
......@@ -7,7 +7,7 @@
"cypress:open": "npx cypress open",
"cypress:record": "npx cypress run --record --key <YOUR_KEY>",
"cypress:ci": "npx cypress:run --parallel",
"cypress:run": "npx cypress-tags run -g **/*.features",
"cypress:run": "npx cypress-tags run -g **/*.features --browser chrome",
"cypress:tags": "npx cypress-tags run -e TAGS='@dryrun'"
},
"author": "",
......
const report = require('multiple-cucumber-html-reporter');
const fs = require('fs');
const mapOs = (os) => {
if(os.startsWith('win')) {
return 'windows';
} else if (os.startsWith('osx')) {
return 'osx';
} else if (os.startsWith('linux')) {
return 'linux';
} else if (os.startsWith('ubuntu')) {
return 'ubuntu';
} else if (os.startsWith('android')) {
return 'android';
} else if (os.startsWith('ios')) {
return 'ios';
}
};
fs.readFile('cypress/.run/results.json', function read(err, data) {
if (err) {
throw err;
}
var runInfos = JSON.parse(data);
report.generate({
jsonDir: './cypress/cucumber-json/',
reportPath: './cypress/reports/',
metadata:{
browser: {
name: runInfos.browserName,
version: runInfos.browserVersion
},
device: 'Cypress',
platform: {
name: mapOs(runInfos.osName)
}
},
customData: {
title: 'Run info',
data: [
{label: 'Project', value: 'project'},
{label: 'Execution Start Time', value: new Date(runInfos.startedTestsAt).toLocaleString()},
{label: 'Execution End Time', value: new Date(runInfos.endedTestsAt).toLocaleString()}
]
}
});
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment