【问题标题】:Identifying the same Web Elements with Selenium使用 Selenium 识别相同的 Web 元素
【发布时间】:2017-06-20 03:04:32
【问题描述】:

我是一名自动化工程师,我目前正在尝试为可持续的网页创建测试用例(我可以在以后运行并且仍然通过)

这是我的问题:

我正在尝试选择具有相同确切类名的多个 Web 按钮。现在我可以“选择”这些按钮,但这些只是 临时 x 可能会更改的路径。

对于相同的网络元素,我需要唯一的 ID(或某种区分它们的方法)。 x 路径的唯一区别是:

  • 我可以找到每个按钮的 HTML 格式代码,但是如果移动一个按钮,我的测试将失败。

  • HTML 代码是类名 + 按钮的第 n 个。但是,如果从网页中取出一个按钮,我的测试将再次失败。

//*[@id="tenant-details-accordion"]/div[1]/div[2]/div/div[2]/div[1]/div/a/div //*[@id="tenant-details-accordion"]/div[1]/div[2]/div/div[2]/div[2]/div/a/div //*[@id="tenant-details-accordion"]/div[1]/div[2]/div/div[2]/div[3]/div/a/div

^^上面的代码是我目前使用 Selenium 找到每个按钮的方式

如果我复制每个类 x 路径,这就是我得到的

<div class="src-js-components-DateControl-___DateControl__dateControl___2nYAL"><a tabindex="0"><div class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"></div><!-- react-text: 392 -->Set +<!-- /react-text --></a></div>

 <div class="src-js-components-DateControl-___DateControl__dateControl___2nYAL"><a tabindex="0"><div class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"></div><!-- react-text: 386 -->Set +<!-- /react-text --></a></div>

 <div class="src-js-components-DateControl-___DateControl__dateControl___2nYAL"><a tabindex="0"><div class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"></div><!-- react-text: 398 -->Set +<!-- /react-text --></a></div>

我已经与开发团队讨论过这个问题,但是他们告诉我为这些 Web 元素分配唯一 ID 是一个很大的禁忌。 (当我们投入生产时,这与项目的全球化有关)即使他们确实分配了唯一 ID,他们告诉我在项目可以投入生产之前他们必须剥离它们。这最终会使我的测试最终变得毫无用处......

我现在来 Stack Overflow 寻求帮助,我在网上查找的所有内容都无法给我答案,但这似乎是 QA 和开发部门之间的有效问题。

有没有办法将 ID 分配给 Web 元素,以便使用 selenium 的测试人员可以识别它们,但不会影响开发人员在整个项目中使用该元素的能力? p>

编辑: 使用我公司使用的框架,我实际上并没有在 selenium 中编写任何代码。我将 Xpath 保存到一个对象,然后在手动测试中使用预先存在的方法调用该对象。我只能选择要保存在对象中的 Xpath。

稍后我将与 Dev 交谈,让他们解释大的“不可以”,以便我可以与大家交流。感谢您的时间和意见

例如:

BirthDateSet= someXpath

Click() using {BirthDateSet}

这里有一些图片可以帮助您直观地了解

【问题讨论】:

  • 分享一些HTML 提到的按钮的代码示例
  • 提供的数据是XPath 表达式,而HTML 代码示例应该看起来像&lt;div id="tenant-details-accordion"&gt; &lt;div&gt;...&lt;/div&gt; &lt;/div&gt;... 你能也分享这个信息吗?您可以从浏览器HTMLinspector 获取它
  • 开发人员是否说过为什么他们认为“为这些 Web 元素分配唯一 ID 是一个很大的禁忌”?我可以猜测,也许这些是动态创建的对象,但您仍然可以将 ID 分配给具有可预测且动态值的元素。至于那是“不可以”,您的开发人员并不知情。

标签: selenium testing selenium-webdriver automation qa


【解决方案1】:

您可以简化您的XPath,使其对DOM 中可能发生的变化不那么敏感:

//div[@class="src-js-components-DateControl-___DateControl__icon___2z6Ak null"][N] # Where N is button index

如果类名2z6Ak这部分是动态生成的,试试:

//div[starts-with(@class, "src-js-components-DateControl-___DateControl__icon___")][N] # Where N is button index

