Re: SmartFrog components unit testing
Steve Loughran <[email protected]> Tue, 31 Mar 2009 17:01:13 +0100
| Newsgroups | gmane.comp.java.smartfrog.user |
|---|---|
| Message-ID | <[email protected]> |
Dominik Pospisil wrote:
> Hello,
>
>
> I would like to write some unit tests for custom components. I was
> wondering if there is an easy way how to do this preferably using JUnit
> or TestNG. I would like to do following things within an unit tests:
>
>
> 1) start (multiple) SF daemon(s)
> 2) deploy custom components
> 3) test component logic, inspect SmartFrog environment
> 4) stop SF daemon(s)
>
>
> Do I have to implemnt all this or is there something I can reuse?
I will split this into two problems. Running tests under Ant, and
testing SmartFrog itself. First the problem of running tests against
SmartFrog from Ant
The way it works is
-we have various Ant tasks to start and stop Smartfrog
-we have a functionaltest task to start smartfrog in one thread, wait
until the port is live,
then run a junit task pointed at that daemon, clearing everything up
at the end.
This lets us bring up a daemon if one is not running, and test it.
Here are all the ant tasks from common.xml to handle this; there is a
lot of set up to make it easy
to override and tune the test run:
http://smartfrog.svn.sourceforge.net/viewvc/smartfrog/trunk/core/common.xml?view=markup
<!--
SFOS-167 shows how Ant holds on to task definitions for a long
time, longer than we can
sustain on a windows client build. To reduce Permanent Generation
heap space, we are
not loading the tasks if they are already present
-->
<target name="probe-for-smartfrog-tasks" >
<condition property="sf.tasks.loaded">
<typefound name="sf-startdaemon"/>
</condition>
</target>
<!-- ========================================================== -->
<!-- probe for tasks and use them if they are found; fail if not -->
<!-- ========================================================== -->
<target name="use-smartfrog-tasks"
depends="use-smartfrog-tasks-classic,use-smartfrog-tasks-ivy,probe-for-smartfrog-tasks"
unless="sf.tasks.loaded"
description="declare the classpath and imports for the smartfrog
tasks">
<available
classname="org.smartfrog.tools.ant.Parse"
classpathref="smartfrog.tasks.classpath"
property="sfTasks.present"/>
<echo level="verbose">
Loading tasks from
${toString:smartfrog.tasks.classpath}
</echo>
<fail unless="sfTasks.present">
Smartfrog tasks not found in the classpath. Are the dependencies in
ivy.xml right?
smartfrog.tasks.classpath=
"${toString:smartfrog.tasks.classpath}"
</fail>
<typedef
resource="org/smartfrog/tools/ant/tasks.properties"
classpathref="smartfrog.tasks.classpath"
/>
</target>
<property name="junit.printsummary" value="off" />
<property name="junit.showoutput" value="true" />
<!-- set to brief for brief, plain for more -->
<property name="junit.printformatter" value="plain" />
<property name="junit.timeout" value="6000000"/>
<property name="junit.memory" value="512m"/>
<presetdef name="sf-junit">
<junit printsummary="${junit.printsummary}"
fork="true"
forkmode="once"
maxmemory="${junit.memory}"
includeantruntime="true"
showoutput="true"
timeout="${junit.timeout}"
>
<jvmarg value="-ea"/>
<jvmarg value="-esa"/>
<jvmarg
value="-Demma.coverage.out.file=${emma.coverage.dir}/coverage.emma" />
<jvmarg value="-Demma.coverage.out.merge=true" />
<!--copy all proxy settings from the running JVM-->
<syspropertyset refid="proxy.settings"/>
<!-- #Tests take system property parameters -->
<!-- #Formatters for capture and display -->
<formatter type="xml"/>
<formatter type="${junit.printformatter}" usefile="false"/>
</junit>
</presetdef>
<!-- testing for a server being present; set a property to set -->
<presetdef name="sf-daemonfound">
<condition >
<socket port="${smartfrog.daemon.port}" server="localhost" />
</condition>
</presetdef>
<!-- wait for 10 seconds for a daemon. Set maxwait to a different
value for more or less time, timeoutproperty to the name of a property
to set on failure -->
<presetdef name="sf-waitfordaemon">
<waitfor maxwait="10" maxwaitunit="second">
<socket server="localhost" port="${smartfrog.daemon.port}"/>
</waitfor>
</presetdef>
<!-- reporting wrapper -->
<macrodef name="sf-junitreport">
<attribute name="data"/>
<attribute name="reports"/>
<sequential>
<junitreport todir="@{data}">
<fileset dir="@{data}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="@{reports}"/>
</junitreport>
</sequential>
</macrodef>
<macrodef name="sf-test-report">
<attribute name="data"/>
<attribute name="reports"/>
<attribute name="failed"/>
<sequential>
<sf-junitreport data="@{data}" reports="@{reports}" />
<fail if="@{failed}">Tests failed see:
@{reports}</fail>
</sequential>
</macrodef>
<presetdef name="sf-startdaemon-debug">
<sf-startdaemon classpathref="run.classpath"
logStackTraces="true" spawn="true"
dir="${build.test.dir}"
>
<!-- assertions are enabled -->
<assertions enableSystemAssertions="true">
<enable/>
</assertions>
<!--copy all proxy settings from the running JVM-->
<syspropertyset refid="proxy.settings"/>
<!-- load in a property file if it is present -->
<propertyfile file="${runtime.properties}" optional="true"/>
</sf-startdaemon>
</presetdef>
<!--
This target defines the task
<sf-system-test> which is a functional tests runner ready to
run smartfrog, just add tests and go.
The classpath of the daemon is set to tests.run.classpath;
-->
<target name="declare-system-test-tasks"
depends="declare-extended-smartfrog-tasks,init-codebase" >
<property name="daemon.jvmargs" value=""/>
<presetdef name="sf-system-test">
<sf-functionaltest testTimeout="600" shutdownTime="10">
<application>
<condition property="daemon.already.live">
<socket server="localhost" port="${smartfrog.daemon.port}" />
</condition>
<sf-conditional unless="daemon.already.live">
<sf-startdaemon-debug failonerror="false"
spawn="false"
classpathref="tests.run.classpath">
<jvmarg line="${daemon.jvmargs}" />
<!--all properties beginning with test. or run.-->
<syspropertyset>
<propertyref prefix="test."/>
<propertyref prefix="run."/>
</syspropertyset>
</sf-startdaemon-debug>
</sf-conditional>
</application>
<probe>
<socket port="${smartfrog.daemon.port}" server="localhost"/>
</probe>
<teardown>
<parallel>
<sf-stopdaemon failonerror="false"/>
<sf-conditional unless="tests.skip.reports">
<sf-junitreport data="${test.data.dir}"
reports="${test.reports.dir}"
/>
</sf-conditional>
</parallel>
</teardown>
</sf-functionaltest>
</presetdef>
<presetdef name="sf-system-test-junit">
<sf-junit
errorProperty="system.test.failed"
failureProperty="system.test.failed"
includeAntRuntime="true"
>
<classpath refid="tests.run.classpath" />
<sysproperty key="test.classes.dir"
value="${test.classes.dir}"/>
<!--all properties beginning with test and runtime, and the
codebase-->
<syspropertyset>
<propertyref prefix="test."/>
</syspropertyset>
<sysproperty key="org.smartfrog.codebase" value="${codebase}"/>
<syspropertyset>
<propertyref prefix="runtime."/>
</syspropertyset>
</sf-junit>
</presetdef>
<!-- define the system test post processor-->
<presetdef name="sf-system-test-validate">
<fail if="system.test.failed" unless="tests.skip.failing">
System Tests for ${ant.project.name} failed - see
${test.reports.dir}/index.html
</fail>
</presetdef>
<!--default pattern for system tests-->
<property name="sf-system-test-class-pattern"
value="org/smartfrog/**/test/**/*Test.class" />
<presetdef name="sf-system-test-batch-run">
<sf-system-test>
<test>
<sf-system-test-junit>
<batchtest todir="${test.data.dir}" if="testcase">
<fileset dir="${test.classes.dir}"
includes="**/${testcase}.class"/>
</batchtest>
<batchtest todir="${test.data.dir}" unless="testcase">
<fileset dir="${test.classes.dir}">
<include name="${sf-system-test-class-pattern}"/>
</fileset>
</batchtest>
</sf-system-test-junit>
<sf-system-test-validate/>
</test>
</sf-system-test>
</presetdef>
</target>
------------------------------------------------------------------------------