背景
随着产品的快速迭代,会出现产品被前方催着要功能,发包来不及测试的场景(回归测试),为解决这种问题,我推行了端到端测试的试行。
Demo测试场景
在百度搜索playwright,根据返回的搜索内容判断第一条内容是否符合我们的搜索结果。
Demo效果示例
前提条件
- 运行环境:node环境 (优先安装好node)
- 测试框架:Playwright-test
- 语法:TypeScript
- 测试工具:Playwright
- 测试工具依赖的特定测试浏览器(任意一个):谷歌,Safari,Opera,Edge,火狐等任选其一
注意:playwright不支持babel编译,所以要结合ts,具体看个人需求,如不使用ECMAScript相关语法无需配置
安装依赖包
yarn add playwright @playwright/test typescript ts-node
#OR
npm install playwright @playwright/test typescript ts-node
复制代码
配置项目配置文件
配置package.json
{
...
"scripts": { "test": "playwright test" }
}
复制代码
公共配置playwright.config.ts
(详细配置参考:Test-configuration)
import { PlaywrightTestConfig } from "@playwright/test";
let config: PlaywrightTestConfig = {
timeout: 6 * 60 * 1000, // 每个测试用例超时
globalTimeout: 60 * 1000, // 总超时
testDir: "./demo",//测试目录
reporter: [["html", { outputFolder: "./", open: "always" }]],//测试报告
use: {
launchOptions: {
headless: false, //不是无头模式
// recordVideo:'videos'
// recordVideo
// devtools: true,
},
contextOptions: {
viewport: { //窗口视野大小
width: 1400,
height: 900,
},
},
//baseURL: process.env.TENANT_URL, // 基础URL
screenshot: "only-on-failure", // 失败时截屏
trace: "retain-on-failure",// 失败时跟踪记录
browserName: "webkit", // 测试浏览器
},
};
export default config;
复制代码
配置tsconfig.json
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
"target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs",
/* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
/* Advanced Options */
"skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ }
}
复制代码
编写测试用例
1、根目录下创建测试目录demo
2、创建测试用例文件
import { expect, test } from "@playwright/test"; import { chromium } from "playwright";
import { TestOperationPanel } from "./TestOperationPanel";
import { judgeSystem } from "./config";
let testOperation: TestOperationPanel, browser, page, context;
/**测试用例组**/
test.describe("Playright-demo", async function () {
/**运行所有测试用例前的函数**/
test.beforeAll(async ({ browserName }, testConfig) => {
/**判断系统类型配置**/
const launch = await judgeSystem();
/**创建浏览器**/
browser = await chromium.launch(launch);
/**创建窗口**/
context = await browser.newContext();
/**创建界面**/
page = await context.newPage();
/**创建UI交互配置代码实例**/
testOperation = new TestOperationPanel(page); });
/**运行每个测试用例前的函数**/
test.beforeEach(async function () {
/**跳转地址**/
await testOperation.goTestUrl("http://www.baidu.com"); }); /**测试用例**/
test("搜索Playwright", async function () {
/**搜索指定内容**/
const result = await testOperation.searchContent("playwright");
/**断言校验匹配的内容**/
expect(result).toMatch(/^playwright/); });
/**运行所有测试用例后的函数**/
test.afterAll(async function ({ browser }) {
/**关闭浏览器**/
await browser.close()
});
});
复制代码
3、创建测试用例公共设置文件
(在demo文件夹下创建config.ts文件,因为需要匹配不同操作系统,所以单独配置浏览器)
import os from "os";
import fs from "fs";
/** * 判断操作系统决定lanuch条件 * @returns */
export function judgeSystem() {
const osType = os.type();
if (osType === "Darwin") {
/**macOS系统下测试浏览器的配置 */
return { executablePath: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", //浏览器地址 }; }
if (osType === "Linux") {
/**Linux系统下测试浏览器的配置 */
// return { devtools: true }
}
if (osType === "Windows_NT") {
/**windows系统下测试浏览器的配置 */
// return { devtools: true } }
}
复制代码
4、在demo文件夹下TestOperationPanel.ts
(实现UI交互层代码和业务代码分割,捕获元素的方法较多,参考Page Object Model,UI交互参考Selectors)
//UI交互层代码
import { Page } from "playwright";
export class TestOperationPanel {
protected page: Page;
constructor(page: Page) {
this.page = page;
}
/** * 加载测试的网址 */
goTestUrl = async (url: string) => {
/**跳转地址**/
await this.page.goto(url);
/**等待页面加载**/
await this.page.waitForLoadState(); };
/** * 搜索指定内容 */
searchContent = async param => {
/**在输入框中填充搜索字段**/
await this.page.locator(".s_ipt").fill(param);
/**在输入框中回车触发搜索**/
await this.page.locator(".s_ipt").press("Enter");
/**等待页面加载**/
await this.page.waitForLoadState();
/**返回搜索内容第一项的内容**/
const result = await this.page.locator('//div[@id="1"]/h3//em').textContent();
return result;
}
}
复制代码
运行测试用例
npm run test //若需要获取运行的详细日志可在运行前加DEBUG=pw:api
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END