<html>
<!-- <![CDATA[ putDataHere ]]> -->
+<head>
<title>Writing tests for the AspectJ compiler
</title>
+</head>
<body>
<h2>Writing tests for the AspectJ compiler
</h2>
<li><a href="#simple">Simple test definitions</a></li>
<li><a href="#sourceFiles">Test source files</a></li>
<li><a href="#incremental">Incremental tests</a></li>
- <li><a href="#verifying">Verifying test steps</a></li>
+ <li><a href="#verifying">Verifying test steps</a>
<ul>
<li><a href="#messages">Messages</a></li>
<li><a href="#dirchanges">Changes in an output directory</a></li>
- <li><a href="#tester">Runtime behavior</a></li>
- </ul>
+ <li><a href="#tester">Testing runtime behavior</a></li>
+ </ul></li>
+ <li><a href="#forking">Forking at runtime</a></li>
<li><a href="#compilerOptions">Compiler Options</a></li>
<li><a href="#background">Harness background</a></li>
</ul>
<a href="#simple">Simple test definitions</a> and
<a href="#sourceFiles">Test source files</a>.
-<p>Related documents:
+<p>Related documents:</p>
<ul>
<li>For information on running the harness, see
<a href="readme-tests-module.html">
<code>pack/Aspect.java</code> and
<code>pack2/Main.java</code> and
run the main class:
+</p>
<pre>
<ajc-test dir="new" title="simple run test">
<compile files="pack/Aspect.java,pack1/Main.java"/>
<p>More complex compilations are discussed in
<a href="#compilerOptions">Compiler Options</a> below.
-
+</p>
<a name="sourceFiles"></a>
<h4>Test source files</h4>
question of whether source files should be updated; if not,
the tag can have the special value "same". For example, if
the last example had two more lines:
+</p>
<pre>
...
<inc-compile tag="30"/>
the normal (ajc) compiler, and requires specifying
<code>-ajdeCompiler</code> to the harness or compile step
as an argument.
-<p>
+<p/>
To recap the attributes of note for setting up incremental tests:
<ul>
</li>
</ul>
-<p>
+<p/>
Now, to get back to the question of
what exactly is happening in an incremental test. To do so,
compare the tags with the files specified in
are to run the corresponding class or check the compiler messages.
More generally, the harness can verify compile/run test steps by detecting the
following things and comparing against expected behavior:
-<p>
+<p/>
<table border="1" cellpadding="1">
</tr>
<tr><td>Runtime behavior</td>
<td>Use <code>Tester</code> in test source code
- to signal events for comparison with expected events.</td>
+ to signal events for comparison with expected events.
+ To signal failure when running a forked test without Tester,
+ throw an exception.</td>
</tr>
</table>
-<p>
+<p/>
<a name="messages"></a>
<h5>Messages</h5>
and a List of ISourceLocation (essentially, "see also", to point
to other relevant places in the code). The thrown element is not
supported, but you can specify the others:
-
+</p>
<pre>
<ajc-test dir="new" title="simple error test">
<compile files="Main.java">
to distinguish them. If you are using text or detail attributes,
do not use one string that is a prefix of the other, since it
will match either message, and the other message might not match.
-
+</p>
<p>
The "info" messages are special in that they are normally ignored.
To specify expected "info" messages, you have to list all the
messages the compiler will issue, which can vary depending on
-the compiler settings. Use the option <code>^verbose<code> to
+the compiler settings. Use the option <code>^verbose</code> to
force the compiler's <code>-verbose</code> option off.
+</p>
<p>
By the same token, if you don't specify any extra source locations,
then they will not be checked. If you think it is a bug if they
are issued, then you have to specify one if them. (There is
currently no way to specify that a message has no extra
source locations.)
+</p>
<a name="dirchanges"></a>
<h5>Changes in an output directory</h5>
The current harness defaults to using the classes directory,
and when using the classes directory uses <code>.class</code>
as a default suffix.
+</p>
<p>
Here's an example specification:
-<pre>
+</p>
+ <pre>
<ajc-test dir="new/dirchanges-test" title="dir-changes test">
<compile staging="true"
files="Main.java,DeleteMe.java,Unchanged.java"/>
}
aspect A {
- before () : target(Runnable) && execution(void run()) {
+ before () : target(Runnable) && execution(void run()) {
Tester.event("before advice");
}
}
<code>Tester</code> also has methods that operate like
JUnit assertions as idioms to detect differences in
expected and actual values, signalling appropriately.
-<p>
+</p>
<code>Tester</code> is at
<a href="../testing-client/src/org/aspectj/testing/Tester.java">
<p>You can write runtime test cases without using Tester;
simply throw some exception from the main thread to signal failure.
+</p>
+
+<a name="forking"></a>
+<h4>Forking and load-time weaving</h4>
+<p>You can fork the tests that are run by setting global properties
+ or by setting attributes to run. One attribute,
+ <code>aspectpath</code>, forces the run to fork and uses
+ load-time weaving to weave aspects with the classpath.
+ </p>
+<p>To fork for all tests, set the global system property
+ <code>javarun.fork</code> to "true". You can also
+ set other properties to control how forking happens.
+ (By default, forking uses the java executable that was
+ used to run the harness.)
+ The following causes all <code>run</code> steps to
+ fork into the specified Java 1.1 VM.
+</p>
+<pre>
+java -Djavarun.fork=true \
+ -Djavarun.java=c:/home/jdk11/bin/java.exe \
+ -Djavarun.java.home=c:/home/jdk11 \
+ -Djavarun.bootclasspath=c:/home/jdk11/lib/classes.zip \
+ -Djavarun.vmargs=-Dname=value,-Dname2="value 2" \
+ org.aspectj.testing.drivers.Harness ...
+ </pre>
+
+<p>You can fork a specific test by setting
+ the <code>fork</code> attribute (and optionally the
+ <code>vmargs</code> attribute):
+</p>
+<pre>
+ <ajc-test dir="new" title="show forking">
+ <compile files="Main.java"/>
+ <run class="Main" fork="true"
+ vmargs="-Dname=value,-Dname2="value 2"/>
+ </ajc-test>
+</pre>
-<a name="compilerOptions"></a>
+<p>As a special case of forking, load-time weaving sets up
+ a Java 1.4 or later VM using our weaving class loader,
+ if you specify the <code>aspectpath</code> attribute to
+ <code>run</code>.
+ In the following example, the main class and the aspect
+ are compiled separately. The main class is then woven
+ and run using load-time weaving.</p>
+<pre>
+ <ajc-test dir="new" title="show LTW">
+ <compile files="Aspect.java" outjar="out.jar"/>
+ <compile files="Main.java"/>
+ <run class="Main" aspectpath="out.jar"/>
+ </ajc-test>
+</pre>
+
+ <a name="compilerOptions"></a>
<h4>Compiler options</h4>
The harness does not support all of the AspectJ 1.1 compiler options.
Flags are mainly supported through the a comma-delimited list in
<code>-g:none</code>, but will fail for comma-delimited single-arg options like
<code>-g:lines,vars</code> because the comma delimiters
are ambiguous (yes, a design bug!).
-<p>
+<p/>
The <code>compile</code> element has the following attributes
which handle most of the other compiler arguments:
<ul>
Paths for these are all relative to the test base directory, and
multiple entries are separated with commas.
(Use only one entry for xlintfile.)
-<p>
+<p/>
Here is a cooked example that uses all <code>compiler</code> attributes:
<pre>
<ajc-test dir="new" title="attributes test">
<ul>
<li><u>badInput</u>:
To test invalid input, set the compiler <code>badInput</code> attribute
-to "</code>true</code>". This prevents the harness from aborting a test
+to "<code>true</code>". This prevents the harness from aborting a test
because a specified input file was not found. (However, there is no way
to specify bad input for a directory in the files attribute intended for
-inpath, because the harness selects readable directories.)
the emacssym option off, even in tests that specify it).
</li>
</ul>
-<hr>
+<hr/>
<small>last updated March 8, 2004 </small> <!-- CVS variable -->
</body>