Привет!
Сейчас я работаю над расширением/плагином для Markdown, который добавляет довольно много тегов BBCode, и планирую написать для них acceptance-тесты в QUnit (мне надоело постоянно проверять их вручную, а их очень много).
Речь идёт о смеси простых тегов, которые просто оборачивают HTML, и сложных тегов, к которым привязаны обработчики событий. Поэтому мне нужно тестировать как итоговый HTML, так и работу обработчиков событий.
Я нашёл несколько примеров acceptance-тестов для расширений Markdown (а именно local-dates-composer-test.js.es6, spoiler-button-test.js-es6, checklist-test.js.es6 и pretty-text-test.js), которые использовал в качестве ориентиров. Эти тесты можно условно разделить на два подхода:
- Имитация открытия сайта, создания новой темы и ввода текста в редакторе, с последующим получением результата через селектор в DOM. (local-dates-composer-test.js.es6, spoiler-button-test.js-es6)
- Создание экземпляра Pretty Text для немедленной обработки текста и сравнение полученного HTML. (checklist-test.js.es6, pretty-text-test.js) (в тесте checklist также создаётся экземпляр модели Post для проверки обработчиков событий, и в целом кажется, что тестируется инициализатор).
Я попробовал оба метода и в целом добился успеха. Первый метод довольно прост, и я получил нужный результат, хотя это заняло больше времени, чем второй. Второй метод я также успешно реализовал, и тесты выполняются значительно быстрее, но при этом я получаю странную ошибку.
Вот мой код и результаты:
Метод 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 в тестах, чтобы сэкономить время. Хотел бы узнать, чего именно мне не хватает, из-за чего возникает эта ошибка, или есть ли ещё более эффективный способ написания таких тестов в целом.

