QUnit.module()

追加されたバージョン: 1.0.0

説明

QUnit.module( name )
QUnit.module( name, nested )
QUnit.module( name, options )
QUnit.module( name, options, nested )

関連するテストを共通のラベルでグループ化します。

パラメータ 説明
name (文字列) このテストグループのラベル。
options (オブジェクト) フックコールバックを設定します。
nested (関数) ネストされたモジュールを作成したり、フックを機能的に追加するためのスコープ。

モジュール内のすべてのテストはそのモジュールにグループ化されます。テストはQUnit.testメソッドを使用してモジュールに追加できます。モジュールは、テストの実行を整理、選択、フィルタリングするのに役立ちます。§ テストの整理を参照してください。

モジュールは他のモジュールの中にネストできます。出力では、テストは通常、すべての親モジュールの名前をプレフィックスとして付けられます。例:「祖父母 > 親 > 子 > 私のテスト」。§ ネストされたモジュールのスコープを参照してください。

QUnit.module.only()QUnit.module.skip()、およびQUnit.module.todo()メソッドはQUnit.module()のエイリアスであり、QUnit.test.only()QUnit.test.skip()、またはQUnit.test.todo()の動作をモジュールのすべてのテストに一度に適用します。

フック

フックを使用して、備品を準備したり、その他のセットアップとティアダウンのロジックを実行できます。フックは、個々のテストの前後、またはモジュール全体の前後で実行できます。

  • before: 最初のテストの前にコールバックを実行します。
  • beforeEach: 各テストの前にコールバックを実行します。
  • afterEach: 各テストの後でコールバックを実行します。
  • after: 最後のテストの後でコールバックを実行します。

スコープ付きモジュールhooksパラメータ、モジュールのoptionsオブジェクト、またはQUnit.hooksを介してグローバルにすべてのテストに対してフックを追加できます。

モジュールに追加されたフックは、ネストされたモジュールのテストにも適用されます。

テストのに実行されるフックは、追加された順序で、外側から内側へと並べられます。これは、テストが最初にグローバルなbeforeEachフックを実行し、次に親モジュールのフックを実行し、最後にテストが属する直近のモジュールに追加されたフックを実行することを意味します。テストのに実行されるフックは、内側から外側へと、逆の順序で並べられます。言い換えれば、beforebeforeEachのコールバックはキューを形成し、afterEachafterスタックを形成します。

フックコールバック

フックコールバックは非同期関数にすることができ、Promiseまたはその他のthenableを返すことができます。QUnitは、テストの実行を継続する前に、フックの非同期作業が完了するのを自動的に待ちます。

各フックは、フックが実行されているQUnit.testと同様に、同じassertオブジェクトとthisを介したテストコンテキストにアクセスできます。例:§ テストコンテキストの使用

パラメータ 説明
assert (オブジェクト) アサーションオブジェクト。

フック内から新しいQUnit.testを動的に作成することは推奨されません。afterフックが1回だけ実行され、モジュール内の最後のフックになるという要件を満たすために、QUnitは動的に定義されたテストを親モジュールまたはグローバルテストに関連付ける場合があります。QUnit.begin()を介して動的なテストを定義することをお勧めします。

オプションオブジェクト

オプションオブジェクトを使用してフックを追加できます。

名前 説明
before (関数) 最初のテストの前に実行されます。
beforeEach (関数) 各テストの前に実行されます。
afterEach (関数) 各テストの後で実行されます。
after (関数) 最後のテストの後で実行されます。

モジュールオプションオブジェクトのプロパティは、各テストの開始時にテストコンテキストオブジェクトにコピーされます。このようなプロパティは、フックコールバックからも変更できます。§ テストコンテキストの使用を参照してください。

例: § モジュールオプションの宣言

ネストされたスコープ

モジュールはネストして、親モジュール内の共通のラベルの下にテストをグループ化できます。

モジュールのスコープには、フックを手続き的に追加するために使用できるhooksオブジェクトが与えられます。

パラメータ 説明
hooks (オブジェクト) フックを追加するためのオブジェクト。

例: § ネストされたモジュールのスコープ

変更ログ

QUnit 2.4 QUnit.module.only()QUnit.module.skip()、およびQUnit.module.todo()エイリアスが導入されました。
QUnit 2.0 beforeオプションとafterオプションが導入されました。
QUnit 1.20 nestedスコープ機能が導入されました。
QUnit 1.16 beforeEachオプションとafterEachオプションが導入されました。
setupオプションとteardownオプションはQUnit 1.16で非推奨となり、QUnit 2.0で削除されました。

テストの整理

nestedコールバック引数なしでQUnit.moduleが呼び出された場合、その後定義されたすべてのテストは、別のモジュールが定義されるまで、そのモジュールにグループ化されます。

QUnit.module('Group A');

QUnit.test('basic test example 1', function (assert) {
  assert.true(true, 'this is fine');
});
QUnit.test('basic test example 2', function (assert) {
  assert.true(true, 'this is also fine');
});

QUnit.module('Group B');

QUnit.test('basic test example 3', function (assert) {
  assert.true(true, 'this is fine');
});
QUnit.test('basic test example 4', function (assert) {
  assert.true(true, 'this is also fine');
});

最新の構文の使用

const { test } = QUnit;

QUnit.module('Group A');

test('basic test example', assert => {
  assert.true(true, 'this is fine');
});
test('basic test example 2', assert => {
  assert.true(true, 'this is also fine');
});

QUnit.module('Group B');

test('basic test example 3', assert => {
  assert.true(true, 'this is fine');
});
test('basic test example 4', assert => {
  assert.true(true, 'this is also fine');
});

モジュールオプションの宣言

QUnit.module('module A', {
  before: function () {
    // prepare something once for all tests
  },
  beforeEach: function () {
    // prepare something before each test
  },
  afterEach: function () {
    // clean up after each test
  },
  after: function () {
    // clean up once after all tests are done
  }
});

ネストされたモジュールのスコープ

const { test } = QUnit;

QUnit.module('Group A', hooks => {
  test('basic test example', assert => {
    assert.true(true, 'this is fine');
  });

  test('basic test example 2', assert => {
    assert.true(true, 'this is also fine');
  });
});

QUnit.module('Group B', hooks => {
  test('basic test example 3', assert => {
    assert.true(true, 'this is fine');
  });

  test('basic test example 4', assert => {
    assert.true(true, 'this is also fine');
  });
});

ネストされたモジュールでのフック

before/beforeEachフックはネストされたモジュールに対してキューに入れられます。after/afterEachフックはネストされたモジュールに対してスタックされます。

const { test } = QUnit;

QUnit.module('My Group', hooks => {
  // It is valid to call the same hook methods more than once.
  hooks.beforeEach(assert => {
    assert.ok(true, 'beforeEach called');
  });

  hooks.afterEach(assert => {
    assert.ok(true, 'afterEach called');
  });

  test('with hooks', assert => {
    // 1 x beforeEach
    // 1 x afterEach
    assert.expect(2);
  });

  QUnit.module('Nested Group', hooks => {
    // This will run after the parent module's beforeEach hook
    hooks.beforeEach(assert => {
      assert.ok(true, 'nested beforeEach called');
    });

    // This will run before the parent module's afterEach
    hooks.afterEach(assert => {
      assert.ok(true, 'nested afterEach called');
    });

    test('with nested hooks', assert => {
      // 2 x beforeEach (parent, current)
      // 2 x afterEach (current, parent)
      assert.expect(4);
    });
  });
});

テストコンテキストの使用

テストコンテキストオブジェクトはフックコールバックに対して公開されます。

QUnit.module('Machine Maker', {
  beforeEach: function () {
    this.maker = new Maker();
    this.parts = ['wheels', 'motor', 'chassis'];
  }
});

QUnit.test('makes a robot', function (assert) {
  this.parts.push('arduino');
  assert.equal(this.maker.build(this.parts), 'robot');
  assert.deepEqual(this.maker.log, ['robot']);
});

QUnit.test('makes a car', function (assert) {
  assert.equal(this.maker.build(this.parts), 'car');
  this.maker.duplicate();
  assert.deepEqual(this.maker.log, ['car', 'car']);
});

ネストされたスコープを使用する場合にもテストコンテキストを使用できます。thisバインディングはアロー関数では使用できないことに注意してください。

const { test } = QUnit;

