英文:
Implement Page-Object models in C# Selenium - PageFactory
问题
我对测试自动化非常新手。
1. 我使用的是 Visual Studio 2022,版本 17.6.2。
2. 我安装了 NuGet 包:Selenium.WebDriver、Selenium.Support、Selenium.Chrome.WebDriver、Gherkin、NUnit、NUnit3TestAdapter、xunit、BoDi、SpecFlow.Internal.Json。
我尝试使用在网上找到的示例来实现 POM 模型测试。
**POM:**
```csharp
// 代码部分不翻译
测试:
// 代码部分不翻译
然而,POM 指示出现了错误:
在命名空间 'OpenQA.Selenium.Support' 中找不到 'PageObjects' 类型或命名空间。
当前上下文中不存在 'PageFactory' 的名称。
等等...
请参见下面的截图:
using OpenQA.Selenium.Support.PageObjects;
我是否正确理解 PageFactory 现在已被弃用?
这是原因吗?
我可以使用什么替代?
有人能给我一个链接或建议吗?
<details>
<summary>英文:</summary>
I am very new to the test automation.
1. I run Visual Studio 2022, Version 17.6.2
2. I have NuGet packages: Selenium.WebDriver, Selenium.Support, Selenium.Chrome.WebDriver,
Gherkin, NUnit, NUnit3TestAdapter, xunit, BoDi, SpecFlow.Internal.Json
I try to implement the POM model testing using an example I found on the web.
**POM:**
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium.Support.PageObjects;
using OpenQA.Selenium;
namespace POMExample.PageObjects
{
internal class HomePage
{
private IWebDriver driver;
public HomePage(IWebDriver driver)
{
this.driver = driver;
PageFactory.InitElements(driver, this);
}
[FindsBy(How = How.CssSelector, Using = ".fusion-main-menu a[href*='about']")]
private IWebElement about;
[FindsBy(How = How.ClassName, Using = "fusion-main-menu-icon")]
private IWebElement searchIcon;
public void goToPage()
{
driver.Navigate().GoToUrl("http://www.swtestacademy.com");
}
public AboutPage goToAboutPage()
{
about.Click();
return new AboutPage(driver);
}
}
}
**Test**
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using POMExample.PageObjects;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace POMExample
{
public class TestClass
{
private IWebDriver driver;
[SetUp]
public void SetUp()
{
driver = new ChromeDriver();
driver.Manage().Window.Maximize();
}
[Test]
public void SearchTextFromAboutPage()
{
HomePage home = new HomePage(driver);
home.goToPage();
AboutPage about = home.goToAboutPage();
ResultPage result = about.search("selenium c#");
result.clickOnFirstArticle();
}
[TearDown]
public void TearDown()
{
driver.Close();
}
}
}
However POM Indicates errors:
The type or namespace name 'PageObjects' does not exist in the namespace 'OpenQA.Selenium.Support'
The name 'PageFactory' does not exist in the current context
etc...
see the screenshot below:
[![enter image description here][1]][1]
using OpenQA.Selenium.Support.PageObjects;
Do I understand it right PageFactory is deprecated now ?
Is it the reason?
What can I use instead?
Can somebody give me a link, advice, please
[1]: https://i.stack.imgur.com/qKoes.png
</details>
# 答案1
**得分**: 3
你是正确的 - Selenium的"PageFactory"从版本3.11开始已经被弃用:
> https://ultimateqa.com/selenium-3-11-released/
>
> 在C#中,从版本3.11开始,PageFactory已经被弃用。这实际上是一个很好的变化,因为它防止了使用Selenium贡献者不推荐的类。此外,不使用PageFactory将防止用户遇到许多在使用简单的运行时元素定位时不会出现的奇怪元素异常。
链接继续:
> 这绝不意味着你应该停止使用页面对象模式。
> 这是一个完全独立的概念。您可以在不使用PageFactory.cs的情况下使用页面对象模式。后者只是一个与设计模式无关的Selenium实现。
最后:
> 使用[验收测试驱动自动化](https://ultimateqa.com/acceptance-test-driven-automation/)非常简单。以下是一个符合[页面对象最佳实践](https://techbeacon.com/app-dev-testing/6-rules-high-quality-page-object-patterns)的类的示例:
>
> public class ProductsPage : BasePage
> {
> private readonly string _pageUrlPart;
>
> public ProductsPage(IWebDriver driver) : base(driver)
> {
> _pageUrlPart = "inventory.html";
> }
>
> // 可以使用显式等待通过ExpectedConditions来定位元素
> public bool IsLoaded => Wait.UntilIsDisplayedById("inventory_filter_container");
>
> // 外部测试API无法访问元素
> private IWebElement LogoutLink => _driver.FindElement(By.Id("logout_sidebar_link"));
>
> // 也可以在不使用ExpectedConditions的情况下定位元素
> private IWebElement HamburgerElement => _driver.FindElement(By.ClassName("bm-burger-button"));
>
> public int ProductCount =>
> _driver.FindElements(By.ClassName("inventory_item")).Count;
>
> // 我们使用组合来在另一个页面对象中包含一个页面对象
> public CartComponent Cart => new CartComponent(_driver);
>
> public void Logout()
> {
> HamburgerElement.Click();
> LogoutLink.Click();
> }
> }
<details>
<summary>英文:</summary>
You're correct - Selenium "PageFactory" is deprecated as of v3.11:
> https://ultimateqa.com/selenium-3-11-released/
>
> PageFactory in C# is deprecated as of version 3.11. This is actually a
> great change because it prevents usage of a class that is not
> recommended by the Selenium contributors. Furthermore, not using
> PageFactory will prevent users from many weird element exceptions that
> aren’t experienced when using a simple runtime element locator.
The link continues:
> This in no way means that you should stop using Page Objects Pattern.
> This is totally a separate concept. You can use Page Object Pattern
> without the PageFactory.cs. The latter is just a Selenium
> implementation that has no relation with a design pattern.
Finally:
> Avoiding PageFactory is very simple using [Acceptance Test Driven
> Automation](https://ultimateqa.com/acceptance-test-driven-automation/).
> Here’s an example of a class that meets all [Page Object best
> practices](https://techbeacon.com/app-dev-testing/6-rules-high-quality-page-object-patterns):
>
> public class ProductsPage : BasePage
> {
> private readonly string _pageUrlPart;
>
> public ProductsPage(IWebDriver driver) : base(driver)
> {
> _pageUrlPart = "inventory.html";
> }
>
> // An element can be located using ExpectedConditions through an explicit wait
> public bool IsLoaded => Wait.UntilIsDisplayedById("inventory_filter_container");
>
> //elements are not accessible for the external test API
> private IWebElement LogoutLink => _driver.FindElement(By.Id("logout_sidebar_link"));
>
> // An element can also be located without ExpectedConditions
> private IWebElement HamburgerElement => _driver.FindElement(By.ClassName("bm-burger-button"));
>
> public int ProductCount =>
> _driver.FindElements(By.ClassName("inventory_item")).Count;
>
> //We are using Composition to have one page object living in another page object
> public CartComponent Cart => new CartComponent(_driver);
>
> public void Logout()
> {
> HamburgerElement.Click();
> LogoutLink.Click();
> }
> }
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论