界面测试

你可以使用 Cypress 编写 UI 测试。它是一个基于 NodeJS 的
全栈测试框架,不依赖 Selenium。

要编写集成测试,请在 cypress/integration
目录中创建一个 .js 文件。

示例

以下是一个用于检查待办事项插入的集成测试示例

context('ToDo', () => {
 before(() => {
 cy.login('Administrator', 'admin');
 cy.visit('/desk');
 });

 it('creates a new todo', () => {
 cy.visit('/app/todo/new-todo-1');
 cy.fill_field('description', 'this is a test todo', 'Text Editor').blur();
 cy.get('.page-title').should('contain', 'Not Saved');
 cy.get('.primary-action').click();
 cy.visit('/desk#List/ToDo');
 cy.location('hash').should('eq', '/app/todo');
 cy.get('.list-row').should('contain', 'this is a test todo');
 });
});

在本地运行 Cypress

Cypress 使用你系统上安装的任意基于 Chromium 的浏览器来运行测试。
每个应用都有自己的 Cypress 测试套件。要运行某个应用的测试,请在 frappe-bench 目录中运行
以下命令。

bench --site [sitename] run-ui-tests [app]

这将打开 Cypress Electron 界面,你可以在其中手动运行任意测试,或
运行所有测试。

你也可以在无头模式下运行测试。

# run in headless mode
bench --site [sitename] run-ui-tests [app] --headless

要启用 Cypress 并行测试,你可以传入 --parallel 标志。
有关 Cypress 并行测试工作原理的更多信息可以在此处找到。

# run tests parallelly
bench --site [sitename] run-ui-tests [app] --parallel

代码覆盖率

代码覆盖率有助于识别测试期间执行了源代码的哪些行。为了测量代码覆盖率,需要对源代码进行插桩,并且需要将此插桩后的源代码与我们的测试运行器集成,以收集覆盖率并生成报告。

对于 Frappe 中的 Cypress 测试,.js 文件使用 Istanbul 进行插桩,并使用 Cypress 代码覆盖率插件合并每个测试的覆盖率并保存合并结果。

代码插桩:

为了计算源代码的哪些行被执行了,会通过插桩向代码中插入额外的计数器。例如:

插桩前:

function foo(a, b) {
 if (a < b)
 return b - a;
 else
 return a - b;
}

插桩后:

cov_1m1jljnmzu();

function foo(a, b) {
 cov_1m1jljnmzu().f[0]++;
 cov_1m1jljnmzu().s[0]++;

 if (a < b) {
 cov_1m1jljnmzu().b[0][0]++;
 cov_1m1jljnmzu().s[1]++;
 return b - a;
 } else {
 cov_1m1jljnmzu().b[0][1]++;
 cov_1m1jljnmzu().s[2]++;
 return a - b;
 }
}

当使用这个修改过(插桩)的源代码进行测试时,这些计数器会随着代码的执行而递增,并生成一个覆盖率对象。然后 Cypress 代码覆盖率插件会处理收集到的覆盖率并生成覆盖率报告。

在本地生成代码覆盖率报告:

  1. 使用 istanbul/nyc 对源代码进行插桩:
npx nyc instrument -x 'frappe/public/dist/**' -x 'frappe/public/js/lib/**' -x '**/*.bundle.js' --compact=false --in-place frappe

这会将 frappe 文件夹中的现有源代码替换为插桩后的源代码。-x 标志用于排除指定的路径。你也可以使用 -n 标志来指定要包含的路径。有关 nyc instrument 命令的更多详细信息,请参见此处

  1. 运行 Cypress 测试:
bench --site test_site run-ui-tests frappe --with-coverage
  1. 生成报告:
npx nyc report --reporter=text

有关其他报告格式,请参见此处

Testing-Library 查询

你也可以在 Cypress 测试中使用 Testing Library 查询。Testing Library 提供了以下测试工具:

  • 让编写模拟用户与应用交互方式的 UI 测试变得更加容易
  • 让在不需要了解所有实现细节的情况下查找 DOM 中的元素变得更加容易
  • 帮助保持测试的可维护性(这样小的重构就不会破坏测试)

有关用法的更多详细信息,请参见 Testing Library 文档

Testing Library 提供了多种查询来查找页面上的元素。以下是一些示例:

  • ByRole

在此处查看 HTML 元素及其默认角色的表格

查询 元素
findByRole('button', {name: 'Save'}) “ 且可访问名称为 ‘Save’
findByRole('checkbox') “
findByRole('textbox') , (也匹配其他默认 role=’textbox’ 的元素)
findByRole('searchbox') <input type="search">
findByRole('listbox') <select></select>, “
  • ByLabelText
查询 元素
findByLabelText('Optimize') 与标签 ‘Optimize’ 关联的元素
  • ByPlaceholderText
查询 元素
findByPlaceholderText('Name') placeholder=’Name’ 的元素
  • ByText
查询 元素
findByText('example.json') textContent=’example.json’ 的元素
  • ByDisplayValue
查询 元素
findByDisplayValue('Option 1') 且选中的 <option></option> 为 ‘Option 1’ (也匹配值属性相符的 <input> 或 <textarea></textarea>)
  • ByTitle
查询 元素
findByTitle('Open Link') title=’Open Link’ 的元素
  • ByAltText
  • ByTestId