TestNG支持兩種不一樣類型的依賴項注入:本機(由TestNG自己執行)和外部(由諸如Guice的依賴項注入框架執行)。java
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註釋本地注入的參數類型:ide
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 |
若是您使用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); } }
若是須要更大的靈活性來指定應使用哪些模塊實例化測試類,則能夠指定模塊工廠:ui
/** * @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:this
/** * @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文件中定義父模塊的方法:spa
<suite parent-module="com.example.SuiteParenModule" guice-stage="PRODUCTION"> </suite>
對於給定的套件,TestNG將只建立一次此模塊。還將使用該模塊獲取特定於測試的Guice模塊和模塊工廠的實例,而後將爲每一個測試類建立子注入器。經過這種方法,您能夠在父模塊中聲明全部公共綁定,也能夠在模塊和模塊工廠中注入在父模塊中聲明的綁定。這是此功能的示例:code
/** * @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對象每一個套件僅建立一次,這使您能夠爲套件中的全部測試配置通用環境狀態。
每當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偵聽器的部分所述。
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); } }; } }
有時,您可能只須要在運行時更改套件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批註將此偵聽器添加到執行中。
好了,今天關於TestNG之依賴注入,就分享到這裏。