分组扩展方法
Grouping extension methods
我正在与 .NET 4.5
、VS2013
和 Selenium
合作。
我正在为页面流结构和字段结构有些相似的产品编写 selenium 测试。
要为我在 IWebDriver
上使用扩展方法的字段设置值
示例:
private void WillsCustomerDetail(IWebDriver driver)
{
driver.WillsSetMainCustomerTitle("Dr");
driver.WillsSetMainCustomerGender("Male");
driver.WillsSetMainCustomerName("Liufa");
driver.WillsSetMainCustomerSurname("Afuil");
driver.WillsSetMainCustomerDateOfBirth(new DateTime(1955, 12, 26));
...
}
public static IWebElement WillsSetMainCustomerName(this IWebDriver driver, string value)
{
return driver.SetText(value, WillsElements.CustomerDetails.MainCustomer.Firstname);
}
public static IWebElement SetText(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
element.SendKeys(value);
return element;
}
public static class WillsElements
{
public static class CustomerDetails
{
public static class MainCustomer
{
public static string Title
{
get { return "#Customers-0--Title"; }
}
...
}
}
}
我遇到的问题是我的方法命名
WillsSetMainCustomerTitle
- 实际上是
的串联
遗嘱-产品(网络旅程),
MainCustomer - 部分页面,
标题 - 字段,
对于下一个产品,我将有 LpaSetMainCustomerName
和大多数其他领域,这使它变得一团糟。
我想要的是
driver.Wills.MainCustomer.SetTitle("Dr");
作为扩展方法
有没有实现分组扩展方法的方法? (或者得到类似的东西,在仍然有扩展方法的同时允许很好的分组)。
不可能直接对这样的扩展方法进行分组。
在例子中
driver.Wills.MainCustomer.SetTitle("Dr");
您可以使 Wills
和 MainCustomer
方法各自 return 成为一种特殊类型。下一个级别(MainCustomer
和 SetTitle
)的钻取可以关闭这些类型。搜索 "fluent style" 以了解我的意思。我不推荐这里。它创建了大量的工作来设置只是为了在你想要的地方获得那个小句号。
你也可以包装驱动程序:
new WillsDriver(driver)
.MainCustomer
.Title = "Dr";
同样,您必须写下所有 类 和成员。
我可以建议以下命名约定:
Wills_MainCustomer_SetTitle
一个非常简单的解决方案,使它更具可读性。
如果这些方法的主体总是非常相似,请考虑使用 T4 模板生成这些方法的所有可能情况。
对于那些想知道我最后得到了什么的人。
[Test]
[TestCaseSource("WillsTestData")]
public void WillsTest(IWebDriver driver)
{
driver.Navigate().GoToUrl(WillsNavigation.Index);
var willsDriver = new WillsDriver(driver);
this.WillsCustomerDetail(willsDriver);
...
}
private void WillsCustomerDetail(WillsDriver driver)
{
driver.CustomerDetail.MainCustomer.Title = "Dr";
driver.CustomerDetail.MainCustomer.Gender = "Male";
driver.CustomerDetail.MainCustomer.Name = "Liufa";
driver.CustomerDetail.MainCustomer.Surname = "Afuil";
driver.CustomerDetail.MainCustomer.DateOfBirth = new DateTime(1955, 12, 26);
...
driver.CustomerDetail.ClickContinue();
}
public class WillsDriver
{
public WillsDriver(IWebDriver driver)
{
this.Driver = driver;
this.Index = new IndexClass(driver);
this.Quote = new QuoteClass(driver);
this.CustomerDetail = new CustomerDetailsClass(driver);
}
public CustomerDetailsClass CustomerDetail { get; private set; }
public IndexClass Index { get; private set; }
public QuoteClass Quote { get; private set; }
public IWebDriver Driver { get; set; }
....
public class CustomerDetailsClass
{
public CustomerDetailsClass(IWebDriver driver)
{
this.Driver = driver;
this.MainCustomer = new MainCustomerClass(driver);
this.SecondCustomer = new SecondCustomerClass(driver);
}
public IWebDriver Driver { get; set; }
public MainCustomerClass MainCustomer { get; private set; }
public SecondCustomerClass SecondCustomer { get; private set; }
....
public class MainCustomerClass
{
public MainCustomerClass(IWebDriver driver)
{
this.Driver = driver;
}
public IWebDriver Driver { get; set; }
public string Title
{
set
{
this.Driver.SetDropDown(value, WillsElements.CustomerDetails.MainCustomer.Title);
if (value == "Dr") Thread.Sleep(700);
}
}
....
}
}
public class WillsElements
{
public static class CustomerDetails
{
public static class MainCustomer
{
public static string Title
{
get { return "#Customers-0--Title"; }
}
public static string Gender
{
get { return "#Customers-0--GenderSection-Gender"; }
}
public static string Firstname
{
get { return "#Customers-0--Firstname"; }
}
....
}
}
public static class SetWillElement
{
public static IWebElement SetDropDown(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
var select = new SelectElement(element);
select.SelectByText(value);
return element;
}
public static string YesNoToCssSelector(this string name, string value)
{
return string.Format("{0}[value='{1}']", name, value == "Yes" ? "True" : "False");
}
public static IWebElement ClickButton(this IWebDriver driver, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
element.Click();
return element;
}
public static IWebElement SetRadio(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
((IJavaScriptExecutor) driver).ExecuteScript("arguments[0].checked = true;", element);
return element;
}
public static IWebElement SetText(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
element.SendKeys(value);
return element;
}
}
我应该将 WillsElements
拉入 WillsDriver
class,这样会更整洁。
我正在与 .NET 4.5
、VS2013
和 Selenium
合作。
我正在为页面流结构和字段结构有些相似的产品编写 selenium 测试。
要为我在 IWebDriver
示例:
private void WillsCustomerDetail(IWebDriver driver)
{
driver.WillsSetMainCustomerTitle("Dr");
driver.WillsSetMainCustomerGender("Male");
driver.WillsSetMainCustomerName("Liufa");
driver.WillsSetMainCustomerSurname("Afuil");
driver.WillsSetMainCustomerDateOfBirth(new DateTime(1955, 12, 26));
...
}
public static IWebElement WillsSetMainCustomerName(this IWebDriver driver, string value)
{
return driver.SetText(value, WillsElements.CustomerDetails.MainCustomer.Firstname);
}
public static IWebElement SetText(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
element.SendKeys(value);
return element;
}
public static class WillsElements
{
public static class CustomerDetails
{
public static class MainCustomer
{
public static string Title
{
get { return "#Customers-0--Title"; }
}
...
}
}
}
我遇到的问题是我的方法命名
WillsSetMainCustomerTitle
- 实际上是
的串联
遗嘱-产品(网络旅程),
MainCustomer - 部分页面,
标题 - 字段,
对于下一个产品,我将有 LpaSetMainCustomerName
和大多数其他领域,这使它变得一团糟。
我想要的是
driver.Wills.MainCustomer.SetTitle("Dr");
作为扩展方法
有没有实现分组扩展方法的方法? (或者得到类似的东西,在仍然有扩展方法的同时允许很好的分组)。
不可能直接对这样的扩展方法进行分组。
在例子中
driver.Wills.MainCustomer.SetTitle("Dr");
您可以使 Wills
和 MainCustomer
方法各自 return 成为一种特殊类型。下一个级别(MainCustomer
和 SetTitle
)的钻取可以关闭这些类型。搜索 "fluent style" 以了解我的意思。我不推荐这里。它创建了大量的工作来设置只是为了在你想要的地方获得那个小句号。
你也可以包装驱动程序:
new WillsDriver(driver)
.MainCustomer
.Title = "Dr";
同样,您必须写下所有 类 和成员。
我可以建议以下命名约定:
Wills_MainCustomer_SetTitle
一个非常简单的解决方案,使它更具可读性。
如果这些方法的主体总是非常相似,请考虑使用 T4 模板生成这些方法的所有可能情况。
对于那些想知道我最后得到了什么的人。
[Test]
[TestCaseSource("WillsTestData")]
public void WillsTest(IWebDriver driver)
{
driver.Navigate().GoToUrl(WillsNavigation.Index);
var willsDriver = new WillsDriver(driver);
this.WillsCustomerDetail(willsDriver);
...
}
private void WillsCustomerDetail(WillsDriver driver)
{
driver.CustomerDetail.MainCustomer.Title = "Dr";
driver.CustomerDetail.MainCustomer.Gender = "Male";
driver.CustomerDetail.MainCustomer.Name = "Liufa";
driver.CustomerDetail.MainCustomer.Surname = "Afuil";
driver.CustomerDetail.MainCustomer.DateOfBirth = new DateTime(1955, 12, 26);
...
driver.CustomerDetail.ClickContinue();
}
public class WillsDriver
{
public WillsDriver(IWebDriver driver)
{
this.Driver = driver;
this.Index = new IndexClass(driver);
this.Quote = new QuoteClass(driver);
this.CustomerDetail = new CustomerDetailsClass(driver);
}
public CustomerDetailsClass CustomerDetail { get; private set; }
public IndexClass Index { get; private set; }
public QuoteClass Quote { get; private set; }
public IWebDriver Driver { get; set; }
....
public class CustomerDetailsClass
{
public CustomerDetailsClass(IWebDriver driver)
{
this.Driver = driver;
this.MainCustomer = new MainCustomerClass(driver);
this.SecondCustomer = new SecondCustomerClass(driver);
}
public IWebDriver Driver { get; set; }
public MainCustomerClass MainCustomer { get; private set; }
public SecondCustomerClass SecondCustomer { get; private set; }
....
public class MainCustomerClass
{
public MainCustomerClass(IWebDriver driver)
{
this.Driver = driver;
}
public IWebDriver Driver { get; set; }
public string Title
{
set
{
this.Driver.SetDropDown(value, WillsElements.CustomerDetails.MainCustomer.Title);
if (value == "Dr") Thread.Sleep(700);
}
}
....
}
}
public class WillsElements
{
public static class CustomerDetails
{
public static class MainCustomer
{
public static string Title
{
get { return "#Customers-0--Title"; }
}
public static string Gender
{
get { return "#Customers-0--GenderSection-Gender"; }
}
public static string Firstname
{
get { return "#Customers-0--Firstname"; }
}
....
}
}
public static class SetWillElement
{
public static IWebElement SetDropDown(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
var select = new SelectElement(element);
select.SelectByText(value);
return element;
}
public static string YesNoToCssSelector(this string name, string value)
{
return string.Format("{0}[value='{1}']", name, value == "Yes" ? "True" : "False");
}
public static IWebElement ClickButton(this IWebDriver driver, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
element.Click();
return element;
}
public static IWebElement SetRadio(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
((IJavaScriptExecutor) driver).ExecuteScript("arguments[0].checked = true;", element);
return element;
}
public static IWebElement SetText(this IWebDriver driver, string value, string selector)
{
var element = driver.FindElement(By.CssSelector(selector));
element.SendKeys(value);
return element;
}
}
我应该将 WillsElements
拉入 WillsDriver
class,这样会更整洁。