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

本文介绍了TestCafe,一个用于自动化前端端到端测试的Node.js工具。涵盖其安装,包括准备工作和安装方式;运行测试用例的命令行和编程接口;编写测试用例的代码结构、选择器、操作、断言等;还提及一些技巧如ClientFunction和Role,以及调试功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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写测试用例。

Installation

preparation

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

Install TestCafe

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

建议使用本地安装,这样团队里其他人直接npm install便可安装相同版本的所有依赖。

How to run test cases

Command Line Interface

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

  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 Interface

Programming Interface

也可以写JS代码用Node执行单元测试,这也是本文着重推荐的方法,因为这个方式更加灵活。

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

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

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

  3. 调用 createRunner
    testcafe.createRunner返回一个Runner实例,该实例对外暴露多个方法,用于配置和执行测试任务,支持链式调用,比如:

    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 Class

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

AssertionDescription
eqldeep equal
notEqlnot deep equal
okactual is true
notOkactual is false
containsArray or String or Object or promise contains
notContainsArray or String or Object or promise not contains
typeOftype check
notTypeOftype check
gtGreater than
gtegreater than or equal to
ltless than
lteless than or equal to
withinrange from start and finish
notWithinnot range from start and finish
matchregex check
notMatchregex 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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值