QUnit.module('Machine Maker', hooks => {
  hooks.beforeEach(function () {
    this.maker = new Maker();
    this.parts = ['wheels', 'motor', 'chassis'];
  });

  test('makes a robot', function (assert) {
    this.parts.push('arduino');
    assert.equal(this.maker.build(this.parts), 'robot');
    assert.deepEqual(this.maker.log, ['robot']);
  });

  test('makes a car', function (assert) {
    assert.equal(this.maker.build(this.parts), 'car');
    this.maker.duplicate();
    assert.deepEqual(this.maker.log, ['car', 'car']);
  });
});

JavaScript独自のレキシカルスコープを使用する方が便利な場合があります。

const { test } = QUnit;

QUnit.module('Machine Maker', hooks => {
  let maker;
  let parts;
  hooks.beforeEach(() => {
    maker = new Maker();
    parts = ['wheels', 'motor', 'chassis'];
  });

  test('makes a robot', assert => {
    parts.push('arduino');
    assert.equal(maker.build(parts), 'robot');
    assert.deepEqual(maker.log, ['robot']);
  });

  test('makes a car', assert => {
    assert.equal(maker.build(parts), 'car');
    maker.duplicate();
    assert.deepEqual(maker.log, ['car', 'car']);
  });
});

Promiseを使用したモジュールフック

フックで非同期thenable Promiseの結果を処理する例です。この例では、データベースへの接続または切断後に満たされるES6 Promiseインターフェースを使用しています。

QUnit.module('Database connection', {
  before: function () {
    return new Promise(function (resolve, reject) {
      DB.connect(function (err) {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  },
  after: function () {
    return new Promise(function (resolve, reject) {
      DB.disconnect(function (err) {
        if (err) {
          reject(err);
        } else {
          resolve();
        }
      });
    });
  }
});

テストのサブセットのみを実行する

QUnit.module.only()を使用して、モジュールのすべてのテストをQUnit.testの代わりにQUnit.test.onlyを使用した場合と同じように扱います。

QUnit.module('Robot', hooks => {
  // ...
});

// Only execute this module when developing the feature,
// skipping tests from other modules.
QUnit.module.only('Android', hooks => {
  let android;
  hooks.beforeEach(() => {
    android = new Android();
  });

  QUnit.test('Say hello', assert => {
    assert.strictEqual(android.hello(), 'Hello, my name is AN-2178!');
  });

  QUnit.test('Basic conversation', assert => {
    android.loadConversationData({
      Hi: 'Hello',
      "What's your name?": 'My name is AN-2178.',
      'Nice to meet you!': 'Nice to meet you too!',
      '...': '...'
    });

    assert.strictEqual(
      android.answer("What's your name?"),
      'My name is AN-2178.'
    );
  });

  // ...
});

QUnit.module.skip()を使用して、モジュールのすべてのテストをQUnit.testの代わりにQUnit.test.skipを使用した場合と同じように扱います。

QUnit.module('Robot', hooks => {
  // ...
});

// Skip this module's tests.
// For example if the android tests are failing due to unsolved problems.
QUnit.module.skip('Android', hooks => {
  let android;
  hooks.beforeEach(() => {
    android = new Android();
  });

  QUnit.test('Say hello', assert => {
    assert.strictEqual(android.hello(), 'Hello, my name is AN-2178!');
  });

  QUnit.test('Basic conversation', assert => {
    // ...
    assert.strictEqual(
      android.answer('Nice to meet you!'),
      'Nice to meet you too!'
    );
  });

  // ...
});

QUnit.module.todo()を使用して、開発中の機能であり、まだすべてのテストに合格していないことがわかっていることを示します。これは、モジュールのすべてのテストをQUnit.testの代わりにQUnit.test.todoを使用した場合と同じように扱います。

QUnit.module.todo('Robot', hooks => {
  let robot;
  hooks.beforeEach(() => {
    robot = new Robot();
  });

  QUnit.test('Say', assert => {
    // Currently, it returns undefined
    assert.strictEqual(robot.say(), "I'm Robot FN-2187");
  });

  QUnit.test('Move arm', assert => {
    // Move the arm to point (75, 80). Currently, each throws a NotImplementedError
    robot.moveArmTo(75, 80);
    assert.deepEqual(robot.getPosition(), { x: 75, y: 80 });
  });

  // ...
});