I have a diificult ClassDefNotFound problem (see here)
I run my unit tests through maven surefire plugin.
I would like to print out my unit test classpath at runtime. The following code only outputs one entry, namely the surefire jar. (I guess surefire has its own classloader and is using reflection.)
#Test
public void testGetClasspathTest()
{
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
TestSS.getLogger().debug(url.getFile());
}
}
Can someone suggest a way to get the full runtime classpath from within a junit test?
the answer is simple:
mvn -e -X install
This provides full debug output including test runtime classpath
Related
Spring boot project, there is a web integration test, when execute it in eclipse (run as > junit test) it's ok.
public class ReservationControllerIntegrationTest extends BaseWebIntegrationTest{...}
but when run mvn clean package , encountered below error:
initializationError(com.foo.web.BaseWebIntegrationTest) Time elapsed: 0.005 sec <<< ERROR!
java.lang.Exception: No runnable methods
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:191)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:128)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:416)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:84)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:65)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.<init>(SpringJUnit4ClassRunner.java:140)
when I changed
public class BaseWebIntegrationTest
to
public abstract class BaseWebIntegrationTest
then run mvn clean package again, this time it is build successfully!
So why run junit test in eclipse do not need to specify abstract explicitly?
The mvn surefire plugin auto-detects test suites based on some simple rules applied to all the classes it finds under src/main/test. In particular, it looks for all concrete classes matching a particular naming convention.
https://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html
In your case the plugin thinks that BaseWebIntegrationTest is a test suite, because it matches the naming convention, but it's not finding any test methods in it. When you made the class abstract the plugin skipped it because it was no longer instantiable. You could also have renamed the class so that it didn't end in the word Test.
When you run the test in Eclipse I'm guessing you run the specific integration test (ReservationControllerIntegrationTest) and so Eclipse doesn't try to treat BaseWebIntegrationTest as a test suite.
So I currently have the following build.gradle file:
apply plugin: 'java'
sourceSets {
main {
java {
srcDir 'src/model'
}
}
test {
srcDirs = ["tests/model"]
}
}
dependencies {
compile files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
testCompile group: 'junit', name: 'junit', version: '4.+'
}
that builds successfully when I type "gradle test" into the command line.
However I do the following error when running gradle test:
Creating properties on demand(a.k.a dynamic properties) has been deprecated.
As you can see, my junit tests are all in the folder test/model/ but I was wondering how do I see the results of if my junit tests passed?
You can view my repository here: https://github.com/quinnliu/WalnutiQ
Chingy,
I had to update a couple of things in your build.gradle:
source set for tests
added Maven repository to get JUnit library
apply plugin: 'java'
repositories {
mavenCentral()
}
sourceSets {
main {
java {
srcDir 'src/model'
}
}
test {
java {
srcDir 'tests/model'
}
}
}
dependencies {
compile files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
testCompile group: 'junit', name: 'junit', version: '4.+'
}
Now, the results of $ gradle build:
bender:WalnutiQ demo$ gradle build
:compileJava UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:jar UP-TO-DATE
:assemble UP-TO-DATE
:compileTestJava
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:processTestResources UP-TO-DATE
:testClasses
:test
model.RetinaTest > test_seeBMPImage FAILED
java.lang.IllegalArgumentException at RetinaTest.java:25
model.MARK_I.SpatialPoolerTest > test_performSpatialPoolingOnRegion FAILED
java.lang.IllegalArgumentException at SpatialPoolerTest.java:60
model.util.JsonFileInputOutputTest > test_saveRegionObject FAILED
java.lang.IllegalArgumentException at JsonFileInputOutputTest.java:69
model.util.SynapsePermanencesViewerTest > test_saveRegionToBeOpenedInSynapsePermanencesViewer FAILED
java.lang.IllegalArgumentException at SynapsePermanencesViewerTest.java:45
49 tests completed, 4 failed
:test FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':test'.
> There were failing tests. See the report at: file:///Users/demo/development/tmp/WalnutiQ/build/reports/tests/index.html
I think you can take it from here :o)
PS: I would recommend to refactor your project structure to match Maven/Gradle structure, so you don't have to deal with source sets and it will make your build.gradle cleaner.
src/main/java Production Java source
src/main/resources Production resources
src/test/java Test Java source
src/test/resources Test resources
src/sourceSet/java Java source for the given source set
src/sourceSet/resources Resources for the given source set
When you run gradle build or gradle test, there is a build directory that is created.
This directory is where all the build artifacts are placed.
Inside the build directory is a reports directory. This directory is where reports are placed.
For example, pmd reports, junit reports, etc.
The JUnit reports are located in the tests directory. Open up the index.html file in a browser to view the report.
You can specify where the JUnit test results go with the following command within your test block.
test {
reports.junitXml.destination = file('build/test-results/folder')
}
Are there any ready-to-use Gradle plugins to use for UglifyJs? We are trying to configure Uglify something similar to what has been done here, but the owner of that project seems to have his own private artifactory to which he points to, thereby getting access to UglifyAntTask, which is a github-hosted project not following Gradle/Maven etc. (basically non-managed) JAR. We tried downloading this JAR to our project and tried configuring using the options suggested in gradle page as follows:
dependencies {
compile fileTree(dir: 'libs', include: '*.jar') (or)
compile files('uglifyjs-java-v1.0.jar')
}
Note: The (or) is not there in actual code, I mentioned only to indicate that we tried both options but it was not picking the JAR.
So at a later step, when we gave
ant.taskdef(name: "uglify", classname: "uglify.ant.UglifyTask", classpath: configurations.uglifyjs.asPath)
Gradle throws the following errror:
taskdef class uglify.ant.UglifyTask cannot be found
using the classloader AntClassLoader[]
I am hoping that at least some one must have had the need to include non-managed 3rd party JAR and have figured out how to do this, if so, please point the solution/mistake we have made.
Thanks,
Paddy
Here is how the offical Gradle documentation describe it:
configurations {
uglifyjs
}
dependencies {
uglifyjs files('uglifyjs-java-v1.0.jar')
}
task uglifyjs << {
ant.taskdef(name: 'uglifyjs', classname: 'uglify.ant.UglifyTask', classpath: configurations.uglifyjs.asPath)
ant.uglifyjs( ... UglifyJS Ant Task parameters ... )
}
See http://www.gradle.org/docs/current/userguide/ant.html#N11416
HTH
In a maven project I have some junit tests where I need to refer to some runtime libraries (the birt runtime) when running the tests:
#Before
public void setup() {
// init osgi/birt rte.
BEngine.getEngine().init("C:\\birt-runtime-2_6_1\\ReportEngine\\");
}
#Test
public void testname() {
// run test that requires the initialization of the above rte.
}
This works fine when running the tests locally from eclipse. My maven project is also build on a linux server running jenkins but currently I disable tests that requires the above runtime libs.
I am considering to copy the runtime libs to the server running hudson and see if I can get hudson to pick up the location of these files when the tests are executed on hudson.
But to do this I need to use the correct location of the rte in the tests.
Any suggestions for doing this? Eg using env variables that can both be understood on windows/linux?
If the values will not change during the lifetime of the test run (i.e. the build), then use an environmental variable, and just set it as an option in the surefire plugin, systemPropertyVariables.
The correct way to do this for different environments is to use different profiles in maven.
You can have a default profile which includes the set of variables for windows, and another for the hudson.
EDIT: For running the tests correctly from within Eclipse, then simply you can have a default value for the variable
public String getRteLocation() {
String s = System.getProperty("test.rte.location");
return (s == null) ? "C:\\birt-runtime-2_6_1\\ReportEngine\\" : s;
}
#Before
public void setup() {
// init osgi/birt rte.
BEngine.getEngine().init(getRteLocation());
}
or simply set the environment variable in the Run Configuration in Eclipse.
EDIT: Just a clarification, when I say environment variables, I mean the -D variables set from the java command line.
I am trying to run a single JUnit test from the command line but I am getting an error.
I could compile the JUnit test successfully and the class file gets created in the correct location.
But when I try to run it using:
C:\Program Files\Java\jdk1.7.0_01\bin>java org.junit.runner.JUnitCore C:\eclipse\eclipse-java-helios-SR1-win32\eclipse\JunitWS\SeleniumTraining\src\com\org\tests\Nav.class
I get the error:
JUnit version 4.8.1
Could not find class: C:\eclipse\eclipse-java-helios-SR1-win32\eclipse\JunitWS\SeleniumTraining\src\com\org\tests\Nav.class
Exception in thread "main" java.lang.NoClassDefFoundError: org/hamcrest/SelfDesc
ribbing
I don’t know why it is not able to find the class even though it exists in the said location.
You need to specify the name of the class on the command line, not the filename:
java org.junit.runner.JUnitCore com.org.tests.Nav
From the javadoc for JUnitCore:
JUnitCore is a facade for running tests. It supports running JUnit 4
tests, JUnit 3.8.x tests, and mixtures. To run tests from the command
line, run java org.junit.runner.JUnitCore TestClass1 TestClass2 ....
For one-shot test runs, use the static method runClasses(Class[]). If
you want to add special listeners, create an instance of
org.junit.runner.JUnitCore first and use it to run the tests.
and you will have to add the bin directory (note NOT the src) to the classpath of the command line as well. This may look like:
java -cp C:\eclipse\eclipse-java-helios-SR1-win32\eclipse\JunitWS\SeleniumTraining\bin org.junit.runner.JUnitCore com.org.tests.Nav