使用Playwright的Fixtures和POM模式進(jìn)行高效測(cè)試的那些事兒
Fixture和传统的页面对象模型(POM)都用于测试自动化,但它们有不同的用途,可以结合起来使用以获得更好的效果。Fixtures帮助设置和管理测试环境,而POM用于组织页面交互。在Playwright中,您可以使用Fixtures来处理POM实例,从而使测试更加整洁和易于维护。
传统POM方法?POM(页面对象模型,Page Object Model)是一种设计模式,其中每个页面都有一个单独的类,并在每个测试中手动实例化这些类。
class LoginPage {
constructor(page) { // 构造函数,初始化页面对象和其他登录元素
this.page = page;
this.usernameInput = "#username"; // 用户名输入框的标识符
this.passwordInput = "#password"; // 密码输入框的标识符
this.loginButton = "#login"; // 登录按钮的标识符
}
async goToLoginPage() { // 导航到登录页面
await this.page.goto("https://example.com/login");
}
async enterUsername(username) { // 输入用户名
await this.page.fill(this.usernameInput, username);
}
async enterPassword(password) { // 输入密码
await this.page.fill(this.passwordInput, password);
}
async clickLoginButton() { // 点击登录按钮
await this.page.click(this.loginButton);
}
}
export { LoginPage };
import { test, expect } from "@playwright/test";
import { LoginPage } from "../pages/loginPage";
test("登录测试用例", async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goToLoginPage();
await loginPage.enterUsername("testuser");
await loginPage.enterPassword("password");
await loginPage.clickLoginButton();
expect(await page.url()).toBe("https://example.com/home");
});
POM方法的传统限制
- 代码重复 — 每个测试中你都必须创建
new LoginPage(page)
。 - 难以维护 — 如果
LoginPage
发生变化,所有使用它的测试文件都需要更新。 - 测试设置更冗长 — 每个测试中都有重复的初始化代码 (
new LoginPage(page)
)。
内置的 fixtures 是 内置机制,用于管理可重用的对象(如 LoginPage
)。而不是手动创建,fixtures 会自动注入这些对象,使语言更加简洁流畅。
让我们看看下面的代码,其中包含一个 loginPage 类,一个测试辅助类,最后是一个我们在其中执行测试用例的测试类。
loginPage.js
(同一个页面对象)
class LoginPage {
constructor(page) {
this.page = page;
this.用户名输入 = "#username";
this.密码输入 = "#password";
this.登录按钮 = "#login";
}
async 异步跳转到登录页面() {
await this.page.goto('https://example.com/login');
}
async 输入用户名(username) {
await this.page.fill(this.用户名输入, username);
}
async 输入密码(password) {
await this.page.fill(this.密码输入, password);
}
async 点击登录按钮() {
await this.page.click(this.登录按钮);
}
}
导出 { LoginPage };
fixture.js
(Fixture 定义文件)
我们可以为你创建自定义的测试固定,提供可重复使用的对象或操作。例如,你提供的代码中的 loginPage
就是一个用于与登录页面交互的自定义固定。
import { test as base } from "@playwright/test";
import { LoginPage } from "../pages/loginPage";
export const test = base.extend({
loginPage: async ({ page }, use) => {
const loginPage = new LoginPage(page);
await use(loginPage);
}
});
export { expect } from "@playwright/test";
这段代码的主要功能:
- 自定义测试固定:它创建了一个自定义的固定用例(
loginPage
),使用当前的浏览器page
对象来初始化为LoginPage
类。 - 扩展基础测试:这个固定用例在通过扩展的
test
函数定义的测试中可用。 - 使用
**LoginPage**
:loginPage
固定用例可以被注入到测试中,用于与登录页面进行交互,例如输入凭据或点击登录按钮等操作。 - 导出的
**expect**
是一个断言库,可以用于测试断言。
以下代码段测试了web应用程序的登录功能部分,使用了自定义的loginPage
测试用例来验证登录页面的功能。
import { test, expect } from "../utils/fixture";
test("自动化登录测试用例", async ({ loginPage }) => {
await loginPage.进入登录页面();
await loginPage.输入用户名("testuser");
await loginPage.输入密码("password");
await loginPage.点击登录按钮();
expect(await loginPage.page.url()).toBe("https://example.com/home");
});
基于测试固件的方法的好处?
请注意,这里的“Fixture-Based Approach”直接翻译为“基于测试固件的方法”,在特定语境下可能需要进一步明确,但根据原文,这是最直接的翻译。
使用fixtures(就像你在代码里做的那样)可以避免重复,并使测试更加清晰和整洁。
1️不必在每个测试中都创建对象。
在每个测试中,我们不再使用 const loginPage = new LoginPage(page);
,而是自动注入 loginPage
,利用 Playwright 的 fixture 功能。
提高可读性和易于维护性
- 如果
LoginPage
的构造函数有所更改,我们只需在一处(fixtures)进行更新。 - 所有测试都将自动使用更新的版本。
更快的测试运行(重用测试环境)
- 编写测试用例时会在可能的情况下重复使用 fixture。
- 如果多个测试使用同一个页面(例如
loginPage
和inventoryPage
),Playwright 不会每次都重新创建对象,从而加快执行。
4️多个测试的共享设置项
- 如果所有测试都需要登录,你可以在测试固件中自动化这个过程,而不是在每次测试中重复登录。
export const test = base.extend<SauceDemoFixtures>({
loginPage: async ({ page }, use) => {
const loginPage = new LoginPage(page); // 登录页面对象
await loginPage进入登录页面();
await loginPage输入用户名('testuser');
await loginPage输入密码('password');
await loginPage点击登录按钮();
await use(loginPage); // 使用登录页面对象
},
});
更干净,更易扩展的测试套件
- 随着项目的发展,使用传统的POM管理成百上千的测试用例会变得很痛苦。
- 使用测试固定件,即便测试用例众多,测试结构依然井然有序。
在进行测试自动化时,是选择使用Fixture或者页面对象模型(POM),取决于实际使用情况。
通过使用 Playwright 的 base.extend
方法并结合页面对象模型(POM),你可以创建一个干净、易于维护且高效的测试套件。这种方法允许你将特定页面的交互封装在专门的类中,同时利用 fixture 来处理初始化和清理工作,从而使测试易于维护,并且在项目扩展时更加简洁高效。
共同學(xué)習(xí),寫(xiě)下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章