【问题标题】:How can I call a JUnit test as the setup for another?如何将 JUnit 测试称为另一个测试的设置?
【发布时间】:2019-10-24 16:00:14
【问题描述】:

我正在尝试创建一个要求用户使用管理员帐户登录的 JUnit 测试。 为了避免重复代码,我进行了Login JUnit 测试和GoToAdminPage JUnit 测试。

  • 第一个访问登录页面并登录。
  • 第二次尝试访问只能由管理员访问的菜单,并且旨在从第一次离开的地方继续。对于GoToAdminPage,我想要的是从与Login 结束的相同页面和相同环境开始。

这个想法是,通过创建一个Login 自动化测试,我可以将它重用于我将来想做的任何需要管理员权限的测试。

我想做的是,在GoToAdminPagesetUp() 中,调用第一个测试。 但是,它的作用是为GoToAdminPage 启动一个测试浏览器,然后立即为Login 启动另一个测试浏览器,因为Login.tearDown() 包含driver.quit() 指令而关闭。

我想要的是 GoToAdminPage 期望在同一页面上直接获取 Login 结束,它没有 get 指令,因此它永远不会离开起始 Firefox 页面。

我已经尝试了几件事。我的每个测试都继承了BasicTest 类,它定义了许多东西(WebDriver、JS 执行器、通用实用程序函数等)。在那个类中,我创建了一个调用setUp()test()perform() 函数。

这样,在GoToAdminPage 中,我所要做的就是在GoToAdminPage.setUp() 中调用Login.perform(),从技术上讲,这将实现我想做的事情。但是,它没有,并且与我上面提到的效果相同。

在网上看,我看到我也可以这样GoToAdminPage extends Login,但结果也是一样的。

最后我尝试将整个Login.test() 进程放在Login 类中的一个单独函数中,我可以在GoToAdminPage 中调用它,但结果相同。

总而言之,似乎正在发生的事情是,当我在 GoToLoginPage 中调用另一个 JUnit 测试时,它会执行测试,但它是作为一个单独的测试进行的。

我想要的是能够从本质上进行一项大型测试,一旦我调用了Login,我就可以在我的用户登录后与登录后页面进行交互。 本质上,我只是希望GoToAdminPage 成为Login 流程的扩展。

这可能吗?

这是我当前的代码:

登录.java

public class Login extends BasicTest {

    /**
     * @throws java.lang.Exception
     */
    @Before
    public void setUp() throws Exception {
        super.setUp();
        driver.get(constants.connectionUrl);
    }

    /**
     * @throws java.lang.Exception
     */
    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    public void test() throws Exception {
        this.login(driver);
    }

    public void login(WebDriver d) throws InterruptedException {
        ...login process using webdriver....
    }
}

GoToAdminPage.java

public class GoToAdminPage extends BasicTest {

    Login Login = new Login();
    /**
     * @throws java.lang.Exception
     */
    @Before
    public void setUp() throws Exception {
        super.setUp();
        Login.login(driver);
    }

    /**
     * @throws java.lang.Exception
     */
    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    @Test
    public void test() throws Exception {
        ...post login test process...
    }
}

然而,这仍然具有上述效果。

【问题讨论】:

    标签: java selenium selenium-webdriver junit


    【解决方案1】:

    将“登录”步骤定义为常规方法(未使用@Test 注释)。然后,您可以从任何地方调用该方法。来自您的登录测试方法(在执行步骤后添加所需的断言)和来自任何 setUp 方法,而无需实际运行登录测试。

    【讨论】:

    • 这基本上就是我所做的。我在我的Login 类中定义了一个login() 方法,我在Login@Test 方法和GoToAdminPage@Before 方法中调用它。我会把代码放在OP中。
    【解决方案2】:

    最后我找到了解决办法:

    • GoToAdminPage 扩展Login

    • GoToAdminPage.setUp() 呼叫parent.setUp()

    • GoToAdminPage.test() 呼叫parent.test()

    使用它,我可以让我的第二个测试使用它的父级作为设置阶段。

    【讨论】:

      【解决方案3】:

      您应该应用Page Object Pattern,并创建一个登录对象页面。

      Web 自动化中最流行的模式之一是所谓的 页面对象模式。要了解该模式的主要目标, 首先,您需要考虑您的 Web 自动化测试在做什么。他们 导航到不同的网页并单击/键入/输入各种元素。 页面对象模式包含所有元素、动作和验证 发生在单个对象的页面上 - 页面对象。 source

      页面对象模式的一些优点如下,

      • 减少重复代码
      • 使测试更具可读性和健壮性
      • 提高测试的可维护性

      恕我直言,在测试用例之间创建依赖关系不是一个好习惯。

      例子:

      import org.openqa.selenium.WebDriver;
      import org.openqa.selenium.WebElement;
      import org.openqa.selenium.support.FindBy;
      import org.openqa.selenium.support.PageFactory;
      
      public final class LoginPage {
      
          @FindBy(id="username")
          private WebElement username;
      
          @FindBy(id="password")
          private WebElement password;
      
          @FindBy(id="loginBtn")
          private WebElement submit;
      
          public LoginPage(WebDriver driver) {
              PageFactory.initElements(driver, this);
          }
      
          public void submit(String username, String password) {
              this.username.sendKeys(username);
              this.password.sendKeys(password);
              submit.click();
          }
      }
      

      【讨论】:

      • 不幸的是,我正在处理一个页面由动态元素组成的项目,除了登录页面之外,没有任何页面可以保证存在。所以我的测试必须在每个模块的基础上编写。不过,我可以调整 POP 以使用模块而不是页面。这本质上就是我正在做的事情。许多推荐的实践——泛化和分解以防止代码重复和增加通用测试的数量——我计划使用并将使用。感谢您的FindBy 注释,将非常有帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-19
      • 2010-12-13
      • 2023-03-18
      相关资源
      最近更新 更多