【问题标题】:Intermittent unit-test failure associated with i18next与 i18next 相关的间歇性单元测试失败
【发布时间】:2018-11-09 05:55:57
【问题描述】:

我正在尝试对我的 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.ts
export class NormalTextCustomElement extends BaseText {}

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

现在,我想测试如果我更改i18nKey 的值,翻译后的文本会显示在元素中。为了测试这一点,我编写了以下测试用例。

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

    let component;
    beforeEach(() => {
        component = StageComponent
            .withResources("NormalText/NormalText")
            .inView("<normal-text id='i18n1' value='Ignored Text' i18n-key='test'></normal-text>");

        component.bootstrap((aurelia: Aurelia) => aurelia.use
            .standardConfiguration()
            .plugin(PLATFORM.moduleName("aurelia-i18n"), (instance) => {
                const aliases = ["t"];
                TCustomAttribute.configureAliases(aliases);

                return instance.setup({
                    attributes: aliases,
                    fallbackLng: "en",
                    lng: "en",
                    resources: {         //<-- translation resources
                        en: {
                            translation: {
                                test: "English test"
                            }
                        }
                    }
                });
            }));

    });

    it("Should render the translated text with a i18nKey", (done) => {
        component
            .create(bootstrap)
            .then(() => {
                const spanElement = document.querySelector('normal-text#i18n1>span');
                expect(spanElement.textContent.trim()).toBe('English test');
            })
            .catch(e => { console.log(e.toString()) })
            .finally(() => {
                component.dispose();
                done();
            });
    });
});

现在的问题是这个测试用例间歇性地失败,这肯定是 CI 的问题。我怀疑它与i18next的初始化有关,并且在初始化完成之前测试用例正在运行。虽然我不太确定这个假设。

我应该改变什么,以使这个测试用例成为确定性的?

其他信息:

  1. 如果此测试用例在所有其他 view related test cases 之前运行,则此测试用例成功。
  2. 我创建了一个GitHub repo,以便感兴趣的读者/用户可以重现该问题。请记住,您可能已经多次运行测试来重现问题。

【问题讨论】:

    标签: javascript unit-testing jasmine i18next aurelia


    【解决方案1】:

    事实证明,这个问题实际上与我编写测试用例的方式有关。

    之前我的结构如下。

    describe("View specs", ()=> {
      // here goes other test suite and/or test cases
      describe("i18n specs", () => {
    
        let component;
        beforeEach(() => {
          // here goes the custom initialization code of aurelia, as shown in question
        });
      });
    });
    

    我认为这个自定义初始化代码干扰了默认引导的其他测试用例。我只是简单地从i18n specs 中取出beforeEach 并将其直接放在View specs 测试套件下。这意味着View specs 测试套件下的所有测试用例都使用相同的 aurelia 引导设置。实际上,这确实解决了我的问题。

    【讨论】:

      【解决方案2】:

      猜你是对的。 i18next 的初始化调用是异步的。表示它不会在测试运行之前完成。

      您不想测试翻译本身 - 因此将测试用例的语言设置为“cimode”将导致键而不是翻译值的一致返回。

      【讨论】:

      • 感谢您的回答。我知道使用cimode 使测试更容易,因为我不必明确指定任何翻译资源。但是,在运行测试用例之前初始化 i18next 的问题仍然存在。
      • 不应该受到伤害。初始化调用将完成 - 但翻译结果基于 cimode 始终键 - 初始化完成与否。如果仍然快速 -> 在运行测试之前未设置 cimode -> i18next.com/overview/configuration-options#initimmediate 并最终在 init 上添加一个空资源:{},因此它不会通过 xhr 加载任何翻译
      • 我找到了一个更简单的解决方案来解决我的问题。我将其发布为答案。但是,您的答案提供了一些有用的工具来简化测试。谢谢你:)
      猜你喜欢
      • 2015-02-27
      • 2018-11-11
      • 2017-08-11
      • 2016-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-27
      相关资源
      最近更新 更多