TestCafe is a node.js tool to automate end-to-end web testing, you can write tests in JS or TypeScript, run them and view results.
简言之, Testcafe就是一个能够自动化前端end-to-end测试的工具,咱们可使用简单的JS或者Typescript写测试用例。html
须要提早安装NodeJS, 官网没有指定版本,本文基于NodeJS 8+撰写。前端
npm install -g testcafe
npm install --save-dev testcafe
建议使用本地安装,这样团队里其余人直接npm install
即可安装相同版本的全部依赖。node
可使用命令行执行单元测试git
testcafe chrome tests.js
testcafe path:/safari.app tests.js
testcafe all tests.js
testcafe "chrome:headless" tests.js
更多信息请参考 Command Line Interfacegithub
也能够写JS代码用Node执行单元测试,这也是本文着重推荐的方法,由于这个方式更加灵活。web
const createTestCafe = require('testcafe')
使用工厂函数得到TestCafe实例
工厂函数接受三个参数, 分别是 host controlPanelPort servicePort,返回一个promise, 该promise的最终结果即是一个TestCafe实例chrome
createTestCafe('localhost', 1337, 1338) .then(testcafe => { /* ... */ });
TestCafe对外暴露三个方法,分别是: createBrowserConnection
createRunner
close
,详情请参考 TestCafe Classexpress
调用 createRunner
testcafe.createRunner
返回一个Runner实例,该实例对外暴露多个方法,用于配置和执行测试任务,支持链式调用,好比:npm
const runner = testcafe.createRunner(); return runner .src(['test1.js', 'test2.js']) // 能够提早定义一个数组,或者将须要执行的文件保存在一个文件里,更加灵活,也能够配置文件夹 .filter((testName, fixtureName, fixturePath) => { //Add some filters based on testName, fixtureName, fixturePath }) .browsers(["chrome:headless"]) .reporter('json', stream) // stream is the report file, like const stream = fs.createWriteStream('report.json'); .run({ selectorTimeout: 10000, // the timeout testcafe wait for an element to appear skipJsErrors: true // to ignore JS error });
详情请参考 Runner Classjson
TestCafe使用fixture来组织测试用例,一个测试文件必须包含一个或多个fixture
fixture(fixtureName) fixture `fixtureName`
能够指定fixture的开始页面:
fixture.page(url) fixture.page `url`
而后写测试用例
test .page `url` (testName, async t=> { /* Test Code */ })
注意传入的参数t,它是 test controller,包含测试API和测试用例上下文,使用它咱们能够调用 test actions, 处理浏览器对话框,等待,执行断言。
也许你会注意到 t 是在测试用例中拿到的, 若是咱们须要把一个公用的action抽出来,如何得到 t 呢?
TestCafe提供了一种直接引入t的方式,此时t不包含具体测试用例的上下文,但包含了测试API, 好比:
async login() { await t .typeText("#user", "name") .typeText("#pwd", "pwd") .click("#login") }
看到这里,也许你对typeText
click
很陌生,不要紧,后面会提到。
Test Hooks, 执行在Test Case以前或以后
fixture.beforeEach(fn(t)) fixture.afterEach(fn(t)) test.before(fn(t)) test.after(fn(t))
注意 test.before
test.after
会覆盖fixture.beforeEach
fixture.afterEach
, Test Hooks 一样会拿到Test Controller实例。
能够跳过某些test case 或者fixture
fixture.skip test.skip
也能够指定只执行某些test case或fixture
fixture.only test.only
请参考Selectors
请参考Actions
Assertion | Description |
---|---|
eql | deep equal |
notEql | not deep equal |
ok | actual is true |
notOk | actual is false |
contains | Array or String or Object or promise contains |
notContains | Array or String or Object or promise not contains |
typeOf | type check |
notTypeOf | type check |
gt | Greater than |
gte | greater than or equal to |
lt | less than |
lte | less than or equal to |
within | range from start and finish |
notWithin | not range from start and finish |
match | regex check |
notMatch | regex check |
详情请参考Assertion API
在以前的章节咱们说在 test case 中, 咱们能够执行 test controller 对外暴露的 action, 执行断言,获取上下文变量等等,可是关于 client side 的数据却没法直接拿到,好比:
fixture("Fixture") test('window', async t=> { await t.navigateTo("url"); await t.expect(window.location.href).eql("url") })
会报出以下错误:
window is not defined
TestCafe 提供了ClientFunction构造函数,咱们能够传入一个回调函数,在回调函数中能够访问 window
const getWindowLocation = ClientFunction(() => window.location) fixture("Fixture") test('window', async t=> { await t.navigateTo("url"); let location = await getWindowLocation(); await t.expect(location.href).eql("url") })
在不少网站中,具备不一样角色的用户能够访问不一样的界面或功能,TestCafe 提供了Role
构造方法而且在 TestController 中暴露 UseRole
方法以便切换角色。
首先引入 Role
构造函数
import { Role } from 'testcafe'
建立 role
const user = Role(Env.LOGIN_URL, async t => { await t .typeText("userInput", "name") .typeText("pwdInput", "123") .click("submitBtn"); });
在 test case 中切换 role
t.useRole(user)
笔者认为TestCafe的调试功能不太成熟,只支持下一步等简单操做
t.debug()