全面的基于 Playwright 的ui自动化测试,使用页面对象模型的模块化框架
· 1,187 词 · 6 分钟 读完 playwright进阶 翻译
关键特性
- 模块化设计:通过为“操作”和“断言”创建单独的类,促进代码的重用性和可维护性。
- 数据生成:支持使用工具函数和 API 调用生成测试数据。
- 页面对象模型:用于维护页面元素定位器的通用类。
- Fixture:提供一致且高效的统一配置和钩子函数。
核心组件介绍
页面对象模型(POM)
页面对象模型是一种设计模式,鼓励更好的测试维护并减少代码重复。它将页面细节抽象为对象,使测试人员能够编写更具可读性和更强健的测试用例,尤其适用于 Web 应用程序测试。
页面对象(pages/)
页面对象代表被测试的 Web 应用程序的页面元素定位符。
操作(actions/)
我们为操作创建了单独的类,这些操作使用页面对象与 UI 进行交互。
断言(assertions/)
我们为断言创建了单独的类,这些断言在执行操作后验证应用程序的状态,确保应用程序表现如预期。
工具(utils/)
工具函数提供可在测试中重复使用的通用功能,例如生成随机图书数据。
测试用例(tests/e2e/)
测试用例定义 ui 自动化的测试场景,聚焦于应用程序的特定功能或特性。
用例 1:在此测试中,我们调用“generateRandomBookData”函数生成测试数据,并将其作为参数传递到测试中。
import { test } from "../../fixtures/addBooks_fixture.js";
import generateRandomBookData from "../../utils/generateRandomBookData.js";
test.describe.serial("添加图书功能", () => {
let title, isbn, genre, summary;
test.beforeAll(() => {
// 在所有测试之前生成一次图书数据
const bookData = generateRandomBookData();
({ title, isbn, genre, summary } = bookData); // 解构并分配给局部变量
});
test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:3000/books");
});
test("验证-> 新书添加", async ({ addBookActions, addBookAssertions }) => {
// 在我们的测试中使用生成的图书数据
await addBookAssertions.nodataValidationisPresent();
await addBookActions.clickaddBook(title, genre, isbn, summary);
await addBookAssertions.verifyBookInTable(title);
await addBookAssertions.nodataValidationisNotPresent();
});
});
用例 2:在此测试中,当我们无法在 UI 中生成数据,并且需要通过 API 调用获取测试数据时,可以在 before hooks 中调用 API。
import { test } from "../../fixtures/updateBooks_fixture.js";
import generateRandomBookData from "../../utils/generateRandomBookData.js";
import { addBookViaAPI } from "../../requests/addBooks.js";
test.describe.serial("查看更多,编辑,删除功能", () => {
test.beforeAll(() => {
// 使用requests/addBooks.js文件生成图书数据
addBookViaAPI(generateRandomBookData());
});
test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:3000/books");
});
test("验证-> 查看更多功能", async ({ page, updateBookActions }) => {
await updateBookActions.clickviewMore();
});
test("验证-> 编辑功能", async ({
page,
updateBookActions,
updateBookAssertions,
}) => {
await updateBookActions.clickeditBook();
await updateBookAssertions.verifyUpdatedBookInTable("_editText");
});
test("验证-> 删除功能", async ({
page,
updateBookActions,
updateBookAssertions,
}) => {
await updateBookActions.clickdeleteBook(); // 删除在此测试中添加的书籍
await updateBookAssertions.verifyBookNotIntable("_editText");
await updateBookActions.clickdeleteBook(); // 删除剩余的另一书籍
await updateBookAssertions.nodataValidationisPresent();
});
});
通过 Fixture 增强测试
Fixture 管理测试的配置和解变量的过程,初始化数据、配置测试环境或分配测试可能需要的资源。
使用 Fixture 的好处
- 一致性:确保每个测试在相同条件下运行。
- 效率:智能管理资源,加快测试过程。
实现 Fixture
我们的框架利用 Playwright 的 Fixture 来增强测试工作流,管理 BrowserContext、页面对象、操作和断言的自定义 Fixture。
import { test as baseTest } from "@playwright/test";
import { AddBookActions } from "../pages/addBooks/addBooks_actions";
import { AddBooksAssertions } from "../pages/addBooks/addBooks_assertions";
import { AddBookPageObjects } from "../pages/addBooks/addBooks_pageObjects";
export const test = baseTest.extend({
context: async ({ browser }, use) => {
const context = await browser.newContext();
await use(context);
},
page: async ({ context }, use) => {
const page = await context.newPage();
await use(page);
},
addBookActions: async ({ page }, use) => {
await use(new AddBookActions(new AddBookPageObjects(page)));
},
addBookAssertions: async ({ page }, use) => {
await use(new AddBooksAssertions(new AddBookPageObjects(page)));
},
});
export default test;
import { test as baseTest } from "@playwright/test";
import { UpdateBookActions } from "../pages/UpdateBooks/UpdateBooks_actions";
import { UpdateBooksAssertions } from "../pages/UpdateBooks/UpdateBooks_assertions";
import { UpdateBookPageObjects } from "../pages/UpdateBooks/UpdateBooks_pageObjects";
// 使用附加属性扩展基础测试Fixture以支持UpdateBookActions和UpdateBooksAssertions
export const test = baseTest.extend({
context: async ({ browser }, use) => {
const context = await browser.newContext();
await use(context);
},
page: async ({ context }, use) => {
const page = await context.newPage();
await use(page);
},
updateBookActions: async ({ page }, use) => {
await use(new UpdateBookActions(new UpdateBookPageObjects(page)));
},
updateBookAssertions: async ({ page }, use) => {
await use(new UpdateBooksAssertions(new UpdateBookPageObjects(page)));
},
});
export default test;
测试数据生成
项目使用定义在 utils/generateRandomBookData.js 中的工具函数生成随机图书数据。此函数利用 randomatic 包生成随机字符串和数字,然后将它们组合形成图书数据,包括“标题、类型、ISBN 和摘要”。以下是数据生成的简要概述:
- 标题:一个以“Book ”为前缀,后跟 5 个字母和数字组成的字符串。
- 类型:从预定义的类型列表中随机选择。
- ISBN:一个表示为字符串的随机 13 位数字。
- 摘要:一个包含生成标题的简单字符串。
这些生成的数据用于测试中,以添加、更新或验证应用程序中的书籍,确保测试具有多样性的数据点。
来源
https://medium.com/@kbalaji.kks/comprehensive-playwright-powered-end-to-end-testing-modular-framework-using-page-object-model-5143db40a15b
发布时间: 2024-03-12