上次,我们介绍了用于Web应用程序自动化测试的工具Playwright for .NET。
但是直接使用它来编写测试用例,代码比较凌乱,后期也不好维护。
因此,我们利用SpecFlow让测试用例更好理解和维护。
1.SpecFlow介绍
SpecFlow是.Net平台下用于行为驱动开发的开源框架。它使用普通人能够理解的的软件需求描述作为软件测试的基础,并可以将它们转换为可执行代码。
详细介绍可参看官网:https://specflow.org/
2.安装SpecFlow扩展
运行VS2019,选择菜单“扩展”->“管理扩展”,在打开的窗口在搜索“SpecFlow”:
点击“下载”按钮开始安装,重新启动VS完成安装。
3.创建SpecFlow项目
新建项目,选择“SpecFlow project”模板,点击“创建”按钮,在弹出的窗口中选择.NET框架和测试框架。这里我们选择MSTest作为测试框架:
点击“Create”按钮,最终生成的项目结构如下图:
4.添加Feature文件
在解决方案资源管理器的Feature文件夹上点右键,添加"SpecFlow Feature File",命名为BaiduAdvancedSearch.feature
。
Feature是一个纯文本文件,它的作用是使用被称为Gherkin的语法,按照Given/When/Then的特定示例格式来编写软件需求描述。
执行百度高级搜索的操作
的Feature描述如下:
Feature: 百度高级搜索
所有场景必须顺序执行
Scenario: (1)显示高级搜索页面
Given 打开百度首页
When 鼠标悬停在“设置”按钮
And 点击设置菜单上的“高级搜索“按钮
Then 弹出高级搜索页面
Scenario: (2)执行高级搜索
Given 输入关键词"My IO"
When 点击高级搜索页面上的“高级搜索"按钮
Then 搜索框显示关键词"My IO"
我们把一个需求分成2个连续的场景(Scenario),每个场景又有多个步骤。
5.生成Step文件
在Feature文件空白处点击右键,选择“Generate Step Definitions”菜单,在弹出窗口中设置class name为BaiduAdvancedSearchSteps
,点击“Generate”按钮:
生成的文件中已经包含了对应描述文件的空方法:
可以看到,描述中用双引号表示的搜索关键词自动变成了参数。这样就算调整相关描述,也无需修改代码!
6.填充代码
现在,我们可以按照方法描述填空,代码可以来自于Playwright 的录制功能:
完整代码如下:
using BoDi;
using Microsoft.Playwright;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Threading.Tasks;
using TechTalk.SpecFlow;
namespace SpecFlowProject1.Steps
{
[Binding]
public class BaiduAdvancedSearchSteps
{
[BeforeFeature]
public static async Task BeforeFeature(IObjectContainer container)
{
var playwright = await Playwright.CreateAsync();
var browser = await playwright.Chromium.LaunchAsync(new() { Headless = false, SlowMo=1000 });
var page = await browser.NewPageAsync();
container.RegisterInstanceAs<IPage>(page);
}
private IPage _page;
public BaiduAdvancedSearchSteps(IPage page)
{
this._page = page;
}
[Given(@"打开百度首页")]
public async Task Given打开百度首页()
{
await _page.GotoAsync("https://www.baidu.com/");
}
[When(@"鼠标悬停在“设置”按钮")]
public async Task When鼠标悬停在设置按钮()
{
await _page.WaitForSelectorAsync("#s-usersetting-top");
await _page.HoverAsync("#s-usersetting-top");
}
[When(@"点击设置菜单上的“高级搜索“按钮")]
public async Task When点击设置菜单上的高级搜索按钮()
{
await _page.ClickAsync("a[href='//www.baidu.com/gaoji/advanced.html']");
}
[Then(@"弹出高级搜索页面")]
public async Task Then弹出高级搜索页面()
{
var handle = await _page.WaitForSelectorAsync(".bdlayer.s-isindex-wrap.new-pmd.pfpanel");
var style = await handle.GetAttributeAsync("style");
Assert.IsTrue(style.Contains("display: block;"));
}
[Given(@"输入关键词""(.*)""")]
public async Task Given输入关键词(string p0)
{
await _page.TypeAsync("input[name='q1']", p0);
}
[When(@"点击高级搜索页面上的“高级搜索""按钮")]
public async Task When点击高级搜索页面上的高级搜索按钮()
{
_page = await _page.RunAndWaitForPopupAsync(async () =>
{
await _page.ClickAsync(".advanced-search-btn");
});
}
[Then(@"搜索框显示关键词""(.*)""")]
public async Task Then搜索框显示关键词(string p0)
{
var handle = await _page.WaitForSelectorAsync("#kw");
var text = await handle.GetAttributeAsync("value");
Assert.AreEqual(p0, text);
}
}
}
7.执行测试
选择菜单“测试”->“运行所有测试”,可以看到所有测试运行通过:
你还可以关闭浏览器无头模式,用可视化的方式观察测试是如何工作的:
//关闭浏览器无头模式,每步操作延迟1秒
var browser = await playwright.Chromium.LaunchAsync(new() {
Headless = false, SlowMo=1000 });
结论
通过上面的示例。我们看到,Feature除了少数几个简单的英语单词外,全部都可以用中文,没有一行代码!
完全可以由业务需求人员来编写测试用例,同时可以保证大家都能够理解,达成共识。
而测试代码也是不言自明的,对后期维护非常有利。
还等什么,Playwright for .NET + SpecFlow,走你!
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“,记住我!