如何保持 Selenium 测试用例 DRY?

软件测试
2022-02-05 18:16:51

我对 Selenium 有点陌生,我有一个问题。每当我写一个测试用例时,那个测试用例都是从登录开始的,每次都是一样的四个步骤。如果我更改该帐户的密码,我将不得不在每个测试用例中单独更改它。

如何打破这些登录命令以使我的测试更加干燥?

4个回答

squeemish 和 Phil 提供了很好的建议。

对于他们出色的答案,我要补充:如果您使用 Selenium IDE 通过记录来创建测试,请停止这样做。(很快)学习如何使用您选择的编程语言从头开始编写测试。仅使用 Selenium IDE(和其他记录和回放工具)来探索和尝试想法。

我提出建议的原因是记录和播放工具无法了解您的意图,或者是什么让给定的 UI Gizmo 对您感兴趣。它所知道的只是你点击了它或在其中输入了一些东西。因此,它永远无法生成 squeemish 和 Phil 所描述的那种有意义的抽象。

学习如何从头开始编写测试的一种方法是从您通过 Selenium IDE 创建的测试开始。请注意测试中最困扰您的是什么“代码气味”。了解应用什么重构来消除异味。冲洗并重复,直到测试具有表现力和可维护性。然后在下一个测试中再做一次。

随着时间的推移,您将了解您希望测试的外观。然后,您可以使用所学的知识从头开始编写好的测试。

对于不熟悉测试自动化的人,我倾向于关注三个原则:

  • 删除重复
  • 说出每一个重要的想法
  • 隐藏附带的细节

这是一篇论文,我举了一个例子来说明如何做到这一点: http: //dhemery.com/pdf/writing_maintainable_automated_acceptance_tests.pdf

对于这个例子,我留在工具(机器人框架)中,而不是转向更通用的编程语言。但是原理是一样的。这是 Bob Martin 使用不同的测试工具 (FitNesse) 应用相同原理的精彩视频:http: //blog.objectmentor.com/articles/2009/12/07/writing-maintainable-automated-acceptance-tests

使用抽象类。我将整个登录过程放在一个抽象类中,并在我的测试中首先调用该方法。如果需要更改任何凭据,您只需在一处更改它们。

我的抽象类中的方法:

protected void getBaseURLAndLoginTestUser() throws Exception
{
    driver.get(BASE_URL);

    assertEquals("some text here", findElementBySelector("h3").getText());

    WebElement userName = findElementById("j_username");
    userName.clear();
    userName.sendKeys("testing1");

    WebElement password = findElementById("j_password");
    password.clear();
    password.sendKeys("testing1");

    WebElement loginButton = findElementById("modalDialogButton");
    loginButton.click();
}

然后在我的摘要中的另一种方法中使用它:

protected void setup() throws Exception 
{
        getBaseURLAndLoginTestUser();

        WebElement selectRole =  findElementByXpath("//div[@id='selectRoles']/ul/li[text()='loginRole (Dept C)']");
        selectRole.click();

        Thread.sleep(2000);

        WebElement continueButton = findElementById("continue");
        continueButton.click();

        Thread.sleep(2500);

        assertEquals("some text here", findElementBySelector("header.container_12.clearfix > h1").getText());

        String destinationUrl = navigateToUrl(getNavigationUrl());
        driver.get(destinationUrl);
    }

最后,你在我的测试课上看到的是:

public class NameOfClass extends AbstractClass
{
    @Override
    @BeforeClass
    public void setup() throws Exception
    {
        super.setup();
    }
}

我必须使用super,因为我更改了要导航到的 URL,该 URL 包含在另一个抽象类中。

我可以建议你使用 RobotFramework+SeleniumLibrary 来测试网站(在这里你可以找到一个演示http://code.google.com/p/robotframework-seleniumlibrary/wiki/Demo)。

您可以声明要在 TC 中使用的变量,因此如果您更改密码,则无需在每个 TC 中更改

# global variables -- 
${user} username  
${password}  password

# tc --
...
Input Text   usr  ${user}
Input Password   pwd  ${password}
...

你可以在这里看到更多: