断言后,Java Selenium关闭浏览器

时间:2016-08-01 13:18:13

标签: java unit-testing selenium selenium-webdriver

我有一个包含很多类的代码。
有一个类创建驱动程序 -

public class DriverDelegate {

    private String baseURL = "someLink";
    private WebDriver driver;
    private WebDriverWait wait;

    DriverDelegate(String url) {
        System.setProperty("webdriver.chrome.driver", "${directory}");
        driver = new ChromeDriver();
        driver.get(baseURL + url);
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        wait = new WebDriverWait(driver, 5);
    }

    public WebDriver getDriver() {
        return driver;
    }

我为每个测试创建新的驱动程序。我的大部分行都是包含assertTrue的行 -

public class UserInterfaceTests extends BaseTest{


    @Test
    public void headerClicker() throws java.lang.Exception {

        //Startup
        DriverDelegate driverDelegate = new DriverDelegate("url");
        WebDriver driver = driverDelegate.getDriver();

        //Some random assertTrue
        assertTrue("Test(HeaderClicker) - NoSuchElementException click", TestHelper.headerClicker(schedule, driver));

        //I hope that it is not neccessary to put up all helper classes like TestHelper or BaseTest

现在我从名为Startup -

的类启动我的测试
public class Startup{
    @Test
    public void HeaderClicker() throws Exception{ UserInterfaceTests UI = new UserInterfaceTests(); UI.headerClicker();}

我的问题是如何在assertTrue失败后关闭浏览器。像@AfterTest,@ AfterSuite等之类的东西不起作用,因为其他方法不能使用测试中使用的相同驱动程序。
有什么想法吗?

1 个答案:

答案 0 :(得分:0)

好的,我想在这里谈一些事情。首先,@ shutdown -h现在在他们的评论中是正确的,你不应该以编程方式创建测试类并自己运行他们的@Test方法。让测试运行框架处理(例如TestNG,JUnit等)。

然而,就实际问题而言,您需要预测试和后测试方法来处理在实际测试方法之前和/或之后发生的行为。但是,要使这些工作正常,您需要让测试框架处理测试的运行。您提到@AfterTest@AfterSuite对您的用例不正确,但不是出于您指定的原因(完全)。 TestNG中的@AfterTest仅在套件中指定的<test>节点内的所有类中的所有测试方法之后执行一次。 @AfterSuite仅在整个套件中的所有测试方法之后执行一次。您正在寻找的是@AfterMethod注释。

示例:

public class FooTest {

    private DriverDelegate driver;

    @BeforeMethod
    public void setup() {
        try {
            driver = new DriverDelegate("url");
        } catch (Exception ignore) { }
    }

    @AfterMethod
    public void tearDown() {
        try {
            driver.quit();
        } catch (Exception ignore) { }
        driver = null;
    }

    @Test
    public void foo() {
        // do test stuff
    }
}

在上面的代码中,当TestNG运行此测试类时,在此类中使用@Test注释的每个方法将具有初始化驱动程序的相应@BeforeMethod执行和关闭的@AfterMethod即使测试失败,驱动程序也是如此。关于使用TestNG进行此类设置的几点要点:

(1)TestNG不会创建测试类的单独实例,因此如果在类对象上保存状态,则无法在类中并行运行测试方法,因为您可能有多种方法尝试创建新的驱动程序和将它们保存到同一个变量中,破坏正在运行的其他测试的状态。 可以以每个类的并行模式运行(例如,有5个线程,每个线程同时运行一个单独的测试类)。

(2)为什么我将@BeforeMethod@AfterMethod主体包装在try-catch块中?因为TestNG在配置方法异常上快速失败并且可能导致其他尚未运行的测试被跳过,因此您需要处理任何可能失败的代码。通过包装创建和关闭Web驱动程序,您可以忽略该错误并继续运行其他测试。例如,如果无法创建驱动程序,driver变量将为null,@Test方法将失败,但其他方法可能会成功。理想情况下,您可能应该对异常进行一些记录,以便您可以调查为什么,例如,无法创建驱动程序。

此外,如果您需要在许多测试类中使用驱动程序,您可以创建一个基类来创建驱动程序,并在每个方法之后关闭它,并让您的测试类扩展它。如果你有一个带有@Test注释方法的类,它将在该测试类和所有超类上运行任何@BeforeMethod方法。保证在类之间对方法进行排序(但如果在同一个类中有多个@BeforeMethod方法则不行。)

public abstract class A {
    @BeforeMethod
    public void setupA() { }
}

public class B extends A {
    @BeforeMethod
    public void setupB() { }

    @Test
    public void foo() { }
}

在上文中,当foo运行时,它将先运行setupA,然后运行setupB。方法以相同的方式工作,但顺序相反。