Ember测试概述 #
一、测试类型 #
Ember支持三种主要测试类型:
| 类型 | 说明 | 速度 |
|---|---|---|
| 单元测试 | 测试独立函数/类 | 最快 |
| 集成测试 | 测试组件 | 中等 |
| 应用测试 | 测试完整流程 | 最慢 |
1.1 测试金字塔 #
text
┌─────────┐
│ 应用测试 │ 少量
├─────────┤
│ 集成测试 │ 中等
├─────────┤
│ 单元测试 │ 大量
└─────────┘
二、测试工具 #
2.1 测试框架 #
Ember默认使用QUnit作为测试框架:
javascript
// tests/test-helper.js
import Application from 'my-app/app';
import config from 'my-app/config/environment';
import * as QUnit from 'qunit';
import { setApplication } from '@ember/test-helpers';
import { setup } from 'qunit-dom';
import { start } from 'ember-qunit';
setApplication(Application.create(config.APP));
setup(QUnit.assert);
start();
2.2 测试助手 #
javascript
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, click, fillIn } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
2.3 测试选择器 #
bash
ember install ember-test-selectors
handlebars
<button data-test-submit>提交</button>
javascript
await click('[data-test-submit]');
三、运行测试 #
3.1 命令行运行 #
bash
# 运行所有测试
ember test
# 交互模式
ember test --server
# 运行特定测试
ember test --filter "user-card"
# 指定浏览器
ember test --browser chrome
3.2 测试文件结构 #
text
tests/
├── acceptance/ # 应用测试
│ └── login-test.js
├── integration/ # 集成测试
│ └── components/
│ └── user-card-test.js
├── unit/ # 单元测试
│ ├── models/
│ │ └── post-test.js
│ └── services/
│ └── session-test.js
├── helpers/ # 测试助手
├── index.html
└── test-helper.js
四、测试配置 #
4.1 testem.js #
javascript
// testem.js
module.exports = {
test_page: 'tests/index.html?hidepassed',
disable_watching: true,
launch_in_ci: ['Chrome'],
launch_in_dev: ['Chrome'],
browser_start_timeout: 120,
browser_args: {
Chrome: {
ci: [
'--headless',
'--disable-gpu',
'--disable-dev-shm-usage',
'--disable-software-rasterizer',
'--mute-audio',
'--remote-debugging-port=0',
'--window-size=1440,900',
],
},
},
};
五、测试最佳实践 #
5.1 测试命名 #
javascript
// 好的命名
module('Integration | Component | user-card', function (hooks) {
test('it renders user name', async function (assert) {});
test('it shows email when showEmail is true', async function (assert) {});
});
// 避免
module('user-card', function (hooks) {
test('test1', async function (assert) {});
});
5.2 AAA模式 #
javascript
test('it calculates total correctly', async function (assert) {
// Arrange - 准备
const cart = new ShoppingCart();
cart.addItem({ price: 10, quantity: 2 });
cart.addItem({ price: 5, quantity: 3 });
// Act - 执行
const total = cart.total;
// Assert - 断言
assert.strictEqual(total, 35, 'Total should be 35');
});
5.3 测试隔离 #
javascript
module('Integration | Component | counter', function (hooks) {
setupRenderingTest(hooks);
hooks.beforeEach(function () {
// 每个测试前的设置
this.counter = 0;
});
hooks.afterEach(function () {
// 每个测试后的清理
});
test('it increments', async function (assert) {
// 测试代码
});
});
六、断言方法 #
6.1 常用断言 #
javascript
// 相等
assert.strictEqual(actual, expected, 'message');
// 深度相等
assert.deepEqual(actual, expected, 'message');
// 布尔
assert.true(value, 'message');
assert.false(value, 'message');
// 存在
assert.ok(value, 'message');
assert.notOk(value, 'message');
// DOM断言
assert.dom('.title').hasText('Hello');
assert.dom('.title').exists();
assert.dom('.title').doesNotExist();
assert.dom('input').hasValue('test');
assert.dom('button').isDisabled();
assert.dom('input').isFocused();
七、总结 #
Ember测试要点:
| 类型 | 用途 |
|---|---|
| 单元测试 | 测试独立逻辑 |
| 集成测试 | 测试组件 |
| 应用测试 | 测试用户流程 |
良好的测试覆盖是应用质量的保障。
最后更新:2026-03-28