Guide to Selenium with JUnit / TestNG – 使用JUnit/TestNG的Selenium指南

最后修改: 2016年 12月 5日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.介绍

This article is a quick, practical introduction to working with Selenium and writing tests with JUnit and TestNG.

本文是关于使用Selenium和使用JUnitTestNG编写测试的快速、实用介绍。

2. Selenium Integration

2.Selenium集成

In this section, we’ll start with a simple scenario – opening a browser window, navigating to a given URL and looking for some desired content on the page.

在本节中,我们将从一个简单的场景开始–打开一个浏览器窗口,导航到一个给定的URL,在页面上寻找一些想要的内容。

2.1. Maven Dependencies

2.1.Maven的依赖性

In the pom.xml file, add the following dependency:

pom.xml文件中,添加以下依赖关系。

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.4.0</version>
</dependency>

The latest version can be found in the Maven Central Repository.

最新版本可以在Maven中央仓库中找到。

2.2. Selenium Configuration

2.2.Selenium配置

First, create a new Java class file called SeleniumConfig:

首先,创建一个名为SeleniumConfig的新Java类文件。

public class SeleniumConfig {

    private WebDriver driver;

    //...

}

Given we’re using a Selenium 3.x version, we have to specify the path of an executable GeckoDriver file (based on your OS) using a system property called webdriver.gecko.driver The latest version of the GeckoDriver may be downloaded from Github Geckodriver Releases.

鉴于我们使用的是Selenium 3.x版本,我们必须使用一个名为webdriver.gecko.driver的系统属性指定一个可执行的GeckoDriver文件的路径(基于你的操作系统)。GeckoDriver的最新版本可以从Github Geckodriver Releases下载。

Let’s now initialize the WebDriver in the constructor, we’ll also set 5 seconds as a time-out for WebDriver to wait for an element on the page to appear:

现在让我们在构造函数中初始化WebDriver,我们还将设置5秒作为WebDriver的超时时间,以等待页面上的元素出现。

public SeleniumConfig() {
    Capabilities capabilities = DesiredCapabilities.firefox();
    driver = new FirefoxDriver(capabilities);
    driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}

static {
    System.setProperty("webdriver.gecko.driver", findFile("geckodriver.mac"));
}

static private String findFile(String filename) {
   String paths[] = {"", "bin/", "target/classes"};
   for (String path : paths) {
      if (new File(path + filename).exists())
          return path + filename;
   }
   return "";
}

This configuration class contains a couple of methods that we will ignore for now, but we will see more about these on the second part of this series.

这个配置类包含几个方法,我们现在将忽略这些方法,但我们将在本系列的第二部分看到更多关于这些方法的信息。

Next, we will need to implement a SeleniumExample class:

接下来,我们将需要实现一个SeleniumExample类。

public class SeleniumExample {

    private SeleniumConfig config;
    private String url = "http://www.baeldung.com/";

    public SeleniumExample() {
        config = new SeleniumConfig();
        config.getDriver().get(url);
    }

    // ...
}

In here, we will initialize the SeleniumConfig and set the desired URL to navigate to. Similarly, we’ll implement a simple API to close the browser and get the title of the page:

在这里,我们将初始化SeleniumConfig,并设置所需的URL以导航到。同样地,我们将实现一个简单的API来关闭浏览器并获得页面的标题。

public void closeWindow() {
    this.config.getDriver().close();
}

public String getTitle() {
    return this.config.getDriver().getTitle();
}

In order to navigate to the About section of baeldung.com, we need to create a closeOverlay() method that checks and closes the overlay on a homepage load. Thereafter, we navigate to the About Baeldung page using the getAboutBaeldungPage() method:

为了导航到baeldung.com的About部分,我们需要创建一个closeOverlay()方法,在主页加载时检查并关闭覆盖层。此后,我们使用getAboutBaeldungPage()方法导航到关于Baeldung的页面。

public void getAboutBaeldungPage() {
    closeOverlay();
    clickAboutLink();
    clickAboutUsLink();
}

private void closeOverlay() {
    List<WebElement> webElementList = this.config.getDriver()
      .findElements(By.tagName("a"));
    if (webElementList != null) {
       webElementList.stream()
         .filter(webElement -> "Close".equalsIgnoreCase(webElement.getAttribute("title")))
         .filter(WebElement::isDisplayed)
         .findAny()
         .ifPresent(WebElement::click);
    }
}

private void clickAboutLink() {
    Actions actions = new Actions(config.getDriver());
    WebElement aboutElement = this.config.getDriver()
        .findElement(By.id("menu-item-6138"));
        
    actions.moveToElement(aboutElement).perform();
}

private void clickAboutUsLink() {
    WebElement element = this.config.getDriver()
        .findElement(By.partialLinkText("About Baeldung."));
    element.click();
}

We can check if the required information is available on the displayed page:

我们可以检查所需的信息是否在所显示的页面上可用。

public boolean isAuthorInformationAvailable() {
    return this.config.getDriver()
        .getPageSource()
        .contains("Hey ! I'm Eugen");
}

