如何在 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 那样。

我想知道是否:

您可以在 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 模块必须用于创建 InjectorLifecycleInjector.builder() 的自定义注释.我无法重用 @Guice 注释,因为 TestNG 还将创建其注入器,并且声明的依赖项将被创建两次。

  • AutopilotSuiteListener:实现 ISuiteListener 以创建父 InjectorGovernator 的 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();
        }
    }