【发布时间】:2017-11-29 18:24:34
【问题描述】:
我将 JUnit 测试用例和套件打包到一个 jar 中,并尝试使用 JUnit 核心从 main 内部执行这些。问题是当我在 JAR 中打包后执行这些测试用例时,没有注入 bean(这意味着 spring 上下文存在问题。)但是,当我从 IDE 执行 main 方法时,注入了 bean 并且一切正常。
这些测试用例有一个加载弹簧上下文的父类。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AppConfig.class } )
public abstract class BaseTest {
@Autowired
protected WebDriver driver;
@PreDestroy
public void teardown() {
...
}
}
一个测试类和套件-
public class SomeTestClass extends BaseTest {
@Test
public void someTestCase() {
...
}
}
@RunWith(Suite.class)
@Suite.SuiteClasses({
SomeTestClass.class
})
public class SomeTestSuite { }
有一个 main 方法用于使用 JUnitCore 执行这些测试用例/套件。
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 中执行 main 方法时没有问题。
我使用 IntelliJ 2017.2.x、JUnit 4.12 测试用例和 maven shade 插件 3.0 来打包 jar。
编辑 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$1.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$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.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$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.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$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.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 一起移动时,我不必进行太多更改。
【问题讨论】:
-
我认为您的单元测试不属于任何可执行的 JAR。它们应该在打包之前在您的 IDE 或集成构建工具中运行。
-
我的情况不同。这些是业务 Web 应用程序的 selenium 测试用例。尽管我很想将这些与酱实验室集成,但目前它不是一个选项。
-
对我来说听起来并没有什么不同。祝你好运。堆栈跟踪告诉你什么是空的。这会给你一个提示。
-
粘贴您的 NPE 和您获得的任何其他日志输出。粘贴您如何“通过 JAR”运行此程序。并解释为什么你甚至想从 jar 中运行打包在 main 中的 junit 测试,而不是使用 maven。
-
NPE 粘贴在上面,JAR 被触发为“java -jar myjar.jar”。当代码使用来自 spring 核心的 Environment 类型的对象时,就会发生 NPE。它应该是Autowired。我打印了要自动装配的班级成员,他们都是空的。