解决与i18next相关的Aurelia自定义元素单元测试间歇性失败问题
Fixing Flaky Aurelia I18n Custom Element Tests
我之前碰到过一模一样的Aurelia i18n自定义元素测试不稳定问题,核心原因确实是i18next的异步初始化还没完成,测试就开始断言DOM内容了。本地偶尔成功是因为初始化速度快,但CI环境资源有限,初始化延迟更明显,所以必然失败。下面是我验证过的可靠解决方案:
1. 确保I18n插件初始化完全完成
首先,修改bootstrap配置,让插件的setup操作完全完成后再继续Aurelia的启动流程。把bootstrap函数改成异步,等待instance.setup()的Promise完成:
beforeEach(() => { component = StageComponent .withResources("NormalText/NormalText") .inView("<normal-text id='i18n1' value='Ignored Text' i18n-key='test'></normal-text>"); component.bootstrap(async (aurelia: Aurelia) => { await aurelia.use .standardConfiguration() .plugin(PLATFORM.moduleName("aurelia-i18n"), async (instance) => { const aliases = ["t"]; TCustomAttribute.configureAliases(aliases); // 等待i18n setup完成 await instance.setup({ attributes: aliases, fallbackLng: "en", lng: "en", resources: { en: { translation: { test: "English test" } } } }); }); }); });
2. 测试用例中显式等待I18n就绪
即使bootstrap里等待了setup,有时候组件渲染和i18n的翻译更新还是存在时序问题。我们可以直接获取I18n服务实例,等待它的initializedPromise(这是Aurelia i18n提供的专门用于等待初始化完成的Promise):
it("Should render the translated text with a i18nKey", async () => { try { await component.create(bootstrap); // 获取I18n服务实例,等待初始化完成 const i18n = component.container.get(I18n); await i18n.initializedPromise; const spanElement = document.querySelector('normal-text#i18n1 > span'); expect(spanElement.textContent.trim()).toBe('English test'); } finally { component.dispose(); } });
为什么这样能解决问题?
instance.setup()本身是异步操作,它会加载翻译资源、初始化i18next实例,之前的代码没有等待这个过程完成就启动了组件,导致渲染时翻译还没准备好。i18n.initializedPromise是Aurelia i18n插件暴露的一个Promise,会在i18next完全初始化、所有资源加载完成后resolve,确保我们的断言时机是完全安全的。- 改用
async/await代替then/catch让代码更清晰,也更容易处理异步时序问题。
这样修改后,不管是本地多次运行还是CI环境,测试都会稳定通过,不会再出现间歇性失败的情况。
内容的提问来源于stack exchange,提问作者Sayan Pal
相关产品推荐
相关产品推荐