【讨论】:

    【解决方案2】:

    使用 xpath 到达所需按钮的另一种方法如下:

    //*[@id='tenant-details-accordion']/descendant::div[contains(@class, 'DateControl__icon')][1]
    

    xpath 上面应该能够选择第一个出现的按钮。同样,对于第二个出现的按钮,xpath 将变为:

    //*[@id='tenant-details-accordion']/descendant::div[contains(@class, 'DateControl__icon')][2]
    

    因此,您可以根据页面上所需按钮的出现级别继续替换谓词([2])。

    【讨论】:

      【解决方案3】:

      您可以要求开发人员为这些按钮添加属性 所以而不是:

      <button class="common_class_name"> 
      <button class="common_class_name"> 
      <button class="common_class_name"> 
      

      对于您将看到的每个按钮

      <button class="common_class_name" test-id="uniqueAttributeForButton1">
      <button class="common_class_name" test-id="uniqueAttributeForButton2">
      <button class="common_class_name" test-id="uniqueAttributeForButton3">
      

      在您的测试中,您可以使用 css 选择器找到这些按钮 例如C#代码:

      var buttonLocator = "[test-id=\"uniqueAttributeForButton1\"]";

      WebElement button = driver.FindElement(By.CssSelector(buttonLocator));

      【讨论】:

        【解决方案4】:

        如果开发者不想添加唯一 ID 或属性(奇怪的是他们为什么不想这样做),您可以尝试这样的操作:

                //return div class 'col-sm-4' which contain text 'Activation Date'
                var parentDiv = driver.FindElement(By.XPath("//div[contains(@class, 'col-sm-4') and contains(., 'Activation Date')]"));
        
                //should return div with icon you want e.g. Click
                var childElement = parentDiv.FindElement(By.CssSelector(".DateControl__icon")); 
                childElement.Click();
        

        【讨论】:

          【解决方案5】:

          您可以使用nth 方法来查找您的独特元素或使用其他方法,这不会解决您的真正问题,即您的同事开发人员不合作 自动化测试应该(除其他外)为开发人员提供服务,让他们知道他们没有尽快破坏任何东西,但如果他们没有付出任何努力,那你为什么要完全投资它..?

          他们可能甚至不会看结果。尤其是当您的定位器采用div[2]/div[3]... 的形式时,它会经常中断,您将失去他们对自动化的信任

          我不是前端专家,但我见过生产中的企业产品使用 G10N 和 L10N 以及其他长词,它们的 HTML 中有 id,所以如果我是你,我会更深入地了解 为什么?这么大的禁忌,我觉得这听起来很奇怪......

          所以你问错了问题,应该是这样的 ~ 如何在全球 Web 应用程序中使用 React 向 HTML 添加唯一 ID?应该问是开发商。

          附带说明,正如许多人倾向于认为的那样,自动化主要是将手动测试转移到自动化,它还会在公司内部的沟通中发现“错误”。在这个主题上引用一个伟大的blog post

          与直觉相反,开发自动化的障碍更大 要么是低优先级的错误,要么是不是错误的东西 任何。这些障碍可能是糟糕设计的征兆 开发实践甚至是低效沟通的症状 组织中的模式(通常是由 组织架构!康威定律就是一个典型的例子)。

          祝你好运!

          【讨论】:

            【解决方案6】:

            编辑: 感谢您的代码。因此,如果您查看您的代码,您会发现尽管您所追求的具有相似的属性,但页面中的某些元素可以让您识别您所追求的。因此,假设您想要 SET 出生日期之后的链接,然后使用: //div[contains(text(),'Birth Date')]/div/a/div

            所以要重用这个xpath,只需替换文本String.format("//div[contains(text(),'%s')]/div/a/div", labelName);

            OLD:如果你想临时为元素分配一个属性,我相信你可以通过 javascript element.setAttribute() 来做到这一点,你可以通过 executeScript() 函数运行它。

            按钮没有文字吗?您是说按钮彼此交换位置吗?还是不想使用按钮的索引?

            【讨论】:

            • 要为元素设置新属性以便能够找到它为driver.findElement(bySomeUniqueIdentifier),您应该首先选择它为document.querySelector(bySomeUniqueIdentifier),对吗?因此,在当前情况下,您的建议毫无意义
            • 我不太明白这个问题。我认为他能够识别元素(因为是的..),但想以这样一种方式操纵它们,以便在测试中更容易识别它们......
            【解决方案7】:

            我知道您想选择“Set +”按钮,对吗?

            如果是这样,您可以尝试在 @id="tenant-details-accordion" 元素下找到所有带有特定文本的按钮:

            //*[@id="tenant-details-accordion"]//*[text()='Set +']
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-01-15
              • 2022-10-18
              • 1970-01-01
              • 1970-01-01
              • 2019-07-03
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多