简体   繁体   English

TestNG - 测试类之间的共享状态

[英]TestNG - sharing state between test classes

I have a suite of test classes that I am running via a testng.xml file. 我有一个测试类套件,我通过testng.xml文件运行。 This works fine. 这很好用。 All tests are run serially, so no parallel-execution hurdles. 所有测试都是连续运行的,因此没有并行执行障碍。

My goal now is to take state that was generated by the test methods in one test class (eg, a customerId primary key value generated by a database insert) and pass it along to another test class, so that the test methods in that second class can take further action based on that shared state (eg, look up the just-inserted customer using the customerId value from the first class). 我现在的目标是在一个测试类中获取由测试方法生成的状态(例如,由数据库插入生成的customerId主键值)并将其传递给另一个测试类,以便第二个类中的测试方法可以基于该共享状态采取进一步的操作(例如,使用来自第一类的customerId值查找刚刚插入的客户)。

It's easy to share state between test methods in a single class, of course, via class member variables, but I don't see how to share it across test classes. 当然,通过类成员变量在单个类中的测试方法之间共享状态很容易,但是我没有看到如何跨测试类共享它。

Really Testng-y way to do this is to set ITestContext attribute with desired value and then get it from other test class. 真正以这种方式执行此操作的方法是将ITestContext属性设置为所需的值,然后从其他测试类中获取它。

Set value: 设定值:

@Test
public void setvaluetest(ITestContext context) {
        String customerId = "GDFg34fDF";
        context.setAttribute("customerId", customerId);
}

Get value: 获得价值:

@Test
public void getvaluetest(ITestContext context) {
        String id = context.getAttribute("customerId");
}

Use a factory to create a repository. 使用工厂创建存储库。 The repository stores "interesting test state" properties. 存储库存储“有趣的测试状态”属性。

  TestRepository tr = TestRepositoryFactory.getInstance();
  ...
  tr.store("test13.PKID", pkid.toString());

and then in your subsequent code, repeat the call to the factory and then get the value: 然后在随后的代码中,重复调用工厂,然后获取值:

  String spkid = tr.get("test13.PKID");

Another way is to use means of object oriented programming. 另一种方法是使用面向对象编程的手段。

Common structure of tests for example: 常见的测试结构例如:

  • TestBase.java (parent class for all other test classes, has methods like @BeforeTest, @AfterSuite, etc.) TestBase.java (所有其他测试类的父类,有@BeforeTest,@ AfterSuite等方法)
    • RegistrationTests.java (extends TestBase, ) RegistrationTests.java (扩展TestBase,)
    • ShoppingTests.java (extends TestBase) ShoppingTests.java (扩展TestBase)
    • and WhateverElseTests.java (extends TestBase) WhateverElseTests.java (扩展TestBase)

So TestBase has all shared data as static fields eg Customer object: 所以TestBase将所有共享数据作为静态字段,例如Customer对象:

public class TestBase {

    protected static final BrowserManager bw = new BrowserManager();
    protected static Customer customer;

    @BeforeSuite
    public void initBrowser() {
        bw.init();
    }

    @AfterSuite
    public void terminateBrowser() {
        bw.terminate();
    }

}

And access to customer in tests, eg ShoppingTests.java : 并在测试中访问customer ,例如ShoppingTests.java

public class ShoppingTests extends TestBase {

    @Test
    public void doSomethingTest() {

        bw.navigateTo().shoppingPage();

        bw.shoppingPreparationHelper().checkDisplayedName(customer.name);
        ...

NB: tests that share objects should go in a strict sequence (first - test that init object, then - test that uses object's data), so use @Test(dependsOnMethods = "someMethodTest") . 注意:共享对象的测试应该按照严格的顺序进行(首先 - 测试init对象,然后测试使用对象的数据),所以使用@Test(dependsOnMethods = "someMethodTest") Otherwise you are in risk of NullPointerException for customer . 否则,您将面临customer NullPointerException的风险。

PS: Object-oriented way has great advantage over ITestContext because you can pass any object(s) from test to test (also between classes), not just string attribute. PS:面向对象的方式比ITestContext有很大的优势,因为你可以将任何对象从测试传递到测试(也在类之间),而不仅仅是字符串属性。

As we know from TestNG JavaDoc, ITestContext defines a test context which contains all the information for a given test run. 正如我们从TestNG JavaDoc所知,ITestContext定义了一个测试上下文,其中包含给定测试运行的所有信息。 An instance of this context is passed to the test listeners so they can query information about their environment. 此上下文的实例将传递给测试侦听器,以便它们可以查询有关其环境的信息。 So we can share generated data from one class in this test with another class in this test. 因此,我们可以在此测试中将一个类的生成数据与此测试中的另一个类共享。

Producer.java Producer.java

public List<String> groupIds = ...;
@AfterClass(alwaysRun = true)
public void reserveGroupIds(ITestContext ctx) {
    ctx.setAttribute(GROUPS_ATTR, groupIds);
}

Consumer.java Consumer.java

public List<String> groupIds;
@BeforeClass(alwaysRun = true)
public void fetchGroupIds(ITestContext ctx) {
    groupIds = (List<String>) ctx.getAttribute(Producer.GROUPS_ATTR);
}

mySuite.xml mySuite.xml

...
<test>
  <classes>
    <class name= "Producer"/>
    <class name= "Consumer"/>
  </classes>
</test>
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM