ember-qunit simplifies testing of Ember.js applications with QUnit by providing QUnit-specific wrappers around the helpers contained in ember-test-helpers. It offers three main testing modes for different test scenarios: unit tests that interact with Ember's dependency injection system, component/template rendering tests, and full acceptance tests with routing capabilities.
ember install ember-qunitimport { setupTest, setupRenderingTest, setupApplicationTest, start, setResolver } from 'ember-qunit';For test loading in AMD environments:
import { loadTests } from 'ember-qunit/test-loader';For QUnit functions:
import { module, test, skip, only, todo } from 'ember-qunit';// tests/test-helper.js
import Application from '../app';
import config from '../config/environment';
import { setApplication } from '@ember/test-helpers';
import { start } from 'ember-qunit';
setApplication(Application.create(config.APP));
start();import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('SidebarController', function(hooks) {
setupTest(hooks);
test('exists', function(assert) {
let controller = this.owner.lookup('controller:sidebar');
assert.ok(controller);
});
});import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render, find } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
module('GravatarImageComponent', function(hooks) {
setupRenderingTest(hooks);
test('renders', async function(assert) {
await render(hbs\`{{gravatar-image}}\`);
assert.ok(find('img'));
});
});ember-qunit provides a layered testing architecture:
start() function that configures and launches the QUnit test runnerFunctions for setting up global test configuration and resolvers.
/**
* Sets a Resolver globally which will be used to look up objects from each test's container
*/
function setResolver(resolver: Resolver): void;Core functions for setting up different types of tests with proper Ember context and helpers.
interface SetupTestOptions {
resolver?: Resolver;
waitForSettled?: boolean;
}
function setupTest(hooks: NestedHooks, options?: SetupTestOptions): void;
function setupRenderingTest(hooks: NestedHooks, options?: SetupTestOptions): void;
function setupApplicationTest(hooks: NestedHooks, options?: SetupTestOptions): void;Central control for starting and configuring the QUnit test runner with Ember-specific options.
interface QUnitStartOptions {
setupTestContainer?: boolean;
startTests?: boolean;
setupTestAdapter?: boolean;
setupEmberTesting?: boolean;
setupTestIsolationValidation?: boolean;
testIsolationValidationDelay?: number;
}
function start(options?: QUnitStartOptions): void;
function setupResetOnerror(): void;Module loading utilities for dynamically loading test modules, particularly useful in AMD environments.
class TestLoader {
static load(): void;
shouldLoadModule(moduleName: string): boolean;
listModules(): string[];
listTestModules(): string[];
loadModules(): void;
}
function loadTests(): void;interface Resolver {
resolve(fullName: string): any;
}
interface TestContext {
owner?: any;
element?: Element;
set?(key: string, value: any): void;
setProperties?(hash: object): void;
get?(key: string): any;
getProperties?(...keys: string[]): object;
pauseTest?(): Promise<void>;
render?(template: any): Promise<void>;
}
interface Assert {
ok(value: any, message?: string): void;
equal(actual: any, expected: any, message?: string): void;
expect(amount: number): void;
timeout(duration: number): void;
dom(target?: string | Element): DOMAssert;
}
interface DOMAssert {
exists(message?: string): void;
doesNotExist(message?: string): void;
isChecked(message?: string): void;
isNotChecked(message?: string): void;
isFocused(message?: string): void;
isNotFocused(message?: string): void;
isRequired(message?: string): void;
isNotRequired(message?: string): void;
hasText(expected?: string, message?: string): void;
containsText(expected?: string, message?: string): void;
doesNotContainText(expected?: string, message?: string): void;
hasValue(expected?: string, message?: string): void;
hasClass(expected?: string, message?: string): void;
doesNotHaveClass(expected?: string, message?: string): void;
hasAttribute(expected?: string, value?: string, message?: string): void;
doesNotHaveAttribute(expected?: string, message?: string): void;
}
abstract class EmberTestAdapter {
asyncStart(): void;
asyncEnd(): void;
}
interface NestedHooks {
before<TC extends TestContext>(fn: (this: TC, assert: Assert) => void | Promise<void>): void;
beforeEach<TC extends TestContext>(fn: (this: TC, assert: Assert) => void | Promise<void>): void;
after<TC extends TestContext>(fn: (this: TC, assert: Assert) => void | Promise<void>): void;
afterEach<TC extends TestContext>(fn: (this: TC, assert: Assert) => void | Promise<void>): void;
}
class QUnitAdapter extends EmberTestAdapter {
init(): void;
asyncStart(): void;
asyncEnd(): void;
}ember-qunit re-exports key QUnit functions for convenience, providing access to the full QUnit testing API:
/**
* Creates a QUnit module (test suite) with hooks support
*/
function module(name: string, hooks?: (hooks: NestedHooks) => void): void;
/**
* Creates a test within the current module
*/
function test<TC extends TestContext>(name: string, callback: (this: TC, assert: Assert) => void | Promise<unknown>): void;
/**
* Skips a test (shows as skipped in output but doesn't run)
*/
function skip<TC extends TestContext>(name: string, callback?: (this: TC, assert: Assert) => void | Promise<unknown>): void;
/**
* Runs only this test, ignoring all others (useful for debugging)
*/
function only<TC extends TestContext>(name: string, callback: (this: TC, assert: Assert) => void | Promise<unknown>): void;
/**
* Creates a todo test (expected to fail, passes if at least one assertion fails)
*/
function todo<TC extends TestContext>(name: string, callback: (this: TC, assert: Assert) => void | Promise<unknown>): void;