背景
从后端测试的角度来看前端测试; 后端测试 黑盒测试:自动化接口测试,不关心内部实现,只关心入参出参,出于用户角度来测试完整功能; 白盒测试:代码层单元测试,关心内部实现,聚焦核心方法,出于开发角度来测试部分核心功能; 前端测试 黑盒测试:(待实现) 白盒测试:(未实现) 从上面角度来看: 1、如果我们要实现前端黑盒测试,需要从用户角度关心页面功能是否达到目的即可,想办法模拟页面操作,并检验页面元素来校验是否达到期望; 2、如果我们要实现前端白盒测试,那么我们要想办法模拟渲染页面,并在内部测试调用JS方法,通过JS对象或者渲染出的页面元素来判断是否达到期望; 市面上前端测试的流行方案: 黑盒测试:Playwright、Selenium,支持多重前端或后端语言,重点是支持C#; 白盒测试:Jest、Mocha、Jasmine等等,以支持前端语言为主,有些测试框架还需借助第三方库才能完整测试(比如要借助第三方的Mock库、断言库等等),以Vue、Angular、React三大语言对上述各个框架的支持度也不太一样,而且.Net开发对前端代码的规范度和熟悉度没有专业前端开发那么高; 结论:目前以前端黑盒测试来实现前端测试比较主,当然后期随着要求越来越高再来考虑前端白盒测试; 前端黑盒测试的目的 业务目的:自动模拟用户在页面上操作,保证固定的一套页面元素操作下,页面功能达到预期; 代码目的:自动模拟用户在页面上操作,保证JS不会报错;前端测试选型
Playwright VS Selenium 尝试过Playwright后,比较两者:- 两者的功能是一致的,Playwright能实现的Selenium也能实现,但是Selenium是建立在依赖各种社区支持勉强实现,语法上不够直观,导致写起来相对Playwright费劲;
- Selenium文档没有完整例子,不好参照;
- Selenium定位不支持模糊查找,定位起来对非专业前端开发来说不轻松;
- Selenium很多东西原生不支持,需借助第三方,导致不知道到底哪些要去找第三方的东西,比如发起Http请求,拦截请求等;
- Selenium弹性等待实现起来不轻松,写法不够简单;
- Selenium录制工具,需下载三方IDE: https://www.selenium.dev/selenium-ide/,Playwright录制起来相对简单,无需三方IDE;
正文
Playwright官方文档:https://playwright.dev/dotnet/docs/intro步骤一:环境安装
1、安装最新版PowerShell
暂时无法在飞书文档外展示此内容 暂时无法在飞书文档外展示此内容 ps:本地PowerShell一般都是老版本,运行命令会有问题2、build单元测试项目
3、用PowerShell执行pwsh bin/Debug/net6.0/playwright.ps1 install
ps:注意本地的net版本,可以进项目的bin/Debug/文件夹确认;4、可能需要重新打开IDE,就可以按步骤三来调试和运行已有测试了
步骤二:UI测试编写
ps:playwright支持Nunit、MsUnit,不支持Xunit(可能是前端对并发的限制),这里选用的是Nunit1、初始化
继承基类BaseService并在setup中调用Init方法即可; Init方法主要做的内容:- 初始化浏览器、页面,设置全局超时时间,调试页面大小,运行时是否弹出浏览器
- 登录指定用户并获取token,初始化cookie,前端初始化权限
- 公共对象page(页面实例)、configuration(配置读取)、context(上下本)、browser(浏览器实例)
2、元素定位
- 根据文案查找对象 GetByRole
- CSS筛选器 Locator
- XPath Locator
- Locator + Nth
- 录制中鼠标定位,生成代码
详见下面介绍的CodeGen:自动录制生成代码
3、元素操作
- Click
- Fill (input输入值)
- Clear
- Focus
- Press("Enter")
- SelectOption
- SetChecked
- Tap
- WaitFor (Attached、Visible、Hidden)
4、操作等待&超时处理
一般在写UI测试时,都需要等待上一个动作结束后才能进行下一个动作,中间的等待动作有两种选择:- 等待固定时间:await Task.Delay(2000);
- 等待某个UI转变,如等待操作成功的弹窗出现
5、接口拦截
await page.RouteAsync("https://ows.yesmro.cn/cs/api/QuotationV2/SubmitQuotation*", async route => { var response = await route.FetchAsync(); var responseTxt = await response.TextAsync(); var responseObj = JsonConvert.DeserializeObject<MstApiResult<QuotationV2Dto>>(responseTxt); InquiryId = responseObj.Body.Id; Console.WriteLine(InquiryId); await route.FulfillAsync(new RouteFulfillOptions { Response = response }); }); 拦截Url*,获取返回结果,反序列为对象,处理该对象,接口实现;6、一般的代码流程
- 初始化页面
- 接口拦截(可选)
- 添加权限脚本(防报错)
步骤三:UI测试调试与运行
1、本地IDE调试 (Rider、Visual Studio、VS Code)
Rider: 方法左侧点击 或 底部Unit Tests菜单2、命令行运行
- cd到宪章文件夹
- dotnet test YesMro.CS.UiTest -e ENVIRONMENT=Production
3、与线上发布闭环
需等待系统发布完成后,等待几分钟才能运行UI测试; CI运行:https://playwright.dev/dotnet/docs/ciCodeGen:自动录制生成代码
官方文档:https://playwright.dev/dotnet/docs/codegen#recording-a-test 启动录制:- 打开PowerShell
- CD到UI项目文件夹
- pwsh bin/Debug/net6.0/playwright.ps1 codegen https://ows.yesmro.cn/home