Markdown 확장 기능 수락 테스트?

안녕하세요!

저는 현재 상당히 많은 수의 BBCode 태그를 추가하는 마크다운 확장 플러그인을 개발 중이며, 이들에 대한 QUnit 인수 테스트를 작성하려고 합니다(매번 수동으로 확인하는 것이 정말 지루해졌고, 태그 수도 많아서요).

해당 태그들은 단순히 HTML을 적용하는 간단한 태그와 이벤트 핸들러가 연결된 복잡한 태그가 섞여 있습니다. 따라서 저는 렌더링된 HTML과 이벤트 핸들러 모두를 테스트해야 합니다.

마크다운 확장 플러그인에 대한 인수 테스트를 여러 개 발견했는데(구체적으로 local-dates-composer-test.js.es6, spoiler-button-test.js-es6, checklist-test.js.es6, pretty-text-test.js)를 참고 자료로 사용했습니다. 이 테스트들은 크게 두 가지 방식으로 나눌 수 있습니다:

  1. 사이트 열기, 새 주제 생성, 에디터에 텍스트 입력을 시뮬레이션한 후 DOM 셀렉터를 통해 출력을 가져오는 방식. (local-dates-composer-test.js.es6, spoiler-button-test.js-es6)
  2. Pretty Text 인스턴스를 생성하여 텍스트를 즉시 렌더링(cook)하고那里的 HTML을 비교하는 방식. (checklist-test.js.es6, pretty-text-test.js) (checklist는 이벤트 처리를 테스트하기 위해 Post 모델 인스턴스도 생성하는 것 같고, 전반적으로 초기화자(initializer)를 테스트하는 것처럼 보입니다.)

두 가지 방법을 모두 시도해 보았으며 어느 정도 성공했습니다. 첫 번째 방법은 꽤 직관적이며 두 번째 방법보다 시간이 더 걸리긴 했지만 원하는 결과를 얻을 수 있었습니다. 두 번째 방법은 테스트 시간이 훨씬 짧았지만 이상한 오류가 발생했습니다.

제 코드와 결과는 다음과 같습니다:

방법 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("Method 1", function (needs) {
  needs.user();
  test("cooking via site", async function (assert) {
    await visit("/");
    await click("#create-topic");

    assert.cooked("hello world", "<p>hello world</p>", "this test works");
  });
});

방법 2: Pretty Text 인스턴스 생성
import { acceptance} from "discourse/tests/helpers/qunit-helpers";
import { cookAsync } from "discourse/lib/text";

acceptance("Method 2", function (needs) {
  needs.user();
  test("cooking using cookAsync", async function (assert) {
    const cooked = await cookAsync("hello world", {});
    assert.equal(cooked, "<p>hello world</p>", "this test also works");
  });
});

현재 이 테스트들은 단순히 “hello world” 텍스트를 렌더링하는 것만 테스트하고 있습니다. 제 자체 태그에 대해 테스트해 보았는데 정상적으로 동작합니다.

방법 2에서 무언가 누락된 것 같아서 afterEach failed ....: this.keyTrapper is null 오류가 발생합니다. 어쨌든 두 가지 방법 모두 동작하며, 간단한 HTML 테스트에는 방법 2를, 이벤트 처리가 포함된 테스트에는 방법 1을 사용해야 한다는 것을 알 수 있습니다.

제 태그 중 상당수가 단순한 HTML이므로, 시간을 절약하기 위해 테스트 중에 방법 2와 방법 1을 함께 사용하려고 합니다. 이 오류를 유발하는 것이 무엇인지, 혹은 아예 더 나은 방법으로 이 테스트를 작성할 수 있는지 알고 싶습니다.

유사한 공식 플러그인에서 어떻게 구현되는지 확인할 수 있습니다.

하지만 그것은 QUnit을 사용하는 것이 아닙니다.

그 이유는 저는 쿠킹(데이터 처리)이 백엔드에서 이루어진다고 생각하기 때문입니다.

프론트엔드에서 이를 시뮬레이션할 수 있으면 좋겠습니다.

참고로 저는 개인적으로 BBCode 플러그인을 테마 컴포넌트로 마이그레이션했습니다. 하지만 모든 테스트를 잃게 되기 때문에 정확히 공개하지는 않았습니다.