如何在 Selenium 代码中存储和列出变量?
How to store and list out variables in Selenium code?
我已经创建了我的 selenium 测试,但是我想开始清理它们以提高可读性和重用性。你如何处理你的变量?
我考虑过建立某种可以查找的按钮字典,但认为这可能会导致比解决问题更多的问题。
[Test]
public static void TestAccrualRuleSet()
{
//Setup buttons and variables
IWebDriver driver = new ChromeDriver();
var hamburgerMenu = By.XPath("//*[@id='menu-toggle']/span/i");
var settingsMenuButton = By.XPath("//*[@id='ulAdminNavBar']/li[4]/a");
var timeAndLaborMgmtButton = By.XPath("//*[@id='ulAdminNavBar']/li[4]/ul/li[11]/a");
var timeOffTrackingButton = By.XPath("//*[@id='ulAdminNavBar']/li[4]/ul/li[11]/ul/li[2]/a");
var actionMenu = By.Id("ucAccrualRules_ddlAccrual");
var ruleNameTextBox = By.Id("ucAccrualRules_ucAccrualRule_txtRuleName");
var accrualRuleFrequencyDropDown = By.Id("ucAccrualRules_ucAccrualRule_cboAccrualType");
var dropDownAccrualTypes = By.Id("ucAccrualRules_ucAccrualRule_hourTypes");
var dropDownAccrualTypesCheckBox1 = By.Id("ucAccrualRules_ucAccrualRule_hourTypes_0");
var dropDownAccrualTypesCheckBox2 = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_hourTypes_1");
var dropDownAccrualTypesCheckBox3 = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_hourTypes_6");
var maxCarryForwardTextBox = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_txtMaxRollover");
var accrualWaitingTextBox = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_txtAccrualWaitingPeriod");
var saveButton = By.XPath("//*[@id='ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_cmdUpdateName']");
var savedSuccessfully = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_UCErrorRuleProperties_lblMessage");
var propertiesButton = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_tpAccuralRulePropertiesnewForms");
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
//Begin test
AppExtensions.LoginUsingChrome(driver);
AppExtensions.SelectCompany(driver, "Ren's Test Account");
System.Threading.Thread.Sleep(1500);
WebDriverExtensions.Element_Click(driver, hamburgerMenu);
System.Threading.Thread.Sleep(1500);
虽然这不是整个测试,但它向您展示了我用来存储 buttons/links 我需要执行测试的大量变量列表的示例。关于如何以及在何处为 Selenium 测试存储这些变量的最佳实践是什么?
建议您在 classes 中对变量进行分组。每个页面将有一个 class,并将该页面的 Web 元素的所有变量移动到相应的 class 中。
这称为 POM 或页面对象模型。
您可以更进一步,向那些 classes 添加方法,涵盖特定页面的多个操作,甚至导航到其他页面。提示:导航方法将导航并等待加载下一个页面和 return 该目标页面的 POM 实例 class.
一种方法是您可以创建一个属性文件并在其中维护所有 xpath 等。然后只需参考 class 中的属性文件,因为需要使用 xpath 或定位器访问变量。这样,如果任何 xpath 发生变化,您只有一个文件要更新,即属性文件。示例:
Inside home.properties file you can have xpath as
searchBtn = //input[@elementid = 'abc']
this.properties = new Properties();
InputStream input = new FileInputStream("home.properties");
this.properties.load(input);
//Inside your class file you can access xpath as
String searchBtn = By.xpath(properties.get("searchButton"))
我想不出其他方法。
通常人们会选择两种模式:
- Object Repository - to store elements data in external source. Alternatively you can go for SpecFlow and keep element locators in Gherkin 个文件。
- Page Object Model - UI 的抽象层,主要思想是将测试逻辑从 UI 表示中分离出来,因此如果 UI 发生变化,测试代码仍然保持不变
我已经创建了我的 selenium 测试,但是我想开始清理它们以提高可读性和重用性。你如何处理你的变量?
我考虑过建立某种可以查找的按钮字典,但认为这可能会导致比解决问题更多的问题。
[Test]
public static void TestAccrualRuleSet()
{
//Setup buttons and variables
IWebDriver driver = new ChromeDriver();
var hamburgerMenu = By.XPath("//*[@id='menu-toggle']/span/i");
var settingsMenuButton = By.XPath("//*[@id='ulAdminNavBar']/li[4]/a");
var timeAndLaborMgmtButton = By.XPath("//*[@id='ulAdminNavBar']/li[4]/ul/li[11]/a");
var timeOffTrackingButton = By.XPath("//*[@id='ulAdminNavBar']/li[4]/ul/li[11]/ul/li[2]/a");
var actionMenu = By.Id("ucAccrualRules_ddlAccrual");
var ruleNameTextBox = By.Id("ucAccrualRules_ucAccrualRule_txtRuleName");
var accrualRuleFrequencyDropDown = By.Id("ucAccrualRules_ucAccrualRule_cboAccrualType");
var dropDownAccrualTypes = By.Id("ucAccrualRules_ucAccrualRule_hourTypes");
var dropDownAccrualTypesCheckBox1 = By.Id("ucAccrualRules_ucAccrualRule_hourTypes_0");
var dropDownAccrualTypesCheckBox2 = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_hourTypes_1");
var dropDownAccrualTypesCheckBox3 = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_hourTypes_6");
var maxCarryForwardTextBox = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_txtMaxRollover");
var accrualWaitingTextBox = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_txtAccrualWaitingPeriod");
var saveButton = By.XPath("//*[@id='ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_cmdUpdateName']");
var savedSuccessfully = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_UCErrorRuleProperties_lblMessage");
var propertiesButton = By.Id("ctl00_ContentPlaceHolder1_ucAccrualRules_ucAccrualRule_tpAccuralRulePropertiesnewForms");
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
//Begin test
AppExtensions.LoginUsingChrome(driver);
AppExtensions.SelectCompany(driver, "Ren's Test Account");
System.Threading.Thread.Sleep(1500);
WebDriverExtensions.Element_Click(driver, hamburgerMenu);
System.Threading.Thread.Sleep(1500);
虽然这不是整个测试,但它向您展示了我用来存储 buttons/links 我需要执行测试的大量变量列表的示例。关于如何以及在何处为 Selenium 测试存储这些变量的最佳实践是什么?
建议您在 classes 中对变量进行分组。每个页面将有一个 class,并将该页面的 Web 元素的所有变量移动到相应的 class 中。 这称为 POM 或页面对象模型。 您可以更进一步,向那些 classes 添加方法,涵盖特定页面的多个操作,甚至导航到其他页面。提示:导航方法将导航并等待加载下一个页面和 return 该目标页面的 POM 实例 class.
一种方法是您可以创建一个属性文件并在其中维护所有 xpath 等。然后只需参考 class 中的属性文件,因为需要使用 xpath 或定位器访问变量。这样,如果任何 xpath 发生变化,您只有一个文件要更新,即属性文件。示例:
Inside home.properties file you can have xpath as
searchBtn = //input[@elementid = 'abc']
this.properties = new Properties();
InputStream input = new FileInputStream("home.properties");
this.properties.load(input);
//Inside your class file you can access xpath as
String searchBtn = By.xpath(properties.get("searchButton"))
我想不出其他方法。
通常人们会选择两种模式:
- Object Repository - to store elements data in external source. Alternatively you can go for SpecFlow and keep element locators in Gherkin 个文件。
- Page Object Model - UI 的抽象层,主要思想是将测试逻辑从 UI 表示中分离出来,因此如果 UI 发生变化,测试代码仍然保持不变