我在使用 Cypress 在单页应用程序 (SPA) 中测试路由时遇到问题,特别是在持续集成 (CI) 环境中运行测试时。尽管测试在我的本地机器上以及本地 Cypress 上运行顺利,但在 CI 中执行时我面临着不一致和失败。
让我们考虑视图中的两个链接:
<a id="id_example" href="/en/example/example2">content</a>
<router-link id="id_example_v2" to="/en/example/example2">
content
</router-link>
如果在我的赛普拉斯测试中我这样做:
cy.get('#id_example').click();
然后检查重定向:
cy.wait(10000);
cy.then(() => {
cy.get('a.bg-info').should('be.visible');
cy.location('pathname').should('include', 'example/example2');
});
测试顺利通过,重定向按预期发生。
但是,如果我做同样的事情:
cy.get('#id_example_v2').click();
没有重定向,测试失败。
如果我考虑到链接是相同的并且这个问题只发生在 CI 上,我就会相信它一定与工作流程的配置有关......这是我的工作流程 .github/workflows/tests.yml
steps:
- uses: actions/checkout@v3
- name: Use Node
uses: actions/setup-node@v3
with:
node-version: lts/*
cache: 'npm'
- name: Install
run: npm install
- name: Install Cypress Dependencies
run: apt-get update && apt-get install -y libgtk2.0-0 libgtk-3-0 libgbm-dev libnss3 libasound2 libxss1 libxtst6 xauth xvfb firefox-esr
- name: Run Cypress tests
env:
NODE_ENV: test
uses: cypress-io/github-action@v6
with:
start: npm run dev
browser: firefox
经检查,两种情况下在DOM中创建的a标签是相同的。唯一的区别在于 Vue Router 处理的客户端路由。
无法通过路由器链路实现重定向。我再说一遍,这只发生在 GitHub Actions CI 上。绝不在本地,绝不在本地 Cypress 上,也绝不在本地以无头模式使用 Cypress。
还有其他人遇到过类似的问题吗?有人可以解释我的情况或提供一些关于如何解决这个问题的见解吗?
使用
cy.wait(10000)
是你的片状测试的根本原因是CI。原因是 CI 机器性能取决于旋转速度和当前服务器负载。
您可能会猜测,根据本地性能,应用程序更改路线所需的时间不到 10 秒,您可能会猜错的时间百分比。
因此,Cypress 告诉我们,使用艰难的等待时间是不好的做法。
反模式: 使用 cy.wait(Number) 等待任意时间段。
相反,您应该等待页面转换中的内容,无论是什么
最佳实践:使用路由别名或断言来保护 Cypress 继续进行,直到满足明确的条件为止。
<router-link id="id_example_v2" to="/en/example/example2">
content <-- wait for this
</router-link>
cy.get('#id_example_v2').click()
cy.contains(<some-content>, {timeout:10_000})