【问题标题】:How to run @BeforeClass multiple times如何多次运行@BeforeClass
【发布时间】:2017-12-07 19:44:58
【问题描述】:

我有一个基本测试类,我在其中编写了使用单例模式实例化浏览器的代码

public class BaseTest {
    public static  WebDriver driver;
    @BeforeClass(alwaysRun=true,groups={"dependx"})
    public static  WebDriver setBrowser()// double checked login using synchronized keyword will increase the time by 100
    {
        if(driver==null){
            synchronized(BaseTest.class){
                System.setProperty("webdriver.chrome.driver","/home/user/Downloads/driver/chromedriver");
                 driver = new ChromeDriver();   
            }
        }
        return driver;
    }
}

现在我的代码运行成功,直到我使用退出或关闭方法关闭浏览器 现在我第二次重新执行相同的代码,它给了我

nosuchSession 异常

这是我的测试类

public class SimpleBase1 {
    public SimpleBase1() {
        PageFactory.initElements(driver, this);
    }

    SimpleBase2 obj;
    FullLafdefy obj2;
    public WebDriver driver = BaseTest.setBrowser();

    @FindBy(xpath ="//a[@id ='yourRooms']/span[contains(text(),'Rooms: ')]")
    WebElement cartButton;
    @FindBy(xpath ="//a[@id='aLamps']")
    WebElement Lamps;

    @BeforeClass
    public void before(){
        obj = new SimpleBase2(driver);
        obj2 = new FullLafdefy(driver);
    }
    @Test(priority=1)
    public void navigateToSite(){
        System.out.println("Here it is  "+Constants.url.value);
        FullLafdefy.navigateToUrl(driver, Constants.returnUrl());
        System.out.println("pretty Please ");
    }

    @AfterClass
    public void tearDown(){
        driver.close();
        driver=null;
    }
}

到目前为止一切正常,我想确保驱动程序值应该等于 null,所以我插入了一行额外的行“driver=null;”在此之后

现在在我的第二个测试班

public class SignPageTest {
    public WebDriver driver = BaseTest.setBrowser();
    SignPage obj ;
    Boolean stu;


    @Test
    public void navigateToSignPage(){
    obj = new SignPage(driver);
    stu = obj.navigateToSignIn();
    }
    @Test(priority=2)
    public void getHandles(){
        stu = obj.handlingWindows();
    }

}

这是我的 testNG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
    <test name="Test1">
    <classes>
          <class name="TestPackageClasses.BaseTest"/>
          <class name="trialPackage.SimpleBase1"/>  
    </classes>
    </test>
    <test name="Test2">
    <classes>
         <class name="TestPackageClasses.BaseTest"/>
         <class name="TestPackageClasses.SignPageTest"/> 
    </classes>
    </test>
</suite>

有人可以告诉我如何重新执行@BeforeClass 的代码,或者可能多次执行@BeforeTest

【问题讨论】:

  • 我可以使用 appium 执行相同类型的框架
  • 有什么理由将测试放在页面对象 (SimpleBase1) 中?
  • 这完全是另一个想法,我想将我的 webElements 作为参数发送给我的页面类中的另一个方法,我只想重新使用它但是我得到空指针作为webElement 为 null 你能告诉我你在关闭或退出浏览器后如何重新实例化浏览器吗
  • 您将 SimpleBase1 类的实例变量驱动程序设置为空,而不是 BaseTest 类的静态类变量驱动程序。请改用此 BaseTest.driver = null 。混合页面对象和测试绝不是一个好主意。还要查看访问修饰符,一切都是公共的或包的。 singelton的目的是什么? setBrowser() 方法有一个 BeforeClass 注释,除非该类中有测试,否则它永远不会被 testNg 触发。无论如何,您都在明确地调用它。

标签: java selenium automated-tests testng


【解决方案1】:

我发现您的代码存在很多问题。这里有几个:

  1. 如果您决定开始并行运行测试,那么您的单例方法将导致灾难。我建议将其更改为 Factory 方法,该方法在调用时会生成 webdriver 实例。因此,您的测试可以直接调用工厂方法并使用 webdriver。
  2. 您的单例使用@BeforeClass 进行注释,但在您的代码中没有任何地方使用@BeforeClass 注释功能,因为您的测试类都没有扩展BaseTest。所以在这个类中你可以很好的去掉这个注解。
  3. 您的套件 xml 明确引用 BaseTest。这会导致@BeforeClass 运行。但是第二个&lt;test name="Test2"&gt; 搞砸了,因为您的测试类TestPackageClasses.SignPageTest 基本上是通过类级数据成员查询BaseTest.setBrowser()。这意味着,一旦 TestNG 为SignPageTest 创建了一个实例,对setBrowser() 的调用就会发生。 TestNG 很早之前就实例化了测试类,然后才调用@BeforeClass

所以这里有一些对您的代码的快速修复。

  1. 让所有测试类扩展BaseTest。这样他们就不需要做任何额外的事情来获取 webdriver 对象,因为它很容易从基类中获得。 webdriver 逻辑的实例化仍然可以是您的@BeforeClass 方法的一部分。但请记住,这样做会严重限制您并行运行测试的能力。如果您想在方法级别执行此操作并准备好并行处理,则需要使用 @BeforeMethod + ThreadLocal(或)使用 TestNG 侦听器。您可以在我的博客文章here 中阅读更多相关信息
  2. BaseTest 类中删除所有同步逻辑和单例方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-26
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多