'TestNG - Test fixture in the style of pytest
Writing Appium tests with TestNG. I'd like to pass the AppiumDriver
to my test methods as an argument, so I don't have to remember to get it in every test. For example:
class FooTest {
@BeforeTest
public void initDriver(){
AppiumDriver driver = ...
// do some black magic to add the driver as an argument for all tests in this class
}
@Test
public void testLogin(AppiumDriver driver){
// example
driver.findElementByAccessibilityId("username").sendKeys("foo");
driver.findElementByAccessibilityId("password").sendKeys("bar");
// etc...
}
}
- I can't use a TestNG parameter because they can only be strings.
- I don't want to use a
DataProvider
for this because I want to use them for other stuff - I don't want to put it in the
ITestContext
, because then I have to remember to get it. (This is what I'm currently doing) - I can't put it as a class property, because I plan to do
parallel="methods"
- I don't want to put it in a class property as a ThreadLocal, because then I have to do
.get()
constantly. - I would prefer to not have to specify it in the @Test decorator for every single test.
Solution 1:[1]
Well if you rule out all available options, there is not much you can do...
I think the best option would be to use the ThreadLocal
approach. If the only concern you have with ThreadLocal
is that you need to call get()
all the time, simply wrap this call in small function:
private final ThreadLocal<AppiumDriver> driver = new ThreadLocal<>();
@BeforeTest
void initDriver() {
final AppiumDriver driver = ...;
...
return this.driver.set(driver);
}
private AppiumDriver driver() {
this.driver.get();
}
@Test
public void testLogin() {
// example
driver().findElementByAccessibilityId("username").sendKeys("foo");
driver().findElementByAccessibilityId("password").sendKeys("bar");
// etc...
}
Solution 2:[2]
If you can use Junit 5.0 then you can use @Parameterizedtest with @MethodSource.
private static AppiumDriver driver() {
//get driver.
}
private static Stream<Arguments> getDriver(){
return Stream.of(Arguments.of(driver())); // return driver obtained from `driver()` method.
}
// use driver from `getDriver()`.
@ParameterizedTest
@MethodSource({"getDriver"})
void testLogin(AppiumDriver driver){
// use driver for your tests.
}
Suppose if some of your tests don't need this driver, you can still use normal @Test
methods instead of using @ParameterizedTest
.
Also, you can have as many arguments in getDriver
if your tests required so.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | dpr |
Solution 2 | Ashish Patil |