Ant is a tool that makes compiling, packaging and even running Java applications easier.
Jameleon uses Ant to help make building custom tags, registering them and executing Jameleon test cases easier. Currently the GUI cannot be used to register nor build custom tags.
Add the following line to the build.xml which needs access any of the Jameleon Ant Tasks
<taskdef resource="ant/JameleonAntTasks.properties" format="properties" classpathref="base.classpath"/>
Jameleon provides the following Ant tasks.
Task Function Short Description Upgrade Jameleon Task Applies any needed configuration changes between releases. This is new as of jameleon-core-3.3-M3 Tag Registration Task Registers Java files matching a given criteria in Jameleon. Test Case Execution Task Executes Jameleon test case scripts in the same JVM as Ant is running in. Test Case Execution Separate VM Task Executes Jameleon test case scripts in a separate JVM from the one Ant is running in.
This tag is used to make any required changes to your configuration and or directory structure that may occur between version releases. This tag is new as of Jameleon-core-3.3-M3 and may or may not need to be executed in future releases.
The UpgradeTask has the following attributes:
attribute Description Required Default environmentProperties The location of the Environment.properties file to be affected. YES res/Environment.properties jameleonGUIProperties The location of the jameleon-gui.properties file to be affected. NO lib/jameleon-gui.properties
The Tag Registration Task auto registers any Jameleon tags into the Jameleon Scripting Engine ( Jelly ). Simply by adding the appropriate javadoc tag, this task will know the required information about the tags to be registered.
The JameleonXDoclet task has the following attributes:
attribute Description Required Default outputdir The directory to save the file(s) to. This directory should be included
in the jar file that is created from all of the custom tags. It is recommended
to use the same location the compiled java files are compiled to. YES N/A outputfilename The name of the file to save. Unless being used by a plug-in developer, this
setting should not be changed. For plug-in developers, this file name should be
the name of your plug-in and all plugins should end in -plugin. So for a jRex plug-in,
the outputfilename would be jrex-plugin.properties NO TestCaseTagDefs.properties quiet Don't print warnings for files that don't have the appropriate tags. NO false isA
The class types to include in the registration. In other words, all classes
that extend or implement the value of isA will be parsed for information. If you're
tag isn't getting registered, it could be that you aren't extending FunctionTag. In
that case, just change the isA to the class your tag is extending.
NO net.sf.jameleon.function.FunctionTag.
This task also accepts an Ant fileset to define where the source files that need registering are. For example, to register source files that exist in src/java where the registered files would be placed in build, the following would work:
<target name="register.tags" description="Registers Custom Tags"> <taskdef resource="ant/JameleonAntTasks.properties" format="properties" classpathref="classpath"/> <jmln-register outputdir="build"> <fileset dir="src/java"> <include name="**/*.java"/> </fileset> </jmln-register> </target>
Once all of the tags are registered, you can generate a file that describes the details of each tag. TODO: add examples. There is currently an example in the jameleon-core/src/xml/standard-build.xml file.
The the following attributes are supported
attribute Description Required Default outputFile The file to generate YES xdocs/syntax-reference.xml plugin The begining of the .properties file to generate from. For the selenium plug-in, this would be selenium-plugin. YES TestCaseTagDefs - or the file that is generated for custom tags templateName The template to use for file generation. Not that the file is loaded through the CLASSPATH. YES syntaxReference.txt - This file is bundled with jameleon-core.jar templateParam This is a nested tag set. <templateParam name="templateVarName" value="var value"/>.
The existing template expects a variable called "pluginName" which is really the library name (i.e. HtmlUnit). NO N/A
This tasks is used to execute test cases that match a certain pattern. If any of the test cases fail, the build fails with a list of files, line numbers and short descriptions why they failed.
All of the jar files that come with Jameleon and any plug-ins must be in the CLASSPATH. The ExecuteTestCaseTask task has the following attributes and it supports the Ant fileset data type as well as the selectortype.
Atribute Name Description Default debug
Prints all stack traces to std out. This is very useful when the test case won't
execute for some reason of if you aren't sure whey something is happening.
false throwExceptionOnFailure
Throws a build exception when a test fails if set to true.
true waitTimeBetweenScripts
Waits n milliseconds between each script being executed.
0 printTestSuiteSummary
This is used when want to break up your tests into several test suites and run any number
of test suites, but only include the test suite summary at the bottom once. Set this to false
when you don't want to print out the summary.
true
The fileset data type allows test cases to be executed based on the filename and/or directory structure. The selector option (which is encapsulated in a fileset) is used to scan for text in the matching files.
The selector Ant tag can be used to execute all test cases that have a keyword or that contain a certain functional point. Because of the nature of the scripting engine, unknown tags are ignored. This is another good reason to use test case doc tags and set a selector to execute all files that contain the tag and value in them. For example, to execute all test cases with a test-case-level of SMOKE:
<target name="run.tests" description="Execute Smoke tests"> <taskdef resource="ant/JameleonAntTasks.properties" format="properties" classpathref="classpath"/> <jmln-test debug="true"> <fileset dir="scripts"> <include name="**/*.xml"/> <exlcude name="**/*.fragment"/> <contains text="test-case-level>SMOKE" casesensitive="no"/> </fileset> </jmln-test> </target>
This would execute all test cases in the scripts directory, containing the word test-case-level>SMOKE, except for files that end in .fragment.
Sometimes you may want to pass in a variable that can be used in a Jameleon script. This can be accomplished via the <variable/> tag. It has name and value attributes that can be set. The following is an example of how to use it:
<target name="run.variable.test" description="Runs a script, passing in a variable on the fly"> <taskdef resource="ant/JameleonAntTasks.properties" format="properties" classpathref="classpath"/> <jmln-test debug="true"> <fileset dir="scripts"> <include name="somescript.xml"/> </fileset> <variable name="varName" value="varValue"/> </jmln-test> </target>
Sometimes you may want to pass in jameleon.conf settings via Ant. This can be accomplished via the <config/> tag. It has name and value attributes that can be set. The following is an example of how to use it:
<target name="run.alpha.tests" description="Runs all scripts under the alpha testEnvironment and sf organization"> <taskdef resource="ant/JameleonAntTasks.properties" format="properties" classpathref="classpath"/> <jmln-test debug="true"> <fileset dir="scripts"> <include name="somescript.xml"/> </fileset> <config name="testEnvironment" value="alpah"/> <config name="organization" value="sf"/> </jmln-test> </target>
While executing several tests simultaneously is not officially supported, it could drastically reduce test execution time. To execute several scripts at the same time, the <parallel/> Ant task can be used. A possible strategy to do this might be to create several "run" targets, representing different groups of test suites. These suites can then be executed in threads. The only caveat to this is that the first suite of tests being executed must run at least 1500 milliseconds before the other ones are. The following is an example:
<taskdef resource="ant/JameleonAntTasks.properties" format="properties" classpathref="classpath"/> <target name="test.admin" description="Run all scripts for the foo admin application"> <jmln-test printTestSuiteSummary="false" > <fileset dir="scripts/admin"> <include name="**.xml"/> </fileset> </jmln-test> </target> <target name="test.userprefs" description="Run all scripts for the user prefs application"> <jmln-test printTestSuiteSummary="false" > <fileset dir="scripts/userprefs"> <include name="**.xml"/> </fileset> </jmln-test> </target> <target name="test.crm" description="Run all scripts for the crm application"> <jmln-test printTestSuiteSummary="false" > <fileset dir="scripts/crm"> <include name="**.xml"/> </fileset> </jmln-test> </target> <target name="test.sales" description="Run all scripts for the sales lead application"> <jmln-test printTestSuiteSummary="false" > <fileset dir="scripts/sales"> <include name="**.xml"/> </fileset> </jmln-test> </target> <target name="print.test.summary" description="Prints the test case execution summary at the end of the HTML results"> <jmln-test printTestSuiteSummary="true" > <fileset dir="tst/xml/acceptance"> <exclude name="*.*"/> </fileset> </jmln-test> </target> <target name="test.suites" description="Runs all test suites in order" depends="test.mapvariables, test.prop, test.csv, print.test.summary"/> <target name="test.threaded"> <parallel> <antcall target="test.admin"/> <antcall target="test.userprefs"/> <antcall target="test.crm"/> <antcall target="test.sales"/> </parallel> <!-- Run this one last so the correct summary is printed --> <antcall target="print.test.summary"/> </target>
The ExecuteTestCaseSeparateVMTask acts mostly the same as the ExecuteTestCaseTask,except it executes under a different VM. This makes it easier to run tests under IDEs like Eclipse or even plug-ins that JNI like the jiffie-plugin.
The following attributes are supported by this tag:
Attribute Name Description Required classpathref A reference to the classpath used when running this tag true if the nested classpath tag is not used fork Execute in a separate VM true - Default is true newenvironment
Do not propagate old environment when new environment variables are
specified. Default is "false" (ignored if fork is disabled).
false - Default is false baseDir
The directory to start the JVM in.
false - Defaults to the Ant project baseDir attribute failOnError
Fails the build when an error occurs.
false - Defaults to false timeout
Time in milliseconds to wait until the execution halts
false - Defaults to 0 separateVmPerScript
Execute each script in a separate JVM. This is helpful for code that
doesn't clean up memory very well. The side effect of using this feature
is that the HTML logs (TestResults.html) file counts each test script
as a suite of test scripts. In other words, percentages and total numbers
will only represent the single script executed.
false - Defaults to false printFooter
When separateVmPerScript is set to true, the test results are not calculated correctly
because the logging system is started and stopped between each test case execution. The result
of this is TestResults.xml file with a summary for each script. To get rid of this,
set printFooter to false and the footer or summary will no longer be logged.
false - Defaults to true
An example might look like:
<target name="run.tests.vm" description="Execute Smoke Tests in a separate VM"> <taskdef resource="ant/JameleonAntTasks.properties" format="properties" classpathref="classpath"/> <jmln-test classpathref="classpath"> <fileset dir="scripts"> <include name="**/*.xml"/> <exlcude name="**/*.fragment"/> <contains text="test-case-level>SMOKE" casesensitive="no"/> </fileset> </jmln-test> </target>