TestNG 集成的大同考试问题

Pax-Exam issue with TestNG Integration

我尝试将 pax-exam 插件与 testng 集成,但最终出现以下错误。但是它在 junit 上运行良好。

[org.ops4j.pax.exam.spi.intern.DefaultTestAddress] : NEW ADDRESS= PaxExam-90b1718e-7414-486a-8ae2-b5628e4b7a67 parent=[TestAddress:PaxExam-ea9b0dd3-b693-4efb-8003-7f6b92b05f99 root:PaxExam-ea9b0dd3-b693-4efb-8003-7f6b92b05f99] root=[TestAddress:PaxExam-ea9b0dd3-b693-4efb-8003-7f6b92b05f99 root:PaxExam-ea9b0dd3-b693-4efb-8003-7f6b92b05f99] args=[Ljava.lang.Object;@4f063c0a
[org.ops4j.pax.exam.spi.intern.DefaultTestAddress] : NEW ADDRESS= PaxExam-652d3b11-ab7c-49d0-bcba-f9d56c9210ee parent=[TestAddress:PaxExam-806e1a66-76ff-44cf-90d9-ff26b658b855 root:PaxExam-806e1a66-76ff-44cf-90d9-ff26b658b855] root=[TestAddress:PaxExam-806e1a66-76ff-44cf-90d9-ff26b658b855 root:PaxExam-806e1a66-76ff-44cf-90d9-ff26b658b855] args=[Ljava.lang.Object;@1e6d1014
org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; nested exception is java.lang.reflect.InvocationTargetException: null
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
    at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:103)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:74)
Caused by: java.lang.NoSuchMethodError: org.testng.internal.MethodInstance.<init>(Lorg/testng/ITestNGMethod;)V
    at org.ops4j.pax.exam.testng.listener.PaxExam.intercept(PaxExam.java:503)
    at org.testng.TestRunner.createParallelWorkers(TestRunner.java:995)
    at org.testng.TestRunner.privateRun(TestRunner.java:747)
    at org.testng.TestRunner.run(TestRunner.java:608)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
    at org.testng.SuiteRunner.run(SuiteRunner.java:240)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1158)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1083)
    at org.testng.TestNG.run(TestNG.java:999)
    at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:76)
    at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:112)
    at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:115)
    ... 9 more

知道这里出了什么问题吗?

以下是我的示例测试代码。我认为这是我们可以编写的基本测试用例。

import org.ops4j.pax.exam.Configuration;
import org.ops4j.pax.exam.Option;
import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
import org.ops4j.pax.exam.spi.reactors.PerClass;
import org.ops4j.pax.exam.testng.listener.PaxExam;
import org.osgi.framework.BundleContext;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import javax.inject.Inject;

import static org.testng.Assert.assertNotNull;
import static org.ops4j.pax.exam.CoreOptions.*;


@Listeners(PaxExam.class)
@ExamReactorStrategy(PerClass.class)
public class SampleTest {

    @Inject
    BundleContext bundleContext;

    @Configuration
    public Option[] config() {

        return options(
                mavenBundle().artifactId("testng").groupId("org.testng").versionAsInProject()
        );
    }

    @Test
    public void testBundleContextStatus() {
        assertNotNull(bundleContext, "Bundle Context is null");
    }
}

这是我用过的依赖。

<dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>${testng.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam</artifactId>
            <version>${exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-container-native</artifactId>
            <version>${exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-testng</artifactId>
            <version>${exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.exam</groupId>
            <artifactId>pax-exam-link-mvn</artifactId>
            <version>${exam.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ops4j.pax.url</groupId>
            <artifactId>pax-url-aether</artifactId>
            <version>${url.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.api.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.ow2.spec.ee</groupId>
            <artifactId>ow2-jta-1.1-spec</artifactId>
            <version>${ow2.jta.spec.version}</version>
            <scope>test</scope>
        </dependency>

将 testng 依赖版本更改为 6.3.1 后,它可以正常工作。但是对于最新发布的版本 6.9.6 问题是存在的。

问题的最新编辑包含答案。 Pax Exam 4.6.0 是用 TestNG 6.8.17 编译的,显然在 TestNG 6 中有一个不兼容的 API 变化。9.x.

Pax Exam 直接使用 TestNG 的一些内部 类,因为没有更好的选择。

一般情况下,最好将 Pax Exam 与 JUnit 结合使用。 JUnit 集成得更好,在 OPS4J 和其他下游项目中有更多的测试覆盖率和使用率。