Next, we are going to test this class with both JUnit and TestNG.

接下来,我们要用JUnit和TestNG来测试这个类。

3. With JUnit

3.使用JUnit

Let’s create a new test class as SeleniumWithJUnitLiveTest:

让我们创建一个新的测试类作为SeleniumWithJUnitLiveTest:

public class SeleniumWithJUnitLiveTest {

    private static SeleniumExample seleniumExample;
    private String expectedTitle = "About Baeldung | Baeldung";

    // more code goes here...

}

We’re going to use the @BeforeClass annotation from org.junit.BeforeClass to do an initial setup. In this setUp() method we are going to initialize the SeleniumExample object:

我们将使用来自org.junit.BeforeClass@BeforeClass注解来进行初始设置。在这个setUp()方法中,我们将初始化SeleniumExample对象。

@BeforeClass
public static void setUp() {
    seleniumExample = new SeleniumExample();
}

In a similar way, when our test case finishes, we should close the newly opened browser. We’re going to do this with @AfterClass annotation – to clean up the settings when test case execution has finished:

以类似的方式,当我们的测试用例完成后,我们应该关闭新打开的浏览器。我们要用@AfterClass注解来做这件事–在测试用例执行结束后清理设置。

@AfterClass
public static void tearDown() {
    seleniumExample.closeWindow();
}

Please note the static modifier on our SeleniumExample member variable – because we need to use this variable in the setUp() and tearDown() static methods – @BeforeClass and @AfterClass can be invoked on static methods only.

请注意我们的SeleniumExample成员变量上的static修饰符–因为我们需要在setUp()tearDown()静态方法中使用这个变量–@BeforeClass@AfterClass只能对静态方法进行调用。

Finally, we can create our full test:

最后,我们可以创建我们的完整测试。

@Test
public void whenAboutBaeldungIsLoaded_thenAboutEugenIsMentionedOnPage() {
    seleniumExample.getAboutBaeldungPage();
    String actualTitle = seleniumExample.getTitle();
 
    assertNotNull(actualTitle);
    assertEquals(expectedTitle, actualTitle);
    assertTrue(seleniumExample.isAuthorInformationAvailable());
}

This test method asserts that the title of the web page is not null and is set as expected. Besides that, we check that the page contains the expected information.

这个测试方法断言,网页的标题不是null,并且是按照预期设置的。除此之外,我们还检查该网页是否包含预期的信息。

When the test runs, it simply opens the URL in Firefox and subsequently closes it after the title of the web page and content have been verified.

当测试运行时,它只是在Firefox中打开URL,随后在网页的标题和内容被验证后关闭它。

4. With TestNG

4.使用TestNG

Let’s now use TestNG to run our test case/suite.

现在让我们使用TestNG来运行我们的测试案例/套件。

Note that if you’re using Eclipse, the TestNG plugin may be downloaded and installed from the Eclipse Marketplace.

请注意,如果你使用的是Eclipse,TestNG插件可以从Eclipse Marketplace下载和安装。

First, let’s create a new test class:

首先,让我们创建一个新的测试类。

public class SeleniumWithTestNGLiveTest {

    private SeleniumExample seleniumExample;
    private String expectedTitle = "About Baeldung | Baeldung";

    // more code goes here...

}

We’ll use a @BeforeSuite annotation from org.testng.annotations.BeforeSuite to instantiate our SeleniumExample class. The setUp() method will be launched just before the test suite is activated:

我们将使用来自org.testng.annotations.BeforeSuite@BeforeSuite注解来实例化我们的SeleniumExample类setUp()方法将在测试套件被激活之前启动。

@BeforeSuite
public void setUp() {
    seleniumExample = new SeleniumExample();
}

Similarly, we’ll use the @AfterSuite annotation from org.testng.annotations.AfterSuite to close our opened browser once the test suite has completed:

同样,我们将使用@AfterSuite注解,来自org.testng.annotations.AfterSuite,在测试套件完成后关闭我们打开的浏览器。

@AfterSuite
public void tearDown() {
    seleniumExample.closeWindow();
}

Finally, let’s implement our test:

最后,让我们来实现我们的测试。

@Test
public void whenAboutBaeldungIsLoaded_thenAboutEugenIsMentionedOnPage() {
    seleniumExample.getAboutBaeldungPage();
    String actualTitle = seleniumExample.getTitle();
 
    assertNotNull(actualTitle);
    assertEquals(expectedTitle, actualTitle);
    assertTrue(seleniumExample.isAuthorInformationAvailable());
}

After a successful completion of the test suite, we find HTML and XML reports in the test-output folder of the project. These reports summarize the test results.

在成功完成测试套件后,我们在项目的test-output文件夹中找到HTML和XML报告。这些报告总结了测试结果。

5. Conclusion

5.结论

In this quick article, we’ve focused on a quick intro to writing Selenium 3 tests with both JUnit and TestNG.

在这篇快速文章中,我们着重介绍了用JUnit和TestNG编写Selenium 3测试的快速入门。

As always, the source for the article is available over at GitHub.

一如既往,文章的源代码可在GitHub上获得