在使用 Playwright 和 Node.js 编写测试时,合理管理测试的前置步骤(setup)、后置步骤(teardown)、以及用例变量,对于确保测试的可靠性和可维护性至关重要。以下是如何在 Playwright 中实现这些功能的详细指南。
1. 前后置步骤管理
Playwright 提供了几种方法来管理测试的前置和后置步骤:
test.use
可以为单个测试或整个测试文件设置上下文变量。
使用 test.use
方法
beforeAll
和afterAll
: 用于在所有测试开始之前和所有测试完成之后执行代码。通常用于全局的初始化和清理工作。beforeEach
和afterEach
: 用于在每个测试用例执行之前和之后执行代码。常用于设置和清理测试环境。-
import { test, expect } from '@playwright/test'; // 在所有测试之前运行一次 test.beforeAll(async () => { console.log('Setup before all tests'); // 例如:启动服务、初始化数据库连接等 }); // 在所有测试之后运行一次 test.afterAll(async () => { console.log('Teardown after all tests'); // 例如:关闭服务、清理数据库等 }); // 在每个测试之前运行 test.beforeEach(async ({ page }) => { console.log('Setup before each test'); await page.goto('https://example.com'); }); // 在每个测试之后运行 test.afterEach(async ({ page }) => { console.log('Teardown after each test'); // 例如:清理本地存储、清理 cookie 等 await page.close(); }); // 测试用例示例 test('Example test 1', async ({ page }) => { const title = await page.title(); expect(title).toBe('Example Domain'); }); test('Example test 2', async ({ page }) => { await page.click('text=More information'); const newTitle = await page.title(); expect(newTitle).toContain('IANA'); });
2. 用例变量管理
在 Playwright 中,可以通过多种方式管理用例变量。常见的方法包括:
- 测试上下文中的
test.use
方法: 可以用来为特定的测试或测试组设置变量。 - 使用
fixture
来共享数据: 在test
对象中,可以定义自定义的fixture
,用于在不同的测试用例之间共享数据。
import { test, expect } from '@playwright/test';
test.use({
// 配置浏览器上下文,例如设置浏览器视口大小
viewport: { width: 1280, height: 720 },
// 其他上下文配置...
});
test('Test with custom viewport', async ({ page }) => {
await page.goto('https://example.com');
// 断言视口大小
const viewport = page.viewportSize();
expect(viewport.width).toBe(1280);
expect(viewport.height).toBe(720);
});
使用 fixture
来共享变量
你可以在 base.extend
方法中定义 fixture
,这些 fixture
会在测试之间共享数据。
import { test as base, expect } from '@playwright/test';
// 扩展默认的 test 对象,添加一个 sharedData fixture
export const test = base.extend<{ sharedData: string }>({
sharedData: async ({}, use) => {
const data = 'Some shared data';
await use(data);
},
});
test('Test 1 with shared data', async ({ sharedData, page }) => {
console.log(sharedData); // 输出 'Some shared data'
await page.goto('https://example.com');
expect(await page.title()).toBe('Example Domain');
});
test('Test 2 with shared data', async ({ sharedData, page }) => {
console.log(sharedData); // 输出 'Some shared data'
await page.goto('https://example.com');
expect(await page.title()).toBe('Example Domain');
});
3. 结合前后置和变量管理
你可以结合 beforeEach
、afterEach
、fixture
来实现复杂的测试用例变量和环境管理。
示例:复杂的测试环境管理
import { test as base, expect } from '@playwright/test'; // 定义一个扩展 test 对象,添加自定义变量和前后置步骤 export const test = base.extend<{ loggedInPage: any; }>({ loggedInPage: async ({ page }, use) => { // 登录步骤作为测试的前置步骤 await page.goto('https://example.com/login'); await page.fill('#username', 'testuser'); await page.fill('#password', 'password'); await page.click('text=Login'); // 等待页面加载 await page.waitForLoadState('networkidle'); // 使用登录后的页面对象 await use(page); // 登出步骤作为后置步骤 await page.click('text=Logout'); }, }); // 测试用例使用已经登录的页面 test('Test after login', async ({ loggedInPage }) => { await loggedInPage.goto('https://example.com/dashboard'); const title = await loggedInPage.title(); expect(title).toBe('Dashboard'); });
总结
- 前后置步骤: 使用
beforeAll
、afterAll
、beforeEach
、afterEach
管理测试的生命周期。 - 用例变量管理: 使用
test.use
或fixture
共享测试数据。 - 结合使用: 前后置步骤和变量管理可以结合使用,实现更复杂的测试场景。
通过合理配置这些功能,你可以确保测试代码的高复用性和清晰性,并确保测试的可维护性和扩展性。