转自:https://www.cnblogs.com/du-hong/p/11818557.html
1.-依赖注入
TestNG支持两种不同类型的依赖项注入:本机(由TestNG本身执行)和外部(由诸如Guice的依赖项注入框架执行)。
1.1-本机依赖项注入
TestNG允许您在方法中声明其他参数。发生这种情况时,TestNG将自动用正确的值填充这些参数。依赖注入可以在以下地方使用:
任何@Before方法或@Test方法都可以声明ITestContext类型的参数。
任何@AfterMethod方法都可以声明ITestResult类型的参数,该参数将反映刚刚运行的测试方法的结果。
任何@Before和@After方法(@BeforeSuite和@AfterSuite除外)都可以声明XmlTest类型的参数,该参数包含当前的<test>标记。
任何@BeforeMethod(和@AfterMethod)都可以声明java.lang.reflect.Method类型的参数 。此参数将接收此@BeforeMethod完成之后(或在为@AfterMethod运行的方法之后)将调用的测试方法。
任何@BeforeMethod都可以声明Object []类型的参数。此参数将接收即将馈入即将到来的测试方法的参数列表,该参数列表可以由TestNG注入,例如java.lang.reflect.Method或来自@DataProvider。
任何@DataProvider都可以声明ITestContext或java.lang.reflect.Method类型的参数 。后一个参数将接收将要调用的测试方法。
您可以使用@NoInjection批注关闭注入:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
public class NoInjectionTest {
@DataProvider(name = "provider")
public Object[][] provide() throws Exception {
return new Object[][] { { CC.class.getMethod("f") } };
}
@Test(dataProvider = "provider")
public void withoutInjection(@NoInjection Method m) {
Assert.assertEquals(m.getName(), "f");
}
@Test(dataProvider = "provider")
public void withInjection(Method m) {
Assert.assertEquals(m.getName(), "withInjection");
}
}
下表总结了可以为各种TestNG注释本地注入的参数类型:
Annotation | ITestContext | XmlTest | Method | Object[] | ITestResult |
---|---|---|---|---|---|
BeforeSuite | Yes | No | No | No | No |
BeforeTest | Yes | Yes | No | No | No |
BeforeGroups | Yes | Yes | No | No | No |
BeforeClass | Yes | Yes | No | No | No |
BeforeMethod | Yes | Yes | Yes | Yes | Yes |
Test | Yes | No | No | No | No |
DataProvider | Yes | No | Yes | No | No |
AfterMethod | Yes | Yes | Yes | Yes | Yes |
AfterClass | Yes | Yes | No | No | No |
AfterGroups | Yes | Yes | No | No | No |
AfterTest | Yes | Yes | No | No | No |
AfterSuite | Yes | No | No | No | No |
1.2-Guice依赖注入
如果您使用Guice,TestNG为您提供了一种简单的方法,即可通过Guice模块注入测试对象:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
@Guice(modules = GuiceExampleModule.class)
public class GuiceTest extends SimpleBaseTest {
@Inject
ISingleton m_singleton;
@Test
public void singletonShouldWork() {
m_singleton.doSomething();
}
}
在此示例中,预计GuiceExampleModule会将接口ISingleton绑定到一些具体的类:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
public class GuiceExampleModule implements Module {
@Override
public void configure(Binder binder) {
binder.bind(ISingleton.class).to(ExampleSingleton.class).in(Singleton.class);
}
}
如果需要更大的灵活性来指定应使用哪些模块实例化测试类,则可以指定模块工厂:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
@Guice(moduleFactory = ModuleFactory.class)
public class GuiceModuleFactoryTest {
@Inject
ISingleton m_singleton;
@Test
public void singletonShouldWork() {
m_singleton.doSomething();
}
}
模块工厂需要实现接口IModuleFactory:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
public interface IModuleFactory {
/**
* @param context The current test context
* @param testClass The test class
*
* @return The Guice module that should be used to get an instance of this
* test class.
*/
Module createModule(ITestContext context, Class<?> testClass);
}
您的工厂将被传递TestNG需要实例化的测试上下文和测试类的实例。您的createModule方法应返回一个Guice模块,它将知道如何实例化此测试类。您可以使用测试上下文来查找有关您的环境的更多信息,例如在testng.xml中指定的参数等。通过父模块和guice-stage套件参数,您将获得更大的灵活性和Guice功能。 guice-stage可让您选择用于创建父注射器的Stage。默认值是DEVELOPMENT。其他允许的值为PRODUCTION和TOOL。这是在test.xml文件中定义父模块的方法:
<suite parent-module="com.example.SuiteParenModule" guice-stage="PRODUCTION">
</suite>
对于给定的套件,TestNG将只创建一次此模块。还将使用该模块获取特定于测试的Guice模块和模块工厂的实例,然后将为每个测试类创建子注入器。通过这种方法,您可以在父模块中声明所有公共绑定,也可以在模块和模块工厂中注入在父模块中声明的绑定。这是此功能的示例:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
package com.example;
public class ParentModule extends AbstractModule {
@Override
protected void conigure() {
bind(MyService.class).toProvider(MyServiceProvider.class);
bind(MyContext.class).to(MyContextImpl.class).in(Singleton.class);
}
}
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
package com.example;
public class TestModule extends AbstractModule {
private final MyContext myContext;
@Inject
TestModule(MyContext myContext) {
this.myContext = myContext
}
@Override
protected void configure() {
bind(MySession.class).toInstance(myContext.getSession());
}
}
<suite parent-module="com.example.ParentModule">
</suite>
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
package com.example;
@Test
@Guice(modules = TestModule.class)
public class TestClass {
@Inject
MyService myService;
@Inject
MySession mySession;
public void testServiceWithSession() {
myService.serve(mySession);
}
}
如您所见,ParentModule为MyService和MyContext类声明了绑定。然后使用构造函数注入将MyContext注入到TestModule类中,该类也声明对MySession的绑定。然后将测试XML文件中的parent-module设置为ParentModule类,这将启用在TestModule中的注入。稍后在TestClass中,您会看到两次注入:* MyService-绑定取自ParentModule * MySession-绑定取自TestModule此配置可确保您使用同一会话实例运行该套件中的所有测试,MyContextImpl对象每个套件仅创建一次,这使您可以为套件中的所有测试配置通用环境状态。
2.-侦听方法调用
每当TestNG即将调用测试(用@Test注释)或配置(用@Before或@After注释中的任何一个注释)方法时 ,侦听器IInvokedMethodListener都会通知您。您需要实现以下接口:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
public interface IInvokedMethodListener extends ITestNGListener {
void beforeInvocation(IInvokedMethod method, ITestResult testResult);
void afterInvocation(IInvokedMethod method, ITestResult testResult);
}
并将其声明为侦听器,如有关TestNG侦听器的部分所述。
3.-覆盖测试方法
TestNG允许您重写并可能跳过测试方法的调用。一个有用的例子是,如果您需要使用特定的安全管理器来测试方法。您可以通过提供实现IHookable的侦听器来实现此目的。
这是JAAS的示例:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
public class MyHook implements IHookable {
public void run(final IHookCallBack icb, ITestResult testResult) {
// Preferably initialized in a @Configuration method
mySubject = authenticateWithJAAs();
Subject.doAs(mySubject, new PrivilegedExceptionAction() {
public Object run() {
icb.callback(testResult);
}
};
}
}
4.-变更套件(或)测试
有时,您可能只需要在运行时更改套件xml中的套件(或)测试标签,而不必更改套件文件的内容。
一个典型的例子就是尝试利用现有的套件文件,并尝试使用它在“被测应用程序”上模拟负载测试。至少您最终将多次复制<test>标记的内容,并创建一个新的套件xml文件并使用。但这似乎并没有太大的规模。
TestNG允许您在运行时通过侦听器更改套件xml文件中的套件(或)测试标签。您可以通过提供实现IAlterSuiteListener的侦听器来实现此目的。请参考“ 监听器”部分以了解监听器。
这是一个示例,显示套件名称在运行时如何更改:
/**
* @author 北京-宏哥
*
* Java自动化测试框架-09 - TestNG之 依赖注入篇
*
* 2019年11月8日
*/
public class AlterSuiteNameListener implements IAlterSuiteListener {
@Override
public void alter(List<XmlSuite> suites) {
XmlSuite suite = suites.get(0);
suite.setName(getClass().getSimpleName());
}
}
只能通过以下两种方式之一添加此侦听器:
通过套件xml文件中的<listeners>标记。
通过服务加载程序
不能使用@Listeners批注将此侦听器添加到执行中。
5.-小结
好了,今天关于TestNG之依赖注入,就分享到这里。
来源:oschina
链接:https://my.oschina.net/u/4370305/blog/4271850