Markdown拡張機能の受け入れテスト?

こんにちは!

現在、多くの BBCode タグを追加する Markdown 拡張機能(プラグイン)の開発に取り組んでおり、それらに対する QUnit のアクセプタンステストを作成しようとしています(手動での確認に疲れ果ててしまい、タグの数も多いためです)。

対象となるタグは、単に HTML を適用する単純なタグと、イベントハンドラが紐付けられている複雑なタグが混在しています。そのため、生成された HTML とイベントハンドラの両方をテストする必要があります。

いくつかの Markdown 拡張機能のアクセプタンステスト(具体的には local-dates-composer-test.js.es6spoiler-button-test.js-es6checklist-test.js.es6、および pretty-text-test.js)に出会い、これらを参考にしました。これらは広義には、テストを実行する 2 つの方法に大別できます。

  1. サイトの起動、新規トピックの作成、エディタ内へのテキスト入力をシミュレートし、DOM 上のセレクタを通じて出力を取得する方法。(local-dates-composer-test.js.es6spoiler-button-test.js-es6
  2. Pretty Text のインスタンスを即座に作成してテキストを生成(cooking)し、HTML を比較する方法。(checklist-test.js.es6pretty-text-test.js)(checklist はイベントハンドラのテストのために Post モデルのインスタンスも作成しており、全体としてイニシャライザをテストしているように見えます)

私は両方の方法を試しており、概ね成功しています。1 番目の方法は非常に直感的で、2 番目の方法よりも時間がかかるものの、目的の成果を得ることができました。2 番目の方法もはるかに高速なテスト時間で成功させましたが、奇妙なエラーが発生しています。

以下に私のコードと結果を示します。

方法 1: サイトの起動をシミュレート
import { acceptance, queryAll } from "discourse/tests/helpers/qunit-helpers";

QUnit.assert.cooked = async function (input, expected, message) {
  await fillIn(".d-editor-input", input);
  const actual = queryAll(".d-editor-preview")[0].innerHTML;
  this.pushResult({
    result: actual === expected.replace(/\/>/g, ">"),
    actual,
    expected,
    message,
  });
};

acceptance("方法 1", function (needs) {
  needs.user();
  test("サイト経由での生成", async function (assert) {
    await visit("/");
    await click("#create-topic");

    assert.cooked("hello world", "<p>hello world</p>", "このテストは動作します");
  });
});

方法 2: Pretty Text インスタンスの作成
import { acceptance} from "discourse/tests/helpers/qunit-helpers";
import { cookAsync } from "discourse/lib/text";

acceptance("方法 2", function (needs) {
  needs.user();
  test("cookAsync を使用した生成", async function (assert) {
    const cooked = await cookAsync("hello world", {});
    assert.equal(cooked, "<p>hello world</p>", "このテストも動作します");
  });
});

現在、これらは単に「hello world」というテキストの生成をテストするものになっています。独自のカスタムタグに対してもテストを行いましたが、それらは動作しています。

方法 2 について何か見落としているのだと思います。エラー afterEach failed ....: this.keyTrapper is null が発生しているためです。いずれにせよ、両方の方法は動作しており、HTML の単純なテストには方法 2 を、イベントハンドラを伴うテストには方法 1 を使用するべきだと理解しています。

私のタグの多くは単なる単純な HTML であるため、時間を節約するためにテスト中に方法 2 と方法 1 を併用したいと考えています。そのエラーを引き起こしている欠落している要素、あるいはテスト全体を書くためのより良い方法があれば知りたいです。

類似の公式プラグインの実装例をご覧ください。

ただし、それは QUnit を使用していません。

理由は、調理(処理)はバックエンド側で行われていると考えているからです。

フロントエンド側でもそれをシミュレートできるといいですね。

余談ですが、私は個人的に BBCode プラグインをテーマコンポーネントに移行しました。しかし、すべてのテストが失われてしまうため、まだ公開していません。