I have a script(test.bat) that allows me to launch one java test by command line :
-java -cp() org.junit.runner.JUnitCore package.Class
Now I want to do the same for several java tests ?
how could I do it? should I have to add the byte code for each java test?
could I have an example , please?
You can use Ant to run your tests with a single command with the junit ant task. Here's an example on how to use it:
<target name="runtests" depends="clean,compiletests">
<junit printsummary="yes" haltonfailure="no">
<classpath>
<path refid="test.classpath" />
<pathelement location="${test.classes}"/>
</classpath>
<formatter type="xml"/>
<batchtest fork="yes" todir="${test.reports}">
<fileset dir="${test.src}">
<include name="**/*Test*.java"/>
</fileset>
</batchtest>
</junit>
</target>
That target uses batchtest which is part of the junit ant task. It sets your test classpath so all your tests that contain the Test.java pattern in their class name will be included. Check out the JUnit Task documentation.
In JUnit, you can group your tests into a test suite and then run that with a single command.
Here is a tutorial on using test suites in JUnit 3, and here is an SO post about same with JUnit 4. Moreover, here is a tutorial on how to use the new features of JUnit 4.
However, if you are practically trying to write a build script in your batch file, I recommend using an existing build system instead, be it Ant, Maven, Buildr or something else.
A convention used in JUnit is to have an AllTests test suite that groups all tests in the project together and have an Ant script or whatever execute the AllTests test suite.
You can create a set of suites using the JUnit annotation syntax. I describe it in more detail here.
I see 3 possibilities:
Use ant (see other answers while I'm typping)
update your batch to java -cp ... file1 file2 filen
use something like this:
org.junit.runner.JUnitCore.runClasses(TestClass1.class, ...);
public class GlobalTest { }
Related
I'm not very familiar with JUnit, but I'm attempting to translate an ant target that makes use of junit into the gradle equivalent. It's not going so hot, since I'm getting some failures on the gradle side -- I'm under the impression that it's due to inputs not being found somehow/somewhere, but I can't confirm, since it's not readily present in the ant target.
Here's the ant script:
<target name="testing">
<junit printsummary="yes" showoutput="yes">
<classpath refid="classpath"/>
<formatter type="xml"/>
<batchtest fork="yes" todir="someOutputLocation">
<fileset dir="${base}/testCode">
<include name="**/included.java"/>
<exclude name="**/excluded.java"/>
</fileset>
</batchtest>
</junit>
</target>
And here's (one of the variations) of my gradle attempt:
task testing(type:Test){
useJUnit()
testClassesDir = file("testCodeCompiled")
include '**/included.class'
exclude '**/excluded.class'
classpath = classpath
}
The two errors I get:
junit.framework.AssertionFailedError
java.lang.NullPointerException
The AssertionFailedError is supposedly caused by multiple JUnit dependencies, which I don't have. I import a local version of only junit-4.11.
I really don't know why it's not working, though I suspect it's due to some of gradle's complexities. I've seen people mention an ant-junit library, which I may try to use to at least replicate the results from within gradle.
EDIT: A thought occurs: I found JUnit within some of gradle's src files. By calling useJUnit(), I may be using that instead? If so, there could be a double dependency after all? Nope. Got rid of useJUnit() and the local jar separately. The former behaved as it did before whereas the latter exploded.
MORE INFO: The cause may likely be that the compiledTestCode is missing several of the directories/data that testCode contains. I probably have to copy over the relevant files. Alternatively, is there a way to make gradle's JUnit use .java files instead of .class?
For those of you wondering, the code is fine. I'm just dumb.
Since I updated my Java from JDK7u55 to JDK7u60, I am facing an issue while running my build. I am using Ant 1.6.5 on Windows Server 2003 Standard Edition. Below is the Ant task which causes a problem.
<!-- RUN JUNIT TASK -->
<target name="run_junit" description="Runs all JUnit tests in another JVM">
<sequential>
<move file="${MyProject}\bin\myApp.jar" tofile="${MyProject}\bin\myApp_original.jar"/>
<move file="${MyProject}\bin\myApp_test.jar" tofile="${MyProject}\bin\myApp.jar"/>
<exec executable="WinTail" spawn="true">
<arg value="${MyProject}\junit.log"/>
</exec>
<java classname="myProject.test.AllTests"
maxmemory="256m"
fork="true"
output="${MyProject}\junit.log"
dir="${MyProject}\bin"
append="true">
<jvmarg value="-Djdk.lang.Process.allowAmbigousCommands=true"/>
<arg value="${MyProject}\bin"/>
<classpath>
<fileset dir="${MyProject}\bin">
<include name="myApp.jar"/>
</fileset>
<pathelement path="${MyProject}\bin"/>
</classpath>
</java>
<move file="${MyProject}\bin\myApp.jar" tofile="${MyProject}\bin\myApp_test.jar"/>
<move file="${MyProject}\bin\myApp_original.jar" tofile="${MyProject}\bin\myApp.jar"/>
</sequential>
</target>
Once two JARs have been renamed, I start running all the tests using <java> task. The AllTests.java uses seperate thread to run each test. There are some tests which takes bit longer to finish and some actually don't respond. I used to kill them manually by using ProcessExplorer. Once that was done it used to execute next command which renames back the JARs to their original names. It used to work when I was using JDK7u55.
Now since I upgraded Java to JDK7u60, instead of waiting for all the tests to be finished, the last two <move> commands are attempted. This causes the build failure as <move> caanot proceed because the underlying JAR files are being used by the test classes. I get below error:
BUILD FAILED
C:\MyProject\build.xml:579: Unable to delete file C:\MyProject\bin\myApp.jar
I am wondering what has changed in JDK7u60 which caused this behavior. I checked the Release Notes of JDK7u60 but didn't get anything. Can someone please shed some light on this?
Firstly on windows it's not uncommon for files belonging to another process or thread to prevent the deletion of a file.
Secondly what exactly is the purpose of the sequential task in your ANT target? The documentation describes the tasks as follows:
Sequential is a container task - it can contain other Apache Ant
tasks. The nested tasks are simply executed in sequence. Sequential's
primary use is to support the sequential execution of a subset of
tasks within the parallel task
In your case there's no use of parallel...
Why don't you try to remove the sequential task and see if that fixes the problem.
Here is my ANT JUnit target
<target name="test" depends="compile" >
<junit failureProperty="test.failure" >
<jvmarg value="-Xdebug" />
<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5432" />
<classpath>
<pathelement path="${basedir}\..\Core\lib\junit-4.10.jar"/>
<pathelement path="${basedir}\..\Suggestion\lib\ssce.jar"/>
<pathelement path="C:\Java\javamail-1.4.1\mail.jar"/>
<pathelement path="C:\Java\commons-net-2.0\commons-net-ftp-2.0.jar"/>
<pathelement path="${basedir}\WebContent\WEB-INF\lib\gson-2.2.1.jar"/>
<pathelement path="${tomcatLibs}\servlet-api.jar"/>
</classpath>
<classpath>
<pathelement path="${build}"/>
</classpath>
<formatter type="brief" usefile="false" />
<test name="com.server.junit.ServerTestSuite" />
<test name="com.junit.DictionaryTestSuite" />
<test name="com.util.junit.SuggestionTestSuite" />
</junit>
<fail message="Unit test failed" if="test.failure"/>
</target>
My unit tests pass fine if run through Eclipse but fail if I laund them from ANT.
I want it to stop at my break point in a Unit test.
From documentation I know I need to add these jvmarg but can't get it to stop so I obviously don't have them in the right place.
Also, I don't think I have the port correct but what port should I use? I didn't have to set up any debug port when debugging JUnits through eclipse, it just worked
You need to forget a moment that you can run JUnit tests and ANT targets from within Eclipse. What you want is to debug a Java application that happens to have the main class org.apache.tools.ant.Main and which can be started with ant from the command line.
You have now two options: You can create a launch config that invokes org.apache.tools.ant.Main but that's pretty complicated to set up (you will have to replicate everything that the ant script does at startup).
The other alternative is to configure ant correctly. In your case, the tests run within the ant process but I know no simple way to pass -Xdebug to Ant itself. Therefore, you must run the tests in a new process. Add this to the junit task:
<junit fork="yes" forkmode="once" ...>
Without this, jvmarg parameters will be ignored.
The next step is to create a debug configuration in Eclipse. This article explains this in detail. For you, only the last part right before "Conclusion" is important.
Detailed instructions:
In Eclipse, navigate to Run | Debug.
Select Remote Java Application, on the left column. Click New, on the bottom of the same column.
In the Create configuration screen you'll be prompted to enter some values. Start with a meaningful name. For Project, select the Java project that contains the source code you want to debug. Leave Connection Type in default, i.e. Standard (Socket Attach) . For Host , enter localhost. If you want to debug a remote server, enter its hostname or IP address. For port, enter 5432.
Click Apply.
Make sure your tests is running in debug mode. In the same screen click Debug . Eclipse should automatically take you to the Debug perspective and you should see a stack trace in the Debug view.
If you are not automatically taken to the Debug perspective, select Window | Open Perspective | Other and then click Debug.
Taken from here.
I'm trying to work out how I can run an ant task without actually needed a build.xml.
In particular I want to run a JUnit task with a formatter. In xml format this looks like below:
<junit printsummary="true" errorProperty="test.failed" failureProperty="test.failed">
<classpath refid="run.class.path" />
<!-- console log -->
<formatter type="xml" classname="be.x.SFFormatter" />
<test name="be.x.SF" outfile="result" todir="${build.output.dir}" />
</junit>
It works when running the ant script, but I would like to get my app running as a runnable jar.
Running the tests from Java was easy:
JUnitCore junit = new JUnitCore();
testResult = junit.run(SeleniumFramework.class);
However, I struggle to work out how to actually get the formatter to work.
The formatter is of type org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter so I doubt I can just plug it in somewhere without running ant.
Has anyone done something similar before?
Thanks!
Ant doesn't do any magic. All it does is read the XML file, create the beans specified in it and then execute the methods as per the Task API (org.apache.tools.ant.Task).
So all you need is to do the same in your code. Don't forget to create a Project :-)
You may use Ant via Groovy to avoid the xml syntax.
See => Using Ant from Groovy for details.
I have a ant file that runs JUnits tests. These tests rely on a relative path to certain configuration files. I've tried to set the working directory for the batch test, but fail.
I want the working directory to be ${plugins.dir}/${name}
The JUnit part of the ant script:
<junit haltonfailure="no" printsummary="on" fork="true" showoutput="true" dir="${plugins.dir}/${name}">
<jvmarg value="-Duser.dir=${plugins.dir}/${name}"/>
<classpath>
<path refid="project.classpath"/>
<pathelement location="${plugins.dir}/${dependency}/#dot/"/>
<pathelement location="${plugins.dir}/${name}/" />
</classpath>
<formatter type="xml" />
<sysproperty key="basedir" value="${plugins.dir}/${name}"/>
<sysproperty key="dir" value="${plugins.dir}/${name}"/>
<batchtest todir="${junit.output}">
<fileset dir="${dir}">
<include name="**\*AllTests.class" />
</fileset>
</batchtest>
</junit>
I've googled and searched but the workarounds I've found have been to set the "dir", "sysproperty" or "jvmarg". As you can see I've tried them all :)
Is there a way to print the current dir in the tag? It doesnt support . That would allow me to verify if the dir is actually changed and to what.
One wildcard in this equation is that this is being run in Hudson that starts upp an eclipse process that starts antrunner. This is so we can run both junit and eclipse plugin junit tests. Shouldn't have anything to do with the problem I think.
I think you are right with setting the basedir property (see projects attributes). However, since it is a property of ANT (and not of the JVM) it is READ ONLY!
Does it effect other target if you set the basedir when calling your ant task? See Command Line reference.
ant -Dbasedir=somedir
Alternatively, span a new ant process to call your junit target. See the AntCall task or Ant task. Following examples assumes that the junit target contains your junit task. I used this task for other properties (never needed the basedir property so far.
<antcall target="junit">
<param name="basedir" value="${plugins.dir}/${name}"/>
</antcall>
<ant dir="${plugins.dir}/${name}" target="junit" />
I had the same scenario and in my case I saw that dir="...." is ignored if run in same jvm so I simply added fork='true' and it worked.
Quote from Apache's documentation site "dir - The directory in which to invoke the VM. Ignored if fork is disabled.". More here.
I'm using NetBeans. When I add to Ant properties (from Tools, Options, Java, Ant) work.dir=C:/MyWorkingDir/ it executes ant with the following command and changes the working dir to C:\MyWorkingDir:
ant -f D:\\workspace\\lib\\project -Dfork=true -Djavac.includes=com/myapp/MyTest.java -Dtest.includes=com/myapp/MyTest.java "-Dwork.dir=C:/MyWorkingDir/" test-single