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


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM