@wanjming/eas-test-platform
v1.0.3
Published
EAS 企业级测试平台 - Playwright + TypeScript + PO 模式
Maintainers
Readme
eas-test-platform
企业级 Playwright UI 自动化测试框架 · TypeScript + PO 模式
快速搭建、开箱即用、企业级实践
📖 简介
eas-test-platform 是一个基于 Playwright 的企业级 UI 自动化测试框架,采用 TypeScript + Page Object 模式。通过 CLI 工具快速初始化项目,生成完整的测试结构,内置丰富的工具类和最佳实践。
适用场景
- ✅ 企业级 Web 应用 E2E 测试
- ✅ 多环境(test/pre/prod)测试管理
- ✅ 复杂业务流程自动化
- ✅ 回归测试、冒烟测试
- ✅ CI/CD 集成测试
⚡ 快速开始
安装
# 全局安装(推荐)
npm install -g @wanjming/eas-test-platform
# 或使用 npx 直接运行
npx @wanjming/eas-test-platform init my-project初始化项目
# 创建新项目
eastp init my-test-project
# 进入项目目录
cd my-test-project
# 安装依赖
npm install
# 安装浏览器
npx playwright install配置环境
编辑 config/.env.test:
BASE_URL=https://your-app.com
WM_ACCOUNT=test_user
WM_PASSWORD=Test@123运行测试
# 运行测试
npm test
# 有头模式
npm run test:headed
# 查看报告
npm run test:report🎯 核心特性
🚀 快速初始化
- 一键创建项目:通过 CLI 命令快速生成完整的测试项目结构
- 交互式配置:项目初始化时通过问答形式设置基础配置
- 开箱即用:预置完整的测试框架,无需额外配置
📐 Page Object 模式
- 规范化设计:采用经典 PO 模式,页面元素与测试逻辑分离
- 三层架构:BaseInteractions(交互)→ BaseAssertions(断言)→ BasePage(业务)
- 易于维护:页面变化时只需修改 Page Object,测试用例无需改动
🛠️ 丰富的工具类
- 文件处理:Excel 读写、PDF 转图片、图片压缩
- API 客户端:HTTP 请求封装、认证管理
- 数据库客户端:MySQL 连接池、事务管理
- OCR 客户端:图片文字识别
- 时间工具:日期格式化、计算
- 日志系统:Pino 日志框架、分级日志
🌍 多环境支持
- 环境隔离:test/pre/prod 环境配置分离
- 环境切换:通过
TEST_ENV环境变量快速切换 - 配置管理:统一的 Settings 类管理所有配置项
📊 强大的报告
- Playwright HTML:内置报告,包含截图、视频、追踪
- Allure 报告:丰富的图表、趋势分析、历史对比
- 失败追踪:自动截图、视频录制、trace 记录
🎨 测试最佳实践
- Fixture 模式:测试夹具管理测试数据和页面实例
- 等待策略:智能等待、接口等待、元素等待
- 步骤记录:所有操作自动记录到 Allure 报告
- 错误处理:统一的异常捕获和日志记录
📦 项目结构
my-test-project/
├── config/ # 环境配置
│ ├── .env.test # 测试环境配置
│ ├── .env.pre # 预发布环境配置
│ ├── .env.prod # 生产环境配置
│ └── settings.ts # 配置管理类
├── core/ # 核心代码
│ ├── fixtures/ # 基础测试夹具
│ │ └── base.fixture.ts # 基础 fixture
│ ├── pages/ # 页面基类
│ │ ├── base_interactions.ts # 交互基类
│ │ ├── base_assertions.ts # 断言基类
│ │ ├── base_page.ts # 页面基类
│ │ └── login_page.ts # 登录页面
│ └── setup/ # 全局配置
│ ├── global-setup.ts # 全局前置
│ └── global-teardown.ts # 全局清理
├── tests/ # 测试模块(按业务划分)
│ └── tuishui/ # 退税模块示例
│ ├── shared/ # 共享代码
│ │ ├── fixtures/ # 共享夹具
│ │ ├── utils/ # 共享工具
│ │ └── sql/ # SQL 查询
│ └── wm_ts_sb/ # 外贸退税申报
│ └── tab_tsmx_ckmx/ # 出口明细标签页
│ ├── page.ts # 页面对象
│ ├── fixture.ts # 测试夹具
│ ├── spec.ts # 测试用例
│ └── factory.ts # 数据工厂
├── data/ # 测试数据
│ └── upload_files/ # 上传文件
├── utils/ # 业务工具类
│ ├── file_utils.ts # 文件工具
│ ├── api_client.ts # API 客户端
│ ├── db_client.ts # 数据库客户端
│ ├── ocr_client.ts # OCR 客户端
│ ├── time_utils.ts # 时间工具
│ └── logger.ts # 日志工具
├── logs/ # 日志目录
├── reports/ # 测试报告
│ ├── html/ # Playwright 报告
│ └── allure-report/ # Allure 报告
├── playwright.config.ts # Playwright 配置
├── tsconfig.json # TypeScript 配置
└── package.json # 项目配置🔧 CLI 命令
初始化项目
# 交互式创建项目
eastp init
# 指定项目名称
eastp init <project-name>
# 查看帮助
eastp init --help项目健康检查
# 检查项目配置完整性
eastp doctor检查内容:
- ✅ 必需文件(playwright.config.ts、tsconfig.json)
- ✅ 核心目录(core/、tests/、config/)
- ✅ 环境配置文件
- ✅ 依赖安装状态
查看版本
eastp --version🧪 测试编写
1. 页面对象(Page Object)
页面对象继承自 BasePage,通过 readonly 属性定义元素定位器,通过方法封装页面操作。
// tests/tuishui/wm_ts_sb/tab_tsmx_ckmx/page.ts
import { type Page } from '@playwright/test'
import { BasePage } from '@core/pages/base_page'
export class TabTsmxCkmxPage extends BasePage {
readonly url = '/#/drawbackMgt/foreign-trade-tax-refund-declaration/mts'
// 定义页面元素
readonly addNewBtn = this.page.getByRole('button', { name: '新建', exact: true })
readonly searchBtn = this.page.getByRole('button', { name: '查询', exact: true })
readonly saveBtn = this.page.getByRole('button', { name: '保存', exact: true })
readonly bgdhInput = this.page.locator("//label[@for='bgdh']/following-sibling::div//input")
constructor(page: Page) {
super(page)
}
// 页面操作方法
async goto(): Promise<void> {
await this.navigate(this.url)
await this.waitForLoadState('load')
}
async fillBgdh(value: string): Promise<void> {
await this.fill(this.bgdhInput, value, '填写报关单号')
}
}说明:
- 继承
BasePage获得click、fill、type、waitForResponse等通用方法 - 使用
readonly定义元素定位器 - 所有操作方法的最后一个参数可传入操作描述,会记录到 Allure 报告
2. 测试夹具(Fixture)
测试夹具用于管理测试数据、页面实例和测试前后的准备清理工作。
// tests/tuishui/wm_ts_sb/tab_tsmx_ckmx/fixture.ts
import { test as base } from '../../shared/fixtures/declaration_context.fixture'
import { TabTsmxCkmxPage } from './page'
type TabTsmxCkmxFixtures = {
tabTsmxCkmx: TabTsmxCkmxPage
testData: Record<string, any>
}
export const test = base.extend<TabTsmxCkmxFixtures>({
// 页面对象夹具
tabTsmxCkmx: async ({ page }, use) => {
const tab = new TabTsmxCkmxPage(page)
await tab.goto()
await use(tab)
},
// 测试数据夹具
testData: async ({ apiClient }, use) => {
const data = await apiClient.send('GET', '/api/test-data')
await use(data)
// 测试结束后清理
await apiClient.send('DELETE', `/api/test-data/${data.id}`)
},
})
export { expect } from '@playwright/test'3. 测试用例(Spec)
测试用例使用自定义的 fixture 获取页面对象和测试数据。
// tests/tuishui/wm_ts_sb/tab_tsmx_ckmx/spec.ts
import { test } from './fixture'
import { epic, feature, story, tags } from 'allure-js-commons'
test.describe('退税明细录入-出口明细', () => {
test.beforeEach(async () => {
await epic('退税')
await feature('外贸企业退税申报')
await story('退税明细录入-出口明细')
})
test('@smoke 新建出口明细,填写报关单号保存成功',
async ({ tabTsmxCkmx, testData }) => {
await tags('smoke')
// 点击新建并等待接口响应
await tabTsmxCkmx.clickAndWaitForResponse(
tabTsmxCkmx.addNewBtn,
{ url: /\/api\/next-glh/, method: 'GET' },
'点击新建按钮'
)
// 填写表单
await tabTsmxCkmx.fillBgdh(testData.bgdh)
// 保存并等待响应
await tabTsmxCkmx.clickAndWaitForResponse(
tabTsmxCkmx.saveBtn,
{ url: /\/api\/mts-tssb/, method: 'POST' },
'点击保存按钮'
)
// 断言
await tabTsmxCkmx.expectVisible(tabTsmxCkmx.page.getByText('保存成功'))
}
)
})🌍 多环境配置
环境文件
在 config/ 目录创建环境配置:
config/
├── .env.test # 测试环境
├── .env.pre # 预发布环境
└── .env.prod # 生产环境配置示例
# .env.test
BASE_URL=https://test.example.com
WM_ACCOUNT=test_user
WM_PASSWORD=Test@123
WM_COMPANY_NAME=测试公司
DB_HOST=test-db.example.com
DB_PORT=3306切换环境
# 测试环境(默认)
npm test
# 预发布环境
npm run test:pre
# 或手动指定
TEST_ENV=prod npm test🚀 CI/CD 集成
GitHub Actions
name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm ci
- run: npx playwright install --with-deps
- run: npm test
- uses: actions/upload-artifact@v3
if: always()
with:
name: test-reports
path: reports/📝 文档
- 📙 发布指南 - npm 发布流程
🤝 贡献
欢迎贡献代码、报告问题或提出建议!
- Fork 本仓库
- 创建特性分支(
git checkout -b feature/AmazingFeature) - 提交更改(
git commit -m 'Add some AmazingFeature') - 推送到分支(
git push origin feature/AmazingFeature) - 开启 Pull Request
📄 许可证
本项目基于 MIT License 开源。
🙏 致谢
- Playwright - 强大的浏览器自动化工具
- TypeScript - JavaScript 的超集
- Allure - 优秀的测试报告框架
如果这个项目对你有帮助,请给一个 ⭐ Star!
Made with ❤️ by wanjiaming
