TestNG - pytest 风格的测试夹具

TestNG - Test fixture in the style of pytest

使用 TestNG 编写 Appium 测试。我想将 AppiumDriver 作为参数传递给我的测试方法,这样我就不必记住在每次测试中都获取它。例如:

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...
    }
}

好吧,如果您排除所有可用的选项,您将无能为力...

我认为最好的选择是使用 ThreadLocal 方法。如果您对 ThreadLocal 的唯一担心是您需要一直调用 get(),只需将此调用包装在小函数中:

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...
}

如果你可以使用 Junit 5.0 那么你可以使用@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.
}

假设如果您的某些测试不需要此驱动程序,您仍然可以使用正常的 @Test 方法而不是使用 @ParameterizedTest。 此外,如果您的测试需要,您可以在 getDriver 中包含尽可能多的参数。