TestCafe 搭建前端End-to-End自动化测试工具

What is Test Cafe

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

Installation

preparation

须要提早安装NodeJS, 官网没有指定版本,本文基于NodeJS 8+撰写。前端

Install TestCafe

  1. Globally
    npm install -g testcafe
  2. Locally
    npm install --save-dev testcafe

建议使用本地安装,这样团队里其余人直接npm install即可安装相同版本的全部依赖。node

How to run test cases

Command Line Interface

可使用命令行执行单元测试git

  1. 使用指定浏览器
    testcafe chrome tests.js
    testcafe path:/safari.app tests.js
  2. 使用全部安装的浏览器
    testcafe all tests.js
  3. headless mode
    Chrome 和 Firefox 支持 headless mode
    testcafe "chrome:headless" tests.js

更多信息请参考 Command Line Interfacegithub

Programming Interface

也能够写JS代码用Node执行单元测试,这也是本文着重推荐的方法,由于这个方式更加灵活。web

  1. 引入工厂函数
    const createTestCafe = require('testcafe')
  2. 使用工厂函数得到TestCafe实例
    工厂函数接受三个参数, 分别是 host controlPanelPort servicePort,返回一个promise, 该promise的最终结果即是一个TestCafe实例chrome

    createTestCafe('localhost', 1337, 1338)
    .then(testcafe => {
        /* ... */
    });

    TestCafe对外暴露三个方法,分别是: createBrowserConnection createRunner close,详情请参考 TestCafe Classexpress

  3. 调用 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

How to write test cases

Code Structure

Fixture

TestCafe使用fixture来组织测试用例,一个测试文件必须包含一个或多个fixture

fixture(fixtureName)
fixture `fixtureName`

能够指定fixture的开始页面:

fixture.page(url)
fixture.page `url`

Test Case

而后写测试用例

test
    .page `url`
    (testName, async t=> {
        /* Test Code */
    })

注意传入的参数t,它是 test controller,包含测试API和测试用例上下文,使用它咱们能够调用 test actions, 处理浏览器对话框,等待,执行断言。

Make Test Step Common

也许你会注意到 t 是在测试用例中拿到的, 若是咱们须要把一个公用的action抽出来,如何得到 t 呢?
TestCafe提供了一种直接引入t的方式,此时t不包含具体测试用例的上下文,但包含了测试API, 好比:

async login() {
    await t
        .typeText("#user", "name")
        .typeText("#pwd", "pwd")
        .click("#login")
}

看到这里,也许你对typeText click很陌生,不要紧,后面会提到。

Test Hooks

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实例。

Skip Tests

能够跳过某些test case 或者fixture

fixture.skip
test.skip

也能够指定只执行某些test case或fixture

fixture.only
test.only

Selectors

请参考Selectors

Actions

请参考Actions

Assertions

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

Tricks

ClientFunction

在以前的章节咱们说在 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")
    })

Role

在不少网站中,具备不一样角色的用户能够访问不一样的界面或功能,TestCafe 提供了Role构造方法而且在 TestController 中暴露 UseRole方法以便切换角色。

  1. 首先引入 Role 构造函数

    import { Role } from 'testcafe'
  2. 建立 role

    const user = Role(Env.LOGIN_URL, async t => {
        await t
            .typeText("userInput", "name")
            .typeText("pwdInput", "123")
            .click("submitBtn");
    });
  3. 在 test case 中切换 role

    t.useRole(user)

How to debug

笔者认为TestCafe的调试功能不太成熟,只支持下一步等简单操做

t.debug()
相关文章
相关标签/搜索