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之依赖注入,就分享到这里。
Java自动化测试框架-09 - TestNG之依赖注入篇 (详细教程)的更多相关文章
- Java自动化测试框架-04 - TestNG之Test Method篇 - 道法自然,法力无边(详细教程)
简介 按照上一篇的计划,这一篇给小伙伴们分享一下测试方法. 一.设置参数 测试方法是可以带有参数的.每个测试方法都可以带有任意数量的参数,并且可以通过使用TestNG的@Parameters向方法传递 ...
- Java自动化测试框架-03 - TestNG之Test Group篇 - 我们一起组团打怪升级(详细教程)
简介 其实这篇文章的group宏哥在上一篇中就提到过,但是就是举例一笔带过的,因此今天专门有一篇文章来讲解Group的相关知识.希望大家茅塞顿开 ,有着更进一步认识和了解测试组. 一.Test Gro ...
- Java自动化测试框架-10 - TestNG之测试结果篇
1.-测试结果 1.1-成功,失败和断言 测试被认为是成功的,如果它不引发任何异常完成,还是它扔的预期异常(请参阅文档expectedExceptions属性上找到的@Test注释). 您的测试方法通 ...
- Java自动化测试框架-01 - TestNG之入门篇 - 大佬的鸡肋,菜鸟的盛宴(详细教程)
TestNG是什么? TestNG按照官方的定义: TestNG是一个测试框架,其灵感来自JUnit和NUnit,但引入了一些新的功能,使其功能更强大,使用更方便. TestNG是一个开源自动化测试框 ...
- Java自动化测试框架-08 - TestNG之并行性和超时篇 (详细教程)
一.并行性和超时 您可以指示TestNG以各种方式在单独的线程中运行测试. 可以通过在suite标签中使用 parallel 属性来让测试方法运行在不同的线程中.这个属性可以带有如下这样的值: 二.并 ...
- Java自动化测试框架-02 - TestNG之理论实践 - 纸上得来终觉浅,绝知此事要躬行(详细教程)
理论 TestNG,即Testing, NextGeneration,下一代测试技术,是一套根据JUnit 和NUnit思想而构建的利用注释来强化测试功能的一个测试框架,即可以用来做单元测试,也可以用 ...
- Java自动化测试框架-07 - TestNG之Factory篇 - 欢快畅游梦幻工厂(详细教程)
简介 最近忙着装修博客园,没时间更新文章,今天终于抽出时间把上次写的一半的文章给写完了,新的博客园风格,希望大家喜欢.今天继续介绍testng的相关知识--工厂. 工厂允许你动态的创建测试.例如,假设 ...
- Java自动化测试框架-11 - TestNG之annotation与并发测试篇 (详细教程)
1.简介 TestNG中用到的annotation的快速预览及其属性. 2.TestNG基本注解(注释) 注解 描述 @BeforeSuite 注解的方法只运行一次,在当前suite所有测试执行之前执 ...
- Java自动化测试框架-02 - TestNG之理论到实践
TestNG,即Testing, NextGeneration,下一代测试技术,是一套根据JUnit 和NUnit思想而构建的利用注释来强化测试功能的一个测试框架,即可以用来做单元测试,也可以用来做集 ...
随机推荐
- 解决mac OSX下安装git出现的"git命令需要使用开发者工具。您要现在安装该工具吗"(19款Mac)
1.本地安装Git ,这里不做说明 2.命令行执行 sudo mv /usr/bin/git /usr/bin/git-system 3.如果提示 权限不足,操作不被允许,关闭Rootless,重启按 ...
- 58同城AES签名接口分析
背景:需要获取58同城上面发布的职位信息,其中的包括职位的招聘要求,薪资福利,公司的信息,招聘者的联系方式.(中级爬虫的难度系数) 职位详情页分析 某个职位详情页的链接 https://qy.m.58 ...
- JVM(三)初始化
字节码指令和符号引用.直接引用 1.主动引用和被动引用 主动引用:虚拟机规定只有满足四个情况的的情况下,才会进行主动引用. 被动引用:除过四种情况的引用是被动引用. 只有主动引用才会初始 ...
- 可能是国内第一篇全面解读 Java 现状及趋势的文章
作者 | 张晓楠 Dragonwell JDK 最新版本 8.1.1-GA 发布,包括全新特性和更新! 导读:InfoQ 发布<2019 中国 Java 发展趋势报告>,反映 Java 在 ...
- 【JZOJ5263】分手是祝愿
Description 请注意本题的数据范围. Input Output Sample Input 2 2 15 19 3 30 40 20 Sample Output 285 2600 Hint 数 ...
- bugku color
下载打开压缩包是七张图片,分别是七个颜色,使用stegsolve打开发现了异常. 七张图片拼起来是 make me tall,看来是要修改图片高度. 我们使用winhex打开图片并在十六进制中修改图片 ...
- Java名词术语---持续更新
在看技术文档的过程中,经常会出现新的java缩写术语,很多时候都不知道它们是什么,在这里记下,持续更新. ——————————————————————————————————————————————— ...
- drf框架中分页组件
drf框架中分页组件 普通分页(最常用) 自定制分页类 pagination.py from rest_framework.pagination import PageNumberPagination ...
- 【C语言笔记】#define与typedef的区别
1.#define define是预处理指令,在编译时不进行任何检查,只进行简单的替换 宏定义的一般形式为: #define 宏名 字符串 这里所说的字符串是一般意义上的字符序列,不要和C语言中的字符 ...
- feof() 函数判断不准确的问题
大家在读文件时应该碰到过这样的问题,while(!feof(fp)) 函数在读文件时会多循环一次,导致 fscanf() 函数多读了一次文件. 所以也就在输出的时候会产生一些乱码. 可以看看下面的代码 ...