我正在尝试为柏树设置一个 e2e 测试套件。我要测试的项目有点像vercel。它有多个 git 供应商,您可以从该 git 供应商登录并托管您的代码。
我正在尝试创建一个我可以使用的简单函数,它可以为所有不同的提供商运行测试。
这是我现在拥有的自定义命令:
// commands.js
Cypress.Commands.add("loginToProviders", (callback) => {
// login with github
cy.loginGithub();
callback("github");
cy.clearCookies();
// login with bitbucket
cy.loginBitbucket();
callback();
cy.clearCookies();
// login with gitlab
cy.loginGitlab();
callback();
cy.clearCookies();
});
这就是我想象的测试应该看起来的样子:
// providertest.spec.cy.js
describe("test login for all providers", () => {
cy.loginToProvider((provider) => {
it(`test login of ${provider}`, () => {
cy.visit("/");
cy.url().should("be.equal", `${Cypress.config("baseUrl")}/`);
});
});
});
我遇到的问题是你不能在测试之外运行 cy 命令。我正在努力寻找此类情况的文档,有谁知道我在哪里可以找到更多描述我的案例的信息。或者我应该如何重构代码的任何指示。任何帮助表示赞赏
你不能在测试之外运行 cy 命令 - 正确,所以一个答案是将自定义命令更改为函数,并将
it()
块移动到函数内。
function testEachProvider(callback) {
// login with github
it('test login of github', () => {
cy.loginGithub();
callback("github");
cy.clearCookies();
})
// login with bitbucket
it('test login of bitbucket', () => {
cy.loginBitbucket();
callback("bitbucket");
cy.clearCookies();
})
// login with gitlab
it('test login of gitlab', () => {
cy.loginGitlab();
callback("gitlab");
cy.clearCookies();
})
})
describe("test login for all providers", () => {
testEachProvider((provider) => {
cy.visit("/");
cy.url().should("be.equal", `${Cypress.config("baseUrl")}/`);
});
})
另一种结构是一个简单的循环,参数化登录命令名。使用此处描述的模式赛普拉斯夹具的动态测试
由于命令是
cy
的属性,您应该能够按名称提取正确的登录命令并使用 ()
调用它。
const providers = ['github', 'bitbucket', 'gitlab']
providers.forEach(provider => {
it(`tests ${provider}`, () => {
cy.clearCookies()
const capFirstProvider = provider.charAt(0).toUpperCase() + provider.slice(1)
const loginCommand = `login${capFirstProvider}`
cy[loginCommand]() // invoke login command
cy.visit("/");
cy.url().should("be.equal", `${Cypress.config("baseUrl")}/`)
})
})
请注意,如果您使用
testIsolation
的默认 true
设置,则不需要 cy.clearCookies()
- Cypress 会为您完成此操作以及一系列其他清理步骤。
您可以使用对象数组概括动态数据。
const providers = [
{ name: 'github', loginCommand: 'loginGithub' },
{ name: 'bitbucket', loginCommand: 'loginBitbucket' },
{ name: 'gitlab', loginCommand: 'loginGitlab' }
]
providers.forEach(provider => {
it(`tests ${provider.name}`, () => {
cy[provider.loginCommand]() // invoke login command
cy.visit("/");
cy.url().should("be.equal", `${Cypress.config("baseUrl")}/`)
})
})
我认为重组以及您如何看待您的测试在这里可能很有价值。与其让它们全部在自定义命令中运行,不如让自定义命令接受一个参数并相应地执行操作。
// Custom command that only runs the login command depending on provider
Cypress.Commands.add('loginToProvider', (provider) => {
if (provider === 'Github') {
return cy.loginGithub();
} else if (provider === 'Bitbucket') {
return cy.loginBitbucket();
} else if (provider === 'Gitlab') {
return cy.loginGitlab();
} else {
return cy.wrap(null); // arbitrary else statement
}
});
// Tests.js
// define potential providers
const providers = ['Github', 'Bitbucket', 'Gitlab']
describe('Provider Tests', () => {
// Use Cypress Lodash to iterate through providers array
Cypress._.times(providers.length, (index) => {
const provider = providers[index];
beforeEach(() => {
cy.clearCookies(); // unsure if necessary, but recommended to clear before each test runs
});
it(`Tests Login for Provider: ${provider}`, () => {
cy.loginToProvider(provider);
cy.visit('/');
cy.url().should('be.equal', `${Cypress.config('baseUrl')}/`);
})
})
});