更多的柏树最佳实践
#javascript #cypress #测试

这些是我在有关赛普拉斯的其他任何文章中都没有看到的其他柏树最佳实践。

使用eslint-plugin-cypress

避免反遗产的最佳方法是拥有一种工具,可以尽早为您捕捉它们。

确保启用所有可用规则:

{
  "extends": [
    "plugin:cypress/recommended"
  ],
  "rules": {
    "cypress/no-force": "error",
    "cypress/assertion-before-screenshot": "error",
    "cypress/require-data-selectors": "error",
    "cypress/no-pause": "error",
  }
}

并确保阅读有关每个规则以提高您对柏树的理解。

使用UI主张来减少测试片状

如果您发现某个动作有时比应提前执行,请在其之前添加一个UI主张。

在此示例中,我们要等待评论出现,然后再添加另一个,否则,我们可能会出现片状的种族条件:

  cy.findByRole("textbox", { name: "Comment" }).type("My first comment");
  cy.findByRole("button", { name: "Post comment" }).click();
+ cy.findByText("My first comment").to("be.visible");
  cy.findByRole("textbox", { name: "Comment" }).type("My second comment");
  cy.findByRole("button", { name: "Post comment" }).click();

使用UI主张减少屏幕截图片状

这就是koude0规则的内容。如果您在没有断言的情况下进行屏幕截图,则可能会根据时机获得不同的屏幕截图。

不幸的是,该规则仅适用于默认的cy.screenshot()命令,因此,如果您使用其他规则,例如cy.percySnapshot()

在此示例中,在发布新帖子后,我们要等待它出现在UI中,然后进行屏幕截图:

  cy.findByRole("button", { name: "Publish" }).click();
+ cy.findByRole("heading", { name: "My new post" }).to("be.visible");
  cy.percySnapshot("Posts - new post");

使用功能创建可重复使用的命令

在大多数情况下,执行单个有意义的动作将涉及执行多个命令和断言。如果您发现自己一遍又一遍地重复相同的命令,请创建一个使它们抽象的函数。

export function goToPosts() {
  cy.findByAltText("Menu").trigger("mouseover");
  cy.findByRole("link", { name: "Posts" }).click();
}

export function createPost(name: string, content: string) {
  cy.findByRole("textbox", { name: "Post name" }).type(name);
  cy.findByRole("textbox", { name: "Post content" }).type(content);
  cy.findByRole("button", { name: "Publish" }).click();
  cy.findByRole("heading", { name }).to("be.visible");
}

export function addComment(comment: string) {
  cy.findByRole("textbox", { name: "Comment" }).type(comment);
  cy.findByRole("button", { name: "Post comment" }).click();
  cy.findByText(comment).to("be.visible");
}

export function deletePost(postName: string) {
  cy.findByRole("button", { name: `Open ${postName} menu` }).click();
  cy.findByRole("button", { name: `Delete ${postName}` }).click();
  cy.findByRole("button", { name: "Yes" }).click();
}

它将使您的测试简洁明了:

describe("Posts", () => {
  it("can create a new post", () => {
    const postName = "My new post";

    goToPosts();

    createPost(postName, "My post content");

    addComment("My first comment");
    addComment("My second comment");

    cy.findByText("My second comment").to("be.visible");
    cy.screenshot();

    deletePost(postName);
  });
});

使生产代码更容易访问

如果您发现不可能或难以使用可访问的Testing Library查询,请继续进行更改代码以使其更容易访问。这将使您的用户更加快乐,并且您的测试降低了依赖于实施详细信息。

- <div onClick={handleClick}>
+ <button type="button" onClick={handleClick}>
    Create post
- </div>
+ </button>

使用cypress-plugin-steps

如果您发现自己在柏树测试中经常使用代码注释,请考虑使用Cypress-Plugin-Steps中的cy.step()。它将在测试日志中显示消息,如果您的测试失败,则您的方案将添加到错误消息中,并且更容易查明失败的命令。

- // Go to posts
+ cy.step("Go to posts");
  cy.findByAltText("Menu").trigger("mouseover");
  cy.findByRole("link", { name: "Posts" }).click();

- // Delete post
+ cy.step("Delete post");
  cy.findByRole("button", { name: 'Open "My new post" menu' }).click();
  cy.findByRole("button", { name: 'Delete "My new post"' }).click();
  cy.findByRole("button", { name: "Yes" }).click();

如果您喜欢这篇文章,则应查看
Cypress Best Practices that are actually bad