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