Reputation: 1217
I have a testng suite of test classes that I am running via a testng.xml file. 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 (e.g., 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 (e.g., look up the just-inserted customer using the customerId
value from the first class).
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.
Upvotes: 6
Views: 6852
Reputation: 782
ITestContext will work fine if both the test cases are in same test scope. If we have to share data between tests in different test context but same suite then we have to set the data in suite context.
public class SharingDataSuiteLevelISuiteFirstTest {
// Passing ITestContext as a parameter to @Test method to use it.
@Test
public void generateData(ITestContext context)
{
String firstName = "Amod";
// Get the suite
ISuite suite = context.getSuite();
// Setting an attribute with name and its value at suite level in stead of test level
suite.setAttribute("FirstName", firstName);
}
}
public class SharingDataSuiteLevelISuiteSecondTest {
// Passing ITestContext as a parameter to @Test method to use it.
@Test
public void useData(ITestContext context)
{
String lastName = "Mahajan";
// Retrieving attribute value set in ITestContext
ISuite suite = context.getSuite();
String FN = (String) suite.getAttribute("FirstName");
String fullName = FN +" "+lastName;
System.out.println("Full Name is : "+fullName);
}
}
More explanation to the above problem can be found here: http://makeseleniumeasy.com/2020/01/06/testng-tutorials-68-sharing-data-between-tests-in-a-suite-using-isuite-itestcontext/
Upvotes: 0
Reputation: 556
As we know from TestNG JavaDoc, ITestContext defines a test context which contains all the information for a given test run. 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
public List<String> groupIds = ...;
@AfterClass(alwaysRun = true)
public void reserveGroupIds(ITestContext ctx) {
ctx.setAttribute(GROUPS_ATTR, groupIds);
}
Consumer.java
public List<String> groupIds;
@BeforeClass(alwaysRun = true)
public void fetchGroupIds(ITestContext ctx) {
groupIds = (List<String>) ctx.getAttribute(Producer.GROUPS_ATTR);
}
mySuite.xml
...
<test>
<classes>
<class name= "Producer"/>
<class name= "Consumer"/>
</classes>
</test>
...
Upvotes: 0
Reputation: 2428
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.)
RegistrationTests.java
(extends TestBase, )ShoppingTests.java
(extends TestBase)WhateverElseTests.java
(extends TestBase)So TestBase
has all shared data as static fields e.g. Customer
object:
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, e.g. ShoppingTests.java
:
public class ShoppingTests extends TestBase {
@Test
public void doSomethingTest() {
bw.navigateTo().shoppingPage();
bw.shoppingPreparationHelper().checkDisplayedName(customer.name);
...
N.B.: 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")
. Otherwise you are in risk of NullPointerException for customer
.
P.S.: 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.
Upvotes: 1
Reputation: 325
Really Testng-y way to do this is to set ITestContext attribute with desired value and then get it from other test class.
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");
}
Upvotes: 4
Reputation: 8227
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");
Upvotes: 1