Недетерминированные проблемы юнит-тестов с аурелией - PullRequest
0 голосов
/ 01 июня 2018

Этот вопрос относится к моему другому вопросу .Я кратко повторяю некоторые детали.Я хочу протестировать свои пользовательские элементы aurelia, как показано ниже.

// BaseText.ts
import { bindable } from "aurelia-framework";
import { BaseI18N } from "aurelia-i18n";

export class BaseText extends BaseI18N {
    @bindable public value: string;
    @bindable public i18nKey: string;
}

// NormalText.html; NormalText inherits from BaseText
<template>
    <span t.bind="i18nKey">${value}</span>
</template>

// ValueText.html; ValueText inherits from BaseText
<template>
    <strong t.bind="i18nKey">${value}</strong>
</template>

Теперь я хочу протестировать представления для этих пользовательских элементов, которые имеют форму ниже.

describe("View specs", () => {

    it("Should render the text in a strong element without any additional style", (done) => {
        const randomId = randomIdGenerator();
        const component = StageComponent
            .withResources("ValueText/ValueText")
            .inView(`<value-text id='${randomId}' value='Hello Static Text'></value-text>`);

        component
            .create(bootstrap)
            .then(() => {
                const strongElement: HTMLElement = document.querySelector(`value-text#${randomId}>strong`);
                console.log(strongElement);
                expect(strongElement).toBeDefined();
                expect(strongElement.style.cssText).toBeFalsy();
                expect(Array.from(strongElement.classList).filter(item => !item.startsWith("au-")).length).toBe(0);
            })
            .catch(e => { console.log(e.toString()) })
            .finally(() => {
                component.dispose();
                done();
            });
    });

    it("Should render a dynamic text", (done) => {
        const randomId = randomIdGenerator();
        const component1 = StageComponent
            .withResources("ValueText/ValueText")
            .inView(`<value-text id='${randomId}' value.bind='boundValue'></value-text>`)
            .boundTo({ boundValue: "Hello Value Text" });

        component1
            .create(bootstrap)
            .then(() => {
                const strongElement = document.querySelector(`value-text#${randomId}>strong`);
                expect(strongElement.textContent.trim()).toBe('Hello Value Text');
            })
            .catch(e => { console.log(e.toString()) })
            .finally(() => {
                component1.dispose();
                done();
            });
    });

    it("Should render the provided static text without i18nKey", (done) => {
        const randomId = randomIdGenerator();
        const component2 = StageComponent
            .withResources("ValueText/ValueText")
            .inView(`<value-text id='${randomId}' value='Hello Static Text'></value-text>`);

        component2
            .create(bootstrap)
            .then(() => {
                const strongElement = document.querySelector(`value-text#${randomId}>strong`);
                expect(strongElement.textContent.trim()).toBe('Hello Static Text');
            })
            .catch(e => { console.log(e.toString()) })
            .finally(() => {
                component2.dispose();
                done();
            });
    });

});

Хотя здесь я показал тесты для ValueText, тесты для NormalText также выглядят очень похоже.

Когда я запускаю наборы тестов для обоих этих элементов по отдельности, все тесты работают нормально.Однако, когда они выполняются вместе, элемент undefined возвращается document.querySelector('...') для некоторых тестовых случаев.В результате чего не выполняются утверждения expect.Это привело к ошибке ниже.

Spec 'HERE_GOES_SPEC_NAME' не имеет ожиданий.

image image

После некоторой отладки кажетсячто, когда тесты выполняются вместе, для набора тестов, который запускается вторым, представление для пользовательских элементов даже не создается.Он создает элемент DOM следующим образом.

<normal-text value="Hello Static Text"></normal-text>

Но часть вида innerHTML отсутствует.Более формально, во время этих тестов связанная модель представления / контроллер остается отсутствующей в шаблонах aurelia, что приводит к искаженному представлению.

Что я должен изменить, чтобы эти тесты стали детерминированными?

Дополнительная информация: Я создал GitHub repo , чтобы заинтересованный читатель / пользователь мог воспроизвести проблему.Помните, что вы могли запускать тесты несколько раз, чтобы повторить проблему.

1 Ответ

0 голосов
/ 06 июня 2018

После долгих сеансов отладки оказалось, что для ошибочных спецификаций теста (т. Е. Набора тестов, который запускается вторым) метаданные были неверными.Например, если сначала запускается набор тестов для NormalText, то для набора тестов ValueText метаданные ValueText отражают метаданные NormalText;более конкретно ресурсы HTML (view): NormalText.

Возможно, где-то есть ошибка или проблема с тем, как я написал тесты.

Однако я нашел простой обходной путьприменив декоратор @customElement("element-name") к обоим классам.И это действительно решило проблему.

...