TestNG,Selenium 如何在多个类之间共享对象

Posted

技术标签:

【中文标题】TestNG,Selenium 如何在多个类之间共享对象【英文标题】:TestNG, Selenium How to share object among multiple Classes 【发布时间】:2015-10-10 11:57:05 【问题描述】:

我正在使用 Selenium + TestNG 执行我的测试用例。我的测试用例分布在多个类中。我想在每个班级都使用相同的 webDriver 副本。 (我不想每次都登录然后做其他操作,所以每个类都调用单独的浏览器的选项消失了)。 为了解决这个问题,现在我正在使用静态 webdriver 对象的继承。但是在并行模式下使用 selenium 网格时,它不起作用,因为它使用相同的对象。您能否告诉我一种方法,我可以与多个类共享对象或在每个“测试”上创建不同的静态实例(就像我为每个测试运行单独的 Java 程序)。

【问题讨论】:

不清楚。您是否想要一个浏览器实例?如果那么你想在网格中做什么?您使用网格在多个节点上运行多个实例 那你没有正确使用TestNg。只需使用 testng.xml 并行运行测试,无需共享同一个对象或继承类。 【参考方案1】:

目前,您在各种类/测试中使用 webdriver 对象的静态引用。因此,有一个驱动程序实例正在修改代码中的静态资源。但是当你选择网格时,你将为每个节点创建不同的驱动程序实例。这些驱动程序将并行运行,并将访问共享资源(静态变量等),同时更改和覆盖其他驱动程序实例所做的更改,这将导致问题。

编写代码时不要共享资源(最少使用静态资源)。尝试将您的驱动程序实例传递给方法,以确保所需的驱动程序只执行那段代码。

【讨论】:

感谢 Vishal 但这不是解决方案。我知道代码需要以不共享资源的方式编写(即没有静态变量)。我想要一种技术实现方式。我实现了通过一个类传递给另一个类的参数,但是这样我必须通过java代码传递对象,我不能只通过testng来做到这一点。如果您知道方法,请您分享。【参考方案2】:

这是我实施解决方案的方式。

我有一个对象 myObj,里面有 webDriver 对象和其他一些东西。我创建了静态对象 myObj 的静态数组。是这样的

// 类中实现了 WebDriver 的某些部分。 WebDriver 不是静态的。

private static MyClass[] ObjectArr = new MyClass[100];

public static MyClass getInstance(Integer id)
    id = (id==null)? 0 : id;
    if(ObjectArr[id] == null)
        ObjectArr[id] = new MyClass();
      
    return ObjectArr[id];

现在,当我想在我的 testng 类中使用它时,我会这样做。

public class x
MyClass i;

@BeforeClass
@Parameters("instanceId")
public void getInstance(@Optional String instanceId)
    i = MyClass.getInstance(Integer.parseInt(instanceId));


这是我的 testng.xml 的样子。

<test name="FireFox" preserve-order="true">
    <parameter name="instanceId" value="1" />
    <parameter name="browser" value="firefox" />
    <classes>
        <class name="com.app.Login"/>
    </classes>
</test> 

<test name="Chrome" preserve-order="true">
    <parameter name="instanceId" value="2" />
    <parameter name="browser" value="chrome" />
    <classes>
        <class name="com.app.Login"/>
    </classes>
</test> 

这对我来说非常适合并行和正常方式的硒网格。

【讨论】:

【参考方案3】:

我遇到了类似的问题。这就是我所做的。

假设:假设 B 类测试依赖于 A 类实例。

@AfterClass(alwaysRun = true)
public void insertValueIntoAttribute(ITestContext ctx) 
    ctx.setAttribute("INSTANCE_OF_A", this); // from inside class A tests

然后在 B 类中,我检索 A 的这个实例并使用它。

@BeforeClass(alwaysRun=true)
@SuppressWarnings("unchecked")
public void fetchData(ITestContext ctx) 
    A a = (A) ctx.getAttribute("INSTANCE_OF_A");

希望这对某人有所帮助。

【讨论】:

【参考方案4】:

我们在进行测试时遇到了类似的情况。我们还想利用 TestNG 并行化以及 Selenium Web 驱动程序。不幸的是,在启用任何 TestNG 并行模式时,在每个测试类中管理 Web 驱动程序生命周期或尝试使用包含 Web 驱动程序的静态类都无效。 IE。 parallel="tests|classes|methods"。将测试中的类和方法与活动的 TestNG 线程和实例化的 Web 驱动程序相匹配是很笨拙的。我们花更多的时间来确定 Web 驱动程序的生命周期,而不是进行真正的 Web 应用程序测试。我们找到了更好的方法。我们有一个开源项目,它抽象出用于 TestNG/Selenium 测试的 Web 驱动程序生命周期管理。它正确支持每个 TestNG 并行模式,为每个被测测试类方法提供正确和活动的 Web 驱动程序。它对我们的测试工作有很大帮助。也许它对您的情况也有用。或者,如果没有其他东西可以让您了解如何以不同的方式处理它。该项目在 GitHub 上以 Concurrent Selenium TestNG (COSENG) 结束。亲切的问候。

【讨论】:

以上是关于TestNG,Selenium 如何在多个类之间共享对象的主要内容,如果未能解决你的问题,请参考以下文章

TestNG 可以运行多个套件吗?

如何通过打开多个窗口一次使用 Selenium TestNG 执行负载测试

使用 selenium TestNG 和 selenium 进行并行测试

Selenium多个浏览器测试。只有最后一个浏览器接收cookie TestNG的

如何从 @AfterMethod 中的 TestNG/Selenium 获取测试结果状态?

使用selenium在java中使用testng进行并行测试