Java自動化測試框架-09 - TestNG之依賴注入篇 (詳細教程)

1.-依賴注入

TestNG支持兩種不一樣類型的依賴項注入:本機(由TestNG自己執行)和外部(由諸如Guice的依賴項注入框架執行)。java

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註釋本地注入的參數類型: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

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);
  }
 
}

若是須要更大的靈活性來指定應使用哪些模塊實例化測試類,則能夠指定模塊工廠: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對象每一個套件僅建立一次,這使您能夠爲套件中的全部測試配置通用環境狀態。

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之依賴注入,就分享到這裏。

相關文章
相關標籤/搜索