Reputation: 862
I am packaging JUnit test cases and suites in a jar and trying to execute these using JUnit core from inside main. The issue is that when I execute these testcases after packaging in JAR, beans are not injected (which implies an issue with spring context.) However, when I execute main method from IDE, beans are injected and everything works.
These test cases have a parent class which is loading the spring context.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { AppConfig.class } )
public abstract class BaseTest {
@Autowired
protected WebDriver driver;
@PreDestroy
public void teardown() {
...
}
}
A test class and suite-
public class SomeTestClass extends BaseTest {
@Test
public void someTestCase() {
...
}
}
@RunWith(Suite.class)
@Suite.SuiteClasses({
SomeTestClass.class
})
public class SomeTestSuite { }
There's a main method which is being used to execute these testcases/suites with 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());
}
}
}
I am getting NullPointerException when executing this via JAR but no issues when execute main method from within IDE.
I am using IntelliJ 2017.2.x, JUnit 4.12 for testcases and maven shade plugin 3.0 to package jar.
EDIT 1
Executing jar as -
java -jar myjar.jar
NPE when executing via JAR-
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)
Background - I have some selenium test cases for an app in production. It creates an instance of headless chrome for execution. The reason these were wrapped as test cases is because ideally we wanted to integrate this with saucelabs (saucelabs needs selenium code wrapped as testcases for execution.) However, currently there are some constraints as to how saucelabs is setup in my organization and we can't go down that road as of today but while we figure this out, we kept writing this code. So now, I am trying to create a JAR with this code and deploy it in production. This way, I don't have to make a lot of changes when we are able to move with Saucelabs.
Upvotes: 1
Views: 952
Reputation: 862
After troubleshooting through spring code and logs, I figured that it's failing because my JAR doesn't have spring.factories
file in it's META-INF
.
Possible solutions-
spring.factories
file in src/main/resources/META-INF
. You can write your own (refer spring doc) or copy spring.factories
from any spring dependency in your project. Related question on SO.I went with option 2 because it seemed easy in this scenario. I didn't need anything more than just spring.factories from spring-boot dependency, so option 1 would have been an overkill.
Upvotes: 1