How do I pass parameters to a Junit test from Ant? - ant

I'm using Junit under Ant to perform Selenium Test.My test cases need to read files
which contain test data(in order to accomplish data driven test).
I don't mind embedding the file names in the test cases, but I'd like to have the name of the directory where the
data files are stored parameterized in the build.xml file.
What's the best way to pass information like that from build.xml down into the test cases?
Is it a good idea to use ant property?
Is it possible to inject Junit4 parameter from build.xml?

The junit task accepts nested sysproperty elements.
<junit fork="no">
<sysproperty key="mydatadir" value="${whatever}"/>
...
</junit>
You can access these from within your tests using System.getProperty().

Related

Jmeter 3.0 can't generate the ANT HTML report

I am on the verge of pulling all my hair out, someone please help me..
I am using JMeter 3.0 and am trying to generate the dashboard report from my jtl files, but I get the error -
result.jtl' does not contain the field names header, ensure the jmeter.save.saveservice.* properties are the same as when the CSV file was created or the file may be read incorrectly
my user.properites file contains -
jmeter.save.saveservice.output_format=csv
jmeter.save.saveservice.bytes=true
jmeter.save.saveservice.label=true
jmeter.save.saveservice.latency=true
jmeter.save.saveservice.response_code=true
jmeter.save.saveservice.response_message=true
jmeter.save.saveservice.successful=true
jmeter.save.saveservice.thread_counts=true
jmeter.save.saveservice.thread_name=true
jmeter.save.saveservice.time=true
jmeter.save.saveservice.timestamp_format=ms
jmeter.save.saveservice.timestamp_format=yyyy-MM-dd HH:mm:ss
jmeter.save.saveservice.print_field_names=true
these values are the same in the jmeter.properties file as well, just to ensure I haven't lost anything...
I really can't work out why I can't get the jtl to include the headers, I have followed every guide I can find, and I seem to be doing it right..
Can someone point to me what I am missing, or include a zipped version of their jmeter with it all working that I can try and point my ant project to?
Hope someone can help.
Double check <jmeter> section of your build.xml file. Default JMeter Ant Task assumes XML out put format for .jtl result files so if you have the following line:
<property name="jmeter.save.saveservice.output_format" value="xml"/>
just comment it out or delete it and your issue should be resolved.
I don't think JMeter Ant Task respects overrides via user.properties file, it is better to use jmeterproperties attribute or explicitly specify the relevant configuration in the Ant build file like:
<target name="test">
<jmeter
jmeterhome="${jmeter.home}"
testplan ="${testpath}/${test}.jmx"
resultlog="${testpath}/${test}.jtl">
<property name="jmeter.save.saveservice.output_format" value="csv"/>
<property name="jmeter.save.saveservice.print_field_names" value="true"/>
<property name="jmeter.save.saveservice.timestamp_format" value="ms"/>
<!--etc.-->
</jmeter>
</target>
I would also recommend choosing one of jmeter.save.saveservice.timestamp_format properties (either ms or yyyy-MM-dd HH:mm:ss as it might cause problems with the dashboard generation), having duplicate property names with different values is not a very good practice.
See Five Ways To Launch a JMeter Test without Using the JMeter GUI article for more information on running JMeter tests via Ant task and other ways of kicking off a JMeter test
I had noticed before you posted, but it is correct, the XML type was hardcoded in the build.xml, now I have changed that, all is working :)

How does jUnit Task get its information

I understand that if I want xml output from my jUnit tests I can use the Ant task "jUnit" to generate such output.
I want to extend the amount of information shown in this generated xml file.
I have additional information in my class file that I want to be available in the XML file as well.
My questions are:
Where is the information in the xml file coming from?
Is the information coming from the specific jUnit runner class that
is used to run the tests?
Does the jUnit task only format the received information or is it
generating the information itself?
Does the jUnit Ant task change the received information? (So it will
only show specific information and filter out everything I want to
add)
The JUnit task's XML formatter is implemented in the class org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter, a listener that receives events during the execution of the JUnit tests. For example, when a "test ended" event is received, the formatter appends an XML element in memory for the test. Here's a link to the source code.
Based on what I read from the code:
The schema of the XML is defined in the Ant task's code. Specifically the above mentioned class. The schema is discussed in Spec. for JUnit XML Output. The content of the report, e.g. test name and class name are fetched from the JUnit test classes themselves. Here's a Javadoc for the method that retrieves the test name:
JUnit 3.7 introduces TestCase.getName() and subsequent versions of JUnit remove the old name() method. This method provides access to the name of a TestCase via reflection that is supposed to work with version before and after JUnit 3.7.
since Ant 1.5.1 this method will invoke "public String getName()" on any implementation of Test if it exists.
Since Ant 1.7 also checks for JUnit4TestCaseFacade explicitly. This is used by junit.framework.JUnit4TestAdapter.
The task does not only format the output. It generates all the report itself using the mentioned formatter. A couple of posts that may be helpful to extend the formatter:
How do I configure JUnit Ant task to only produce output on failures?
Custom JUnit Report?
A proposed solution is to write a custom formatter class extending org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter and provide it in the classname attribute of the formatter element.

Display Ant options, properties specified in invocation

I have an Ant buildfile (build.xml) which is called by some application. I would like to know exactly what kind of properties are used to invoke Ant. Therefore I would like to modify the build.xml file to display all properties specified in the call, e.g.:
ant aTarget -Dxslt.parser=SAXON -Dbasedir=aFolder
would display list as below
- target: aTarget
- xslt.parser = SAXON
- basedir=aFolder
Please note that I do not know exactly what is being using to invoke Ant. Therefore, I need to use some sort of a loop get all properties, options.
The simplest thing that comes to mind is to place a line like:
<echo message="Ant invocation is '${sun.java.command}'" />
In the buildfile outside of any target. It'll look something like:
% ant aTarget -Dx=y
[echo] ant invocation is: 'org.apache.tools.ant.launch.Launcher -cp . aTarget -Dx=y'
It shows you what was passed to the Ant Launcher, which might will likely be a little more than what was passed to the ant wrapper script, but should do.
I would avoid trying to parse the line, as you say, you don't know what might be there, and it could quickly get complicated.
Take a look at the <echoproperties> task:
<property name="in.file.prop" value="value2"/>
<echoproperties/>
in.file.prop and its value will be printed. However, over 60 other properties will be printed as well including properties built into Ant.
You can save the results of <echoproperties> to a file and then filter that file with something like a <linecontains> filter.

Findbugs ant task submitting several dynamically detected JAR files for analysis

I'm currently looking to run static analysis over a pre-existing project. As the project is created and supplied by an off-site company, I cannot change the build process radically.
The project is split into a lot of sub-modules, located in various places. For other analyisi tools (JDepend, Google Testability Explorer, etc.), I have dynamically detected all build JAR files into a path element as follows:
<path id="built-libs">
<fileset dir="${overall-base}">
<include name="${some-common-base}/**/lib/*.jar" />
</fileset>
</path>
<property name="built-libs-string" refid="built-libs" />
For some tools, I use the build-libs, for others I use the string (in classpath form; x.jar;y.jar).
The trouble is, FindBugs uses a completely different format to any other;
<class location="x.jar"/>
<class location="y.jar"/>
...
Now, I could list all the JAR files manually, but then run the risk of this list going out of synch with the other tool's lists, or of introducing typos.
Another complication is that I also want to run the reports in Jenkins, in this case the extract directory for individual modules will depend on the job that has previously built the module (pipeline builds, modules extracted from SCM and built in parallel, the reporting occurring at the end of the pipline).
I could make a call out to the OS to run FindBugs, passing in the JARs in a space separated list (as in Invoking FindBugs from Ant: passing a space-separated list of files to java). However, I prefer a, Ant solution to an OS <exec... hack.
Note I know I have a similar problem for the sourcepath element, however, I'm assuming that solving the class element problem also solves the sourcepath one.
Ideally, FindBugs should be taking a resource collection rather than separate class elements. I'm not familiar with FindBugs, so I can't comment on why they have chose to go the class element route instead of a resource collection, however your comment about using exec implies that using a resource collection is a valid design alternative.
I would try rolling your own Ant macro, which invokes FindBugs directly using the java task. This should give you the control you need and avoiding the redundancy that the FindBugs Ant task would introduce.
Another option (which is an ugly hack) is to use the fileset to write a mini ant file with a FindBugs target, which you then invoke using the ant task. shudders
The Findbugs Ant task allows you to specify a filelist which can be used to specify multiple files. Quoting from the Findbugs documentation
"In addition to or instead of specifying a class element, the FindBugs
task can contain one or more fileset element(s) that specify files to
be analyzed. For example, you might use a fileset to specify that all
of the jar files in a directory should be analyzed."
Example that includes all jars at ${lib.dir}:
<findbugs home="${findbugs.home}" output="xml" outputFile="findbugs.xml" >
<auxClasspath path="${basedir}/lib/Regex.jar" />
<sourcePath path="${basedir}/src/java" />
<fileset dir="${lib.dir}">
<include name="*.jar"/>
</fileset>
</findbugs>

How can I run a custom JUnit4 Runner on JUnit3 test classes with Ant?

We have test classes which are built on Spring 2.0.8's AbstractTransactionalDataSourceSpringContextTests. There are a huge number of these, all of which are written in JUnit3 style.
In order to use JUnit 4 filtering, we have concocted a replacement JUnit38Runner which allows us to match these tests to a specific application environment, and filter them out accordingly.
The whole test suite runs fine outside of Ant, by using the #RunWith annotation on our custom JUnit38Runner.
When we try to run in Ant, however, it forces individual tests to run either as junit.framework.TestSuite or wrapped in a JUnit4TestAdapter, both of which ignore #RunWith annotations under JUnit4. To make matters worse, our existing suites are explicitly overridden by Ant, which calls the suite() methods directly, rather than delegating to JUnit.
I have attempted to extend from the Ant JUnitTestRunner, and simply override the run() method, however the class is simply not written for extension.
Aside from copying the whole of the JUnitTestRunner and hacking it (which will open us up to brittle code issues), has anyone had any luck with other approaches to solving this problem?
We had a similar problem, and although it's not as clean as running the junit task, it's not terribly difficult to solve. We created a class with a main() that simply invokes the Junit4Runner. It adds a RunListener that attempts to write out the junit report output in XML. The idea was that the dataformat is much less likely to change than the runner, so it's less brittle.
I've stripped out a fair amount of environment-specific code, but this is the basic idea. Our test target in ant looks like this:
<java failonerror="yes"
fork="true"
classname="com.mycompany.test.Junit4Runner">
<classpath>
<pathelement location="${basedir}/bin" />
<pathelement path="${ProjectTest.classpath}" />
<!-- above classpath includes junit-4.8.1.jar -->
</classpath>
<arg value="${test.class}" />
</java>
You can view the code for the runner class here. It doesn't depend on anything outside Java 6 SE and Junit 4.8, and it may be compatible with Java 5 SE.

Resources