我正在开发一个具有许多类似数据表/CRUD 屏幕的应用程序。我使用带有页面对象模式的 Selenium 在应用程序中进行导航,并使用对象母体来创建预定义的测试数据,特别是对于具有许多输入的表单。
在编写功能文件时,我突然想到这些测试彼此非常相似,为了重用和干燥,应该可以概括一些常见的步骤。 DataTable 页面对象很简单,因为所有页面的选择器都是相同的。所以我创建了一个DataTable
具有过滤、选择行等必要操作的页面对象。我通过 Specflow 的上下文注入机制使用 DI。
Example:
Scenario: List and search Users
When I type '[email protected] /cdn-cgi/l/email-protection' in filter
Then I should only see items with 'email' = '[email protected] /cdn-cgi/l/email-protection'
以及步骤:
[Binding]
public class DataTableSteps
{
private DataTable _page;
public DataTableSteps(DataTable page) => _page = page;
[When(@"I type '(.*)' in filter")]
public void WhenITypeInFilter(string value) {
_page.FilterSearch (value);
}
[Then(@"I should see items with '(.*)' = '(.*)'")]
public void ThenIShouldSeeAListWhereContains(string column, string value)
{
_page.VisibleInTable(column, value).Should().BeTrue();
}
}
问题是,当我尝试制作通用步骤类时,我找不到好的设计WebFormSteps
处理表单数据以使用不同的方式填写各种输入WebForm
页面对象。我想做以下事情:
Scenario: Add User
When I go to '/Users'
When I create a 'validUser' Item #'validUser' comes from the object mother
Then 'validUser' should be added
并对产品使用相同的步骤和步骤定义:
Scenario: Add Product
When I go to '/Products'
When I create a 'validProduct' Item
Then 'validProduct' should be added
我想到使用接口或抽象类并让NewUserInputWebForm
页面对象和UserMother
来实现这些,但是我找不到在运行时注入正确的具体类型的方法。 (我考虑将具体的对象母体放入相关的页面对象中,这意味着对步骤的依赖性减少,但我无法证明将对象母体添加到这样一个不相关的类(即页面对象)中。
[Binding]
class WebFormSteps
{
IWebFormObject formObject;
IObjectMother objectMother;
public WebFormSteps(IWebFormObject formObject, IObjectMother objectMother)
{
this.formObject = formObject;
this.objectMother = objectMother;
}
[When(@"I create a '([^']*)' item")]
public void WhenICreate(string exampleName)
{
form = objectMother.Create(exampleName);
formObject.FillForm(form);
formObject.Submit();
}
}
我想到的一件事是使用作用域钩子并注册具有正确对象的接口,但是在这种情况下将会有大量的标签和钩子方法。同样,我可以在其他步骤注册类型,例如When I go to '/Users'
一步,但这会使事情变得更加复杂。可以使用反射或者可以在步骤定义中指定类型名称:When I create a 'User' named 'validUser'
,但这会使脆弱的测试变得更加脆弱。此外,测试将变得过于技术性,而不是黄瓜。
有没有好的方法来实现这一目标?我什至不确定这种方法是否是好的做法(包括数据表),因为我无法找到有关此类用法的更多简单示例。我应该坚持专门的步骤,例如:
Scenario: Add User
When I go to '/Users'
When I create a user named 'validUser'
Then 'validUser' should be added to users