我正在使用 C# 和页面对象模型为 Selenium 测试自动化设置一个框架。
框架是使用specflow建立的,其项目结构如下。
- 特征文件
- 步骤定义
- 核心.cs
核心代码如下:
[Binding]
public class Core
{
private readonly IObjectContainer objectContainer;
public IWebDriver _driver;
public Core(IObjectContainer objContainer) => objectContainer = objContainer;
[BeforeScenario]
public void BeforeScenario()
{
_driver = new ChromeDriver();
objectContainer.RegisterInstanceAs<IWebDriver>(_driver);
}
}
步骤定义如下:
[Binding]
public class StepDefinition
{
public IWebDriver driver;
public StepDefinition1(IWebDriver _driver) => driver = _driver;
public IWebElement username => driver.FindElement(By.Id("username"));//property1
public IWebElement password => driver.FindElement(By.Id("pass"));//property2
.
.
.
.
[When(@"i enter data")]
public void WhenIEnterData()
{
username.Click()
}
}
我想将 password
和 username
属性放在单独的文件中。以后会有很多属性和很多步骤定义文件。所以我想把所有的属性都放在一个地方。
我尝试拆分类并将两者标记为部分类并使用相同的名称,但如果有很多步骤定义文件,这将不起作用。
public class OR
{
public IWebDriver driver;
public OR(IWebDriver _driver) => driver = _driver;
public IWebElement username => driver.FindElement(By.Id("username"));
public IWebElement password => driver.FindElement(By.Id("pass"));
}
[Binding]
public class StepDefinition1 :OR
{
public IWebDriver driver;
public StepDefinition1(IWebDriver _driver) => driver = _driver;
[When(@"i enter data")]
public void WhenIEnterData()
{
username.Click();
}
}
但这给了我:
There is no argument given that corresponds to the required formal parameter
_driver
ofOR.OR(IWebDriver)
on constructor of stepdefnition1.
因为会有很多步骤定义文件,所以我想将所有属性保存在一个地方,所有类/步骤定义都可以访问。
最佳答案
虽然 Ikacho 的回答可以解决问题,但您的问题最好用不同的类架构来解决。将步骤定义类和 selenium 相关类分开,并利用页面对象模型。
首先是page对象,专用于登录页面:
public class LoginPage
{
public IWebDriver driver;
public LoginPage(IWebDriver _driver)
{
this.driver = _driver;
}
private IWebElement Username => driver.FindElement(By.Id("username"));
private IWebElement Password => driver.FindElement(By.Id("pass"));
private IWebElement LoginButton => driver.FindElement(By.XPath("//button[contains(., 'Login']"));
public void LogIn(string username, string password)
{
Username.SendKeys(username);
Password.SendKeys(password);
LoginButton.Click();
}
}
还有一个示例步骤定义文件:
[Binding]
public class StepDefinition1
{
private IWebDriver driver;
private LoginPage loginPage;
public StepDefinition1(IWebDriver _driver)
{
driver = _driver;
loginPage = new LoginPage(driver);
}
[When(@"I log in")]
public void WhenIEnterData()
{
loginPage.LogIn("test", "test");
}
}
现在,使用 Selenium API 与 Web 浏览器交互的代码集中在它们自己的类中,为您提供了一种重用该代码的简单方法。它还允许您创建可以处理与网页交互的复杂细节的类,因此这种复杂性不会分散到您的步骤定义中。
根本不需要继承。组合将更简单,更容易重用代码。
关于c# - 如何在共享相同对象实例的单独文件/类中编写类的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57510293/