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

原文地址:https://www.cnblogs.com/du-hong/p/11818557.html

时间: 2024-10-09 09:10:04

Java自动化测试框架-09 - TestNG之依赖注入篇 (详细教程)的相关文章

Java自动化测试框架-03 - TestNG之Test Group篇 - 我们一起组团打怪升级(详细教程)

简介 其实这篇文章的group宏哥在上一篇中就提到过,但是就是举例一笔带过的,因此今天专门有一篇文章来讲解Group的相关知识.希望大家茅塞顿开 ,有着更进一步认识和了解测试组. 一.Test Group(测试组) TestNG 允许你将复杂的测试方法归类为不同的组.不仅仅是可以声明某个方法属于某个组,而且还可以让组包含其他的组.这样TestNG可以调用或者请求包含一组特定的组 (或者正则表达式)而排除其他不需要组的集合.这样,如果你打算将测试分成两份的时候,就无需重新编译.这个特点,会给你在划

Spring框架整合Struts2使用Validation框架验证表单用户输入数据的详细教程

原创整理不易,转载请注明出处:Spring框架整合Struts2使用Validation框架验证表单用户输入数据的详细教程 代码下载地址:http://www.zuidaima.com/share/1778685765291008.htm 在<Struts2教程4:使用validate方法验证数据>中曾讲到使用validate方法来验证客户端提交的数据,但如果使用validate方法就会将验证代码和正常的逻辑代码混在一起,但这样做并不利于代码维护,而且也很难将过些代码用于其他程序的验证.在St

【Java】使用@Reource或@Autowire依赖注入时出现NPE的排查方法

首先想说明的是,@Resource和@Autowire虽然都是用于依赖注入的Annotation,但是二者是有区别的. 1 Resource不依赖于Spring,后者相反,因此为了减少以来,尽量使用Resource: 2 Resource是优先按照变量名称匹配的,也可用@Resource(name="")指定要注入的变量名.Autowire则是优先按类型匹配,配合@Qualifier也可指定变量名. 3 不存在灵异事件!不存在灵异事件!不存在灵异事件!重要的事说三遍.如果出现了Null

Java Spring学习笔记----Bean的依赖注入(1)

Spring常用的两种依赖注入方式:一种是设值注入方式,利用Bean的setter方法设置Bean的属性值:另一种是构造注入,通过给Bean的构造方法传递参数来实现Bean的属性赋值: 1.设值注入方式 直接上代码例子,示例的树结构图如下 Shape.java接口内容 package chapter3; public interface Shape { public double area();//求形状的面积 } Circle.java内容: package chapter3; public

Dora.Interception,为.NET Core度身打造的AOP框架 [4]:与依赖注入框架的无缝集成

Dora.Interception最初的定位就是专门针对.NET Core的AOP框架,所以在整个迭代过程中我大部分是在做减法.对于.NET Core程序开发来说,依赖注入已经成为无处不在并且“深入骨髓”的东西,不论是在进行业务应用的开发,还是进行基础组件的开发,依赖注入是实现“松耦合”最为理想的方式(没有之一).对于绝大部分AOP框架来说,它们最终都会体现为创建一个能够拦截的“代理对象”来实现对方法调用的拦截,但是.NET Core中针对服务实例的提供完全由通过IServiceProvider

框架学习 Spring之依赖注入DI

依赖注入的方式有四种: 1.Setter注入(属性注入) 2.构造器注入 3.P命名空间注入 4.集合类型值注入 1.Setter注入(属性注入) Employee 员工实体类 package com.spring.pojo; public class Employee { private Integer id; private String name; private Department department; public Integer getId() { return id; } pu

Spring框架(2)--依赖注入

在开发中我们大多数使用的MVC的架构,Spring框架直接引用的是service层而不是dao层,使用依赖注入就可以通过service层来调用dao层. Bean的依赖注入入门: Bean的依赖注入概念: 依赖注入(Dependency Injection):它是Spring框架核心IOC的具体实现.在编写程序时,通过控制反转,把对象的创建交给了Spring,但是代码中不可能出现没有依赖的情况. IOC 解耦只是降低他们的依赖关系,但不会消除.例如:业务层仍会调用持久层的方法. 那这种业务层和持

Spring框架使用(控制反转,依赖注入,面向切面AOP)

参见:http://blog.csdn.net/fei641327936/article/details/52015121 Mybatis: 实现IOC的轻量级的一个Bean的容器 Inversion of control 控制反转:由容器控制程序之间的关系,不是程序代码操作 Depend Inject 依赖注入 Aspect oriented programming 面向切面编程 Spring能帮助我们根据配置文件创建及组装对象之间的依赖关系: Spring面向切面编程能帮助我们无耦合的实现日

关于PHP中依赖注入的详细介绍

依赖注入原理: 依赖注入是一种允许我们从硬编码的依赖中解耦出来,从而在运行时或者编译时能够修改的软件设计模式.简而言之就是可以让我们在类的方法中更加方便的调用与之关联的类. 实例讲解: 假设有一个这样的类: 1 2 3 4 5 6 7 class Test {  public function index(Demo $demo,Apple $apple){   $demo->show();   $apple->fun();  } } 如果想使用index方法我们需要这样做: 1 2 3 4 $