【问题标题】:How do I iterate through a table to enter data如何遍历表以输入数据
【发布时间】:2020-01-03 09:26:19
【问题描述】:

我有一个使用 Specflow、Selenium 和 C# 的测试框架。

Specflow 测试步骤如下所示(我使用的是数据表): 我在贷款目的部分创建了以下贷款目的

    |loan purposes     |moreinfo |active|
    |Debt Consolidation|True     |True  |
    |Home Improvements |True     |True  |

所以很明显,这个数据表中有 2 行,第一行只是标题。

在上述步骤的步骤定义中,我首先确定表中的计数并将其存储为变量(在上述实例中正确地给了我 2 的计数)。然后我遍历表中的行数并单击 UI 上的“添加按钮”以根据测试步骤添加所需的行数——因此在本例中,它正确地单击了两次添加按钮,添加了 2空白行。

    var data = dataTable.CreateSet<ProductLoanPurposeData>();

    var count = data.Count();
    for (int i = 0; i < count; i++)
    {
    ClickLoanPurposeAddButton();
    }

这就是我卡住的地方。 所以添加到 UI 上的每一行都有自己的类——我在我的 PageClass 中标记了这个元素“LoanPurposeRow”。 我想要做的是从 dataTable 的第一行获取数据,并将其输入到 UI 上的第一个“LoanPurposeRow”。如果我的数据表中有更多行,那么我想移动到第二个“LoanPurposeRow”并从数据表中的第二行获取数据,依此类推。

我一直在网上搜索并查看了各种答案,但没有找到执行上述操作所需的内容。提前致谢

【问题讨论】:

    标签: c# selenium datatables iteration specflow


    【解决方案1】:

    您的创建集正在将您的表转换为对象,因此您将相应地引用该对象。您需要像这样迭代您的数据对象。请注意,我删除了表格标题中的间距

    foreach(var item in data)
    {
        driver.FindElement(By.Id("LoanPurposeRow")).SendKeys(item.loanpurposes);
    ClickLoanPurposeAddButton();
    }
    

    它会抓取任何“贷款用途”的文本并将其输入到您的元素中。您将需要根据您所在的行调整您的 By 选择器。你可以初始化一个计数器。

    诚然,我没有在我的 selenium 代码中使用 CreateSet,我只是遍历下面的表格,它还允许您保持间距。

    foreach(var item in data.Rows)
    {
        driver.FindElement(By.Id("LoanPurposeRow")).SendKeys(item["loan purposes"]);
    ClickLoanPurposeAddButton();
    }
    

    无论采用哪种方式,第一次迭代都会从第一行获取所有数据,第二次迭代将从第二行获取所有数据,依此类推。

    This link 有更多关于 CreateSet 的信息

    【讨论】:

      【解决方案2】:

      AutomatedOrder 为您指明了正确的方向。您需要获取数据并调用 Selenium API 将数据输入到网页中。我想通过戴上我的“架构师”帽子让他的回答更进一步,让您更好地了解如何在Page Object Model 旁边使用 SpecFlow 步骤。这会在 SpecFlow 和 Selenium 之间强制分离关注点。

      1. 初始化 Selenium Web 驱动程序和register it with the SpecFlow dependency injection framework

      2. 创建一个代表网页的该部分的页面对象类:

        public class LoanPurposesPageObject
        {
            private readonly IWebDriver driver;
        
            // TODO: Change element locators to match your HTML structure
            private IWebElement AddLoanPurposeButton => driver.FindElement(By.XPath("//button[contains(., 'Add Loan Purpose')]"));
            private IWebElement LoanPurposesTextBox => driver.FindElement(By.Id("LoanPurposes"));
            private IWebElement MoreInfoTextBox => driver.FindElement(By.Id("MoreInfo"));
        
            public LoanPurposesPageObject(IWebDriver driver)
            {
                this.driver = driver;
            }
        
            public void Add(string loanPurposes, string moreInfo, bool isActive)
            {
                LoanPurposesTextBox.SendKeys(loanPurposes);
                MoreInfoTextBox.SendKeys(moreInfo);
        
                if (isActive)
                {
                    // TODO: Check radio button or select option in dropdown?
                }
                else
                {
                    // TODO: Check radio button or select option in dropdown?
                }
        
                AddLoanPurposeButton.Click();
            }
        }
        
      3. 修改您的步骤定义类以接受IWebDriver 对象作为构造函数参数并初始化页面对象。

        [Binding]
        public class YourStepDefinitions
        {
            private readonly LoanPurposesPageObject loanPurposes;
            private readonly IWebDriver driver;
        
            public YourStepDefinitions(IWebDriver driver)
            {
                this.driver = driver;
                loanPurposes = new LoanPurposesPageObject(driver);
            }
        
      4. 修改步骤定义方法,将数据从您的 ProductLoanPurposeData 对象传递到页面对象:

        [Binding]
        public class YourStepDefinitions
        {
            // ...
        
            [When(@"...")]
            public void YourStepThatUsesTheDataTable(Table table)
            {
                var data = table.CreateSet<ProductLoanPurposeData>();
        
                foreach (var row in data)
                {
                    loanPurposes.Add(row.LoanPurposes, row.MoreInfo, row.Active);
                }
            }
        }
        

      这使您可以清晰地分离 SpecFlow 内容和 Selenium 内容,并促进大量代码重用,同时保持适当的解耦。

      【讨论】:

        猜你喜欢
        • 2015-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-26
        • 2019-07-22
        • 2013-09-03
        • 1970-01-01
        相关资源
        最近更新 更多