SpringJUnit4ClassRunner 在 Jar 中打包后不工作但在 IDE 中工作

SpringJUnit4ClassRunner not working after packaging in Jar but works in IDE

我正在将 JUnit 测试用例和套件打包在一个 jar 中,并尝试使用 main 中的 JUnit 核心来执行它们。问题是当我在 JAR 中打包后执行这些测试用例时,bean 没有被注入(这意味着 spring 上下文有问题。)但是,当我从 IDE 执行 main 方法时,bean 被注入并且一切正常。

这些测试用例有一个父 class 正在加载 spring 上下文。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AppConfig.class } )
public abstract class BaseTest {

    @Autowired
    protected WebDriver driver;

    @PreDestroy
    public void teardown() {
        ...
    }
}

测试class和套件-

public class SomeTestClass extends BaseTest {
    @Test
    public void someTestCase() {
        ...
    }
}


@RunWith(Suite.class)
@Suite.SuiteClasses({
    SomeTestClass.class
})
public class SomeTestSuite { }

有一个主要方法用于使用 JUnitCore 执行这些 testcases/suites。

    public static void main(String...args) {
        Result result = JUnitCore.runClasses(SomeTestSuite.class);

        if (result.wasSuccessful()) {
            LOGGER.info("All tests executed successfully: {}", result);
        } else {
            LOGGER.error("There are failures");
            for (Failure failure: result.getFailures()) {
                LOGGER.error("failure: {} msg: {} desc: {}", failure, failure.getMessage(), failure.getDescription(), failure.getException());
            }
        }
    }

我在通过 JAR 执行此操作时收到 NullPointerException,但在 IDE.
中执行主要方法时没有问题 我正在使用 IntelliJ 2017.2.x,用于测试用例的 JUnit 4.12 和用于打包 jar 的 maven shade 插件 3.0。

编辑 1
执行 jar 作为 -

java -jar myjar.jar

通过 JAR-

执行时的 NPE
2017-11-29 10:16:00,567 [TestCasesExecutor:44] ERROR junit.framework.Test  - failure: testMethodName(testClass): null msg: null desc: testMethodName(testClass)
java.lang.NullPointerException
        at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:770)
        at org.openqa.selenium.support.ui.FluentWait.<init>(FluentWait.java:96)
        at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:71)
        at org.openqa.selenium.support.ui.WebDriverWait.<init>(WebDriverWait.java:45)
        at com.mycom.SomeTestClass.setup(BaseTest.java:37)
        at com.mycom.testcases.SplunkGcpScoreCardTest.logoutFromGcpScorecard(SplunkGcpScoreCardTest.java:27)
        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:498)
        at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:33)
        at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
        at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
        at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
        at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
        at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
        at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runners.Suite.runChild(Suite.java:128)
        at org.junit.runners.Suite.runChild(Suite.java:27)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58)
        at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:105)
        at org.junit.runner.JUnitCore.runClasses(JUnitCore.java:62)
        at org.junit.runner.JUnitCore.runClasses(JUnitCore.java:49)
        at com.mycom.TestCasesExecutor.main(TestCasesExecutor.java:37)

背景 - 我有一些 selenium 测试用例用于生产中的应用程序。它创建一个无头 chrome 的实例来执行。 将这些包装为测试用例的原因是因为理想情况下我们希望将其与 saucelabs 集成(saucelabs 需要将 selenium 代码包装为测试用例才能执行。)但是,目前存在一些限制saucelabs 是在我的组织中设置的,从今天开始我们不能走这条路,但在我们弄清楚这一点的同时,我们一直在编写这段代码。所以现在,我正在尝试使用此代码创建一个 JAR 并将其部署到生产环境中。这样,当我们能够使用 Saucelabs 移动时,我不必做很多更改。

通过 spring 代码和日志进行故障排除后,我认为它失败了,因为 我的 JAR 在 META-INF[=24] 中没有 spring.factories 文件=]. 可能的解决方案-

  1. 将项目更改为 spring 引导,启用自动配置并使用 spring 引导 maven 插件创建 JAR,该插件负责正确打包。
  2. src/main/resources/META-INF 中创建 spring.factories 文件。您可以编写自己的 (refer spring doc) or copy spring.factories from any spring dependency in your project. .

我选择了选项 2,因为在这种情况下它看起来很简单。我只需要 spring-boot 依赖项中的 spring.factories,所以选项 1 就太过分了。