如何在 TestNG 测试用例中使用 Governator 注入依赖项?
How to inject dependecies using Governator within TestNG test cases?
我正在开发一个使用 TestNG 的测试自动化框架。我决定使用 Dependency Injection 模式来实现更具可读性、可重用的页面对象和测试。
我选择了 Google Guice 因为 TestNG 提供了内置支持以使用 [= 注入测试对象31=]指导模块。我只需要指定我的 Guice 模块 ,您可以在下一个代码片段中看到:
@Guice(modules = CommModule.class)
public class CommunicationTest {
@Inject
private Communication comms;
@Test
public void testSendMessage() {
Assertions.assertThat(comms.sendMessage("Hello World!")).isTrue();
}
}
到目前为止一切顺利,尽管我需要更多高级 DI 功能,例如:
- 生命周期管理
- 配置到字段映射
- 通用绑定注释
因此,我想使用 Netflix/Governator,因为它增强了 Google Guice 的这些功能。为了触发 Governator 功能,我必须通过它创建 Injector
而不是 TestNG。例如:
Injector injector = LifecycleInjector.builder()
.withModules(CommModules.class).build().createInjector();
而且我想尽可能做到透明,就像 TestNG 那样。
我想知道是否:
- 是否可以将我自己的
Injector
实例提供给 TestNG 以便重用 @Guice
注释方法?
- 您知道将 Governator 与 TestNG 集成的库吗?
您可以在 here 中找到我目前所做的工作。
直到现在这是不可能的。我已经在最新的 TestNG 快照版本中修复了这个问题。它应该在即将推出的 TestNG 版本中可用(任何大于 7.0.0
的版本)
我为跟踪此问题而创建的问题:https://github.com/cbeust/testng/issues/2199
简而言之,您可以执行以下操作:
- 实现接口
org.testng.IInjectorFactory
- 通过命令行参数插入新创建的实现的完全限定 class 名称
-dependencyinjectorfactory
因为 Allow user to provide DI Injector TestNG 功能将出现在高于 7.0.0
的版本中。我使用 TestNG 版本 7.0.0
listeners.
实现了一个解决方案
首先,我创建了一个名为 autopilot-testng-runner 的模块,具有以下依赖项:
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.governator</groupId>
<artifactId>governator</artifactId>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
</dependencies>
此模块包含接下来描述的工件:
@AutopilotTest:用于声明哪些 Guice 模块必须用于创建 Injector
和 LifecycleInjector.builder()
的自定义注释.我无法重用 @Guice
注释,因为 TestNG 还将创建其注入器,并且声明的依赖项将被创建两次。
AutopilotSuiteListener:实现 ISuiteListener
以创建父 Injector
、Governator 的 LifecycleManager
实例并在套件启动前绑定配置属性。因此,每个 Suite 都将有一个由 Governator 构建的父 Injector
和一个生命周期管理器。
AutopilotTestListener: ITestListener
实现负责在 运行 测试用例中注入依赖项。
META-INF/services/org.testng.ITestNGListener:服务提供商配置文件包含两个 ITestNGListener
实现的完全限定名称。
然后,我在 project
中添加了 autopilot-testng-runner
作为 Maven 依赖项
<dependency>
<groupId>com.github.eljaiek.playground</groupId>
<artifactId>autopilot-testng-runner</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
最后,我用 @AutopilotTest
替换了 @Guice
注释
@AutopilotTest(modules = CommModule.class)
public class CommunicationTest {
@Inject
private Communication comms;
@Test
public void testSendMessage() {
Assertions.assertThat(comms.sendMessage("Hello World!")).isTrue();
}
}
我正在开发一个使用 TestNG 的测试自动化框架。我决定使用 Dependency Injection 模式来实现更具可读性、可重用的页面对象和测试。
我选择了 Google Guice 因为 TestNG 提供了内置支持以使用 [= 注入测试对象31=]指导模块。我只需要指定我的 Guice 模块 ,您可以在下一个代码片段中看到:
@Guice(modules = CommModule.class)
public class CommunicationTest {
@Inject
private Communication comms;
@Test
public void testSendMessage() {
Assertions.assertThat(comms.sendMessage("Hello World!")).isTrue();
}
}
到目前为止一切顺利,尽管我需要更多高级 DI 功能,例如:
- 生命周期管理
- 配置到字段映射
- 通用绑定注释
因此,我想使用 Netflix/Governator,因为它增强了 Google Guice 的这些功能。为了触发 Governator 功能,我必须通过它创建 Injector
而不是 TestNG。例如:
Injector injector = LifecycleInjector.builder()
.withModules(CommModules.class).build().createInjector();
而且我想尽可能做到透明,就像 TestNG 那样。
我想知道是否:
- 是否可以将我自己的
Injector
实例提供给 TestNG 以便重用@Guice
注释方法? - 您知道将 Governator 与 TestNG 集成的库吗?
您可以在 here 中找到我目前所做的工作。
直到现在这是不可能的。我已经在最新的 TestNG 快照版本中修复了这个问题。它应该在即将推出的 TestNG 版本中可用(任何大于 7.0.0
的版本)
我为跟踪此问题而创建的问题:https://github.com/cbeust/testng/issues/2199
简而言之,您可以执行以下操作:
- 实现接口
org.testng.IInjectorFactory
- 通过命令行参数插入新创建的实现的完全限定 class 名称
-dependencyinjectorfactory
因为 Allow user to provide DI Injector TestNG 功能将出现在高于 7.0.0
的版本中。我使用 TestNG 版本 7.0.0
listeners.
首先,我创建了一个名为 autopilot-testng-runner 的模块,具有以下依赖项:
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.governator</groupId>
<artifactId>governator</artifactId>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</dependency>
</dependencies>
此模块包含接下来描述的工件:
@AutopilotTest:用于声明哪些 Guice 模块必须用于创建
Injector
和LifecycleInjector.builder()
的自定义注释.我无法重用@Guice
注释,因为 TestNG 还将创建其注入器,并且声明的依赖项将被创建两次。AutopilotSuiteListener:实现
ISuiteListener
以创建父Injector
、Governator 的LifecycleManager
实例并在套件启动前绑定配置属性。因此,每个 Suite 都将有一个由 Governator 构建的父Injector
和一个生命周期管理器。AutopilotTestListener:
ITestListener
实现负责在 运行 测试用例中注入依赖项。META-INF/services/org.testng.ITestNGListener:服务提供商配置文件包含两个
ITestNGListener
实现的完全限定名称。
然后,我在 project
中添加了autopilot-testng-runner
作为 Maven 依赖项
<dependency>
<groupId>com.github.eljaiek.playground</groupId>
<artifactId>autopilot-testng-runner</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
最后,我用 @AutopilotTest
@Guice
注释
@AutopilotTest(modules = CommModule.class)
public class CommunicationTest {
@Inject
private Communication comms;
@Test
public void testSendMessage() {
Assertions.assertThat(comms.sendMessage("Hello World!")).isTrue();
}
}