\input texinfo   @c -*-texinfo-*-

@c AUnit Cookbook
@c Copyright (C) 2000-2014, AdaCore

@c %**start of header
@setfilename aunit.info
@settitle AUnit Cookbook
@setchapternewpage odd
@syncodeindex fn cp

@iftex
@afourpaper
@end iftex

@c ----------------------------------------- MACRO

@c Macro used for all AUnit examples
@c No cartouche on HTML as this is part of the css
@macro AEXP{TXT}
@ifhtml
@smallexample
@group
\TXT\
@end group
@end smallexample
@end ifhtml
@ifnothtml
@cartouche
@smallexample
@group
\TXT\
@end group
@end smallexample
@end cartouche
@end ifnothtml
@end macro

@include version.texi
@set VERSION @value{MAJOR_VERSION}@value{MINOR_VERSION}

@c ----------------------------------------- END MACRO

@titlepage

@title AUnit Cookbook
@subtitle AUnit - version @value{VERSION}
@subtitle Configuration level $Revision: 302445 $
@subtitle Date: @today{}
@author AdaCore

@sp 1
@url{http://www.adacore.com}

@vskip 0pt plus 1filll

@page

Copyright @copyright{} 2000-2011, AdaCore

@*

This document may be copied, in whole or in part, in any form or by any
means, as is or with alterations, provided that (1) alterations are clearly
marked as alterations and (2) this copyright notice is included
unmodified in any copy.

@end titlepage

@ifhtml
@c title page for the HTML documentation
@html
<font size="+2">
<p><font color="#33ff33">A</font><font color="#cc0000">U</font>nit Cookbook
<p>AUnit - version @value{VERSION}
<p>Configuration level $Revision: 302445 $
<p>Date: @today{}
<p>AdaCore
</font>

<font size="+1">
<p>@url{http://www.adacore.com}
</font>

@page

<p>Copyright @copyright{} 2000-2013, AdaCore

<p>This document may be copied, in whole or in part, in any form or by any
means, as is or with alterations, provided that (1) alterations are clearly
marked as alterations and (2) this copyright notice is included
unmodified in any copy.
@end html
@end ifhtml

@finalout

@ifnothtml
@contents
@end ifnothtml

@ifinfo

@node Top
@top AUnit

@menu
* Introduction::
* Overview::
* Test Cases::
* Fixture::
* Suite::
* Reporting::
* Test Organization::
* Using AUnit with Restricted Run-Time Libraries::
* Installation and Use::
* GPS Support::
@end menu
@end ifinfo

@c ======================================================================

@node Introduction
@chapter Introduction

@noindent
This is a short guide for using the AUnit test framework.
AUnit is an adaptation of the Java JUnit (Kent Beck, Erich Gamma) and C++
CppUnit (M. Feathers, J. Lacoste, E. Sommerlade, B. Lepilleur, B. Bakker,
S. Robbins) unit test frameworks for Ada code.

@c ---------------------------
@section What's new in AUnit 3

AUnit 3 brings several enhancements over AUnit 2 and AUnit 1:
@itemize

@item Removal of the genericity of the AUnit framework, making the AUnit 3
API as close as possible to AUnit 1.

@item Emulates dynamic memory management for limited run-time profiles.

@item Provides a new XML reporter, and changes harness invocation to support
easy switching among text, XML and customized reporters.

@item Provides new tagged types Simple_Test_Case, Test_Fixture and
Test_Caller that correspond to CppUnit's TestCase, TestFixture and TestCaller
classes.

@item Emulates exception propagation for restricted run-time profiles
(e.g. ZFP), by using the  gcc builtin setjmp/longjmp mechanism.

@item Reports the source location of an error when possible.

@end itemize

@c --------------
@section Examples

With this version, we have provided new examples illustrating the enhanced
features of the framework. These examples are in the AUnit
installation directory:
<aunit-root>/share/examples/aunit, and are also available in the source
distribution aunit-@value{VERSION}-src/examples.

The following examples are provided:
@itemize
@item simple_test: shows use of AUnit.Simple_Test_Cases
(@pxref{AUnit.Simple_Test_Cases}).
@item test_caller: shows use of AUnit.Test_Caller (@pxref{AUnit.Test_Caller}).
@item test_fixture: example of a test fixture (@pxref{Fixture}).
@item liskov: This suite tests conformance to the Liskov Substitution Principle
of a pair of simple tagged types. (@pxref{OOP considerations})
@item failures: example of handling and reporting failed tests
(@pxref{Reporting}).
@item calculator: a full example of test suite organization.
@end itemize

@c ----------------------------------
@section Note about limited run-times

AUnit allows a great deal of flexibility as to the structure of test cases,
suites and harnesses.  The templates and examples given in this document
illustrate how to use AUnit while staying within the constraints of the
GNAT Pro restricted and Zero Foot Print (ZFP) run-time libraries. Therefore,
they avoid the use of dynamic allocation and some other features that would
be outside of the profiles corresponding to these libraries. Tests targeted
to the full Ada run-time library need not comply with these constraints.

@c ------------
@section Thanks

This document is adapted from the JUnit and CppUnit Cookbooks documents
contained in their respective release packages.

Special thanks to Francois Brun of Thales Avionics for his ideas about
support for OOP testing.

@c ======================================================================

@node Overview
@chapter Overview

How do you write testing code?

The simplest way is as an expression in a debugger. You can change
debug expressions without recompiling, and you can wait to decide
what to write until you have seen the running objects. You can also
write test expressions as statements that print to the standard
output stream. Both styles of tests are limited because they require
human judgment to analyze their results. Also, they don't compose
nicely - you can only execute one debug expression at a time and a
program with too many print statements causes the dreaded "Scroll
Blindness".

AUnit tests do not require human judgment to interpret, and it is
easy to run many of them at the same time. When you need to test
something, here is what you do:

@enumerate

@item Derive a test case type from @code{AUnit.Simple_Test_Cases.Test_Case}.

Several test case types are available:
@itemize
@item @code{AUnit.Simple_Test_Cases.Test_Case}: the base type for all test
cases. Needs overriding of @code{Name} and @code{Run_Test}.
@item @code{AUnit.Test_Cases.Test_Case}: the traditional AUnit test case type,
allowing multiple test routines registration, each being run and reported
independently.
@item @code{AUnit.Test_Fixtures.Test_Fixture}: used together with
@code{AUnit.Test_Caller}, this allows easy creation of test suites comprising
several test cases that share the same fixture (@pxref{Fixture}).
@end itemize

@xref{Test Cases}, for simple examples of use of these types.

@item When you want to check a value@footnote{While JUnit and some other
members of the xUnit family of unit test frameworks provide specialized forms
of assertions (e.g. @code{assertEqual}), we took a design decision in AUnit
not to provide such forms.  Ada has a much more rich type system giving a
plethora of possible scalar types, and leading to an explosion of possible
special forms of assert routines.  This is exacerbated by the lack of a single
root type for most types, as is found in Java.  With the introduction of
AUnit 2 for use with restricted run-time profiles, where even 'Image is
missing, providing a comprehensive set of special assert routines in the
framework itself becomes even more unrealistic. Since AUnit is intended to
be an extensible toolkit, users can certainly write their own custom
collection of such assert routines to suit local usage.}, use one of the
following @code{Assert}@footnote{Note that in AUnit 3, and contrary to
AUnit 2, the procedural form of @code{Assert} has the same behavior whatever
the underlying Ada run-time library: a failed assertion will cause the
execution of the calling test routine to be abandoned. The functional form of
@code{Assert} always continues on a failed assertion, and provides you
with a choice of behaviors.} methods:

@AEXP{AUnit.Assertions.Assert (@b{Boolean_Expression}, @b{String_Description});}
or:
@AEXP{if not AUnit.Assertions.Assert (@b{Boolean_Expression}, @b{String_Description}) then
   return;
end if;}

If you need to test that a method raises an expected exception, there
is the procedure @code{Assert_Exception} that takes an access value designating the procedure
to be tested as a parameter:

@AEXP{
   type Throwing_Exception_Proc is access procedure;

   procedure Assert_Exception
     (Proc    : Throwing_Exception_Proc;
      Message : String;
      Source  : String := GNAT.Source_Info.File;
      Line    : Natural := GNAT.Source_Info.Line);
   --  Test that Proc throws an exception and record "Message" if not.
}

Example:

@AEXP{
   -- Declared at library level:
   procedure Test_Raising_Exception is
   begin
      call_to_the_tested_method (some_args);
   end Test_Raising_Exception;

-- In test routine:
procedure My_Routine (...) is
begin
   Assert_Exception (Test_Raising_Exception'Access, @b{String_Description});
end;}

This procedure can handle exceptions with all run-time profiles (including
zfp).  If you are using a run-time library capable of propagating exceptions,
you can use the following idiom instead:

@AEXP{
   procedure My_Routine (...) is
   begin
      ...
      -- Call subprogram expected to raise an exception:
      Call_To_The_Tested_Method (some_args);
      Assert (False, ``exception not raised'');
   exception
      when desired_exception =>
         null;
   end My_Procedure;}

An unexpected exception will be recorded as such by the framework.  If you want
your test routine to continue beyond verifying that an expected exception has
been raised, you can nest the call and handler in a block.

@item Create a suite function inside a package to gather together test cases
and sub-suites@footnote{If using the ZFP or the 'cert' run-time profiles, test
 cases and suites must be allocated using
 @code{AUnit.Memory.Utils.Gen_Alloc}, @code{AUnit.Test_Caller.Create},
 @code{AUnit.Test_Suites.New_Suite}, or be statically allocated.}.

@item At any level at which you wish to run tests, create a harness by
instantiating procedure @code{AUnit.Run.Test_Runner} or function
@code{AUnit.Run.Test_Runner_With_Status} with the top-level suite
function to be executed. This instantiation provides a routine
that executes all of the tests in the suite. We will call this
user-instantiated routine @code{@b{Run}} in the text for backward compatibility
to tests developed for AUnit 1. Note that only one instance of @code{@b{Run}}
can execute at a time.  This is a tradeoff made to reduce the stack requirement
of the framework by allocating test result reporting data structures
statically.

It is possible to pass a filter to a @code{Test_Runner}, so that only a
subset of the tests run. In particular, this filter could be initialized from
a command line parameter. See the package @code{AUnit.Test_Filters} for an
example of such a filter. AUnit does not automatically initialize this filter
from the command line both because it would not be supported with some of the
limited runtimes (zero footprint for instance), and because you might want to
pass the argument through different ways (as a parameter to switch, or a stand-alone
command line argument for instance).

It is also possible to control the contents of the output report by passing an
object of type @code{AUnit_Options} to the @code{Test_Runner}. See package
@code{AUnit.Options} for details.

@item Build the code that calls the harness @code{@b{Run}} routine using
gnatmake or gprbuild. The GNAT project file @i{aunit.gpr} contains all
necessary switches, and should be imported into your root project file.

@end enumerate

@c ======================================================================

@node Test Cases
@chapter Test Case

@menu
* AUnit.Simple_Test_Cases::
* AUnit.Test_Cases::
* AUnit.Test_Caller::
@end menu

@noindent
In this chapter, we will introduce how to use the various forms of Test
Cases. We will illustrate with a very simple test routine, that verifies
that the sum of two Moneys with the same currency result in a value
which is the sum of the values of the two Moneys:

@AEXP{declare
    X, Y: Some_Currency;
begin
   X := 12; Y := 14;
   Assert (X + Y = 26, "Addition is incorrect");
end;}

The following sections will show how to use this test method using the
different test case types available in AUnit.

@c -----------------------------
@node AUnit.Simple_Test_Cases
@section AUnit.Simple_Test_Cases

@noindent
@code{AUnit.Simple_Test_Cases.Test_Case} is the root type of all test
 cases. Although generally not meant to be used directly, it provides a
 simple and quick way to run a test.

This tagged type has several methods that need to be defined, or may be
overridden.

@itemize
@item @code{function Name (T : Test_Case) return Message_String is abstract}:

This function returns the Test name. You can easily translate regular
strings to Message_String using @code{AUnit.Format}. For example:

@AEXP{function Name (@b{T} : @b{Money_Test}) return Message_String is
begin
   return Format (@b{"Money Tests"});
end Name;}

@item @code{procedure Run_Test (T : in out Test_Case) is abstract}:

This procedure contains the test code. For example:
@AEXP{procedure Run_Test (@b{T} : in out @b{Money_Test}) is
    @b{X, Y: Some_Currency;}
begin
   @b{X := 12; Y := 14;}
   @b{Assert (X + Y = 26, "Addition is incorrect");}
end Run_Test;}

@item @code{procedure Set_Up (T : in out Test_Case);} and @code{procedure
Tear_Down (T : in out Test_Case);} (default implementations do nothing):

These procedures are meant to respectively set up or tear down the
environment before running the test case. @xref{Fixture}, for examples
of how to use these methods.

@end itemize

You can find a compilable example of
@code{AUnit.Simple_Test_Cases.Test_Case} usage in your AUnit installation
directory: <aunit-root>/share/examples/aunit/simple_test/ or from the
source distribution aunit-@value{VERSION}-src/examples/simple_test/

@c ----------------------
@node AUnit.Test_Cases
@section AUnit.Test_Cases

@code{AUnit.Test_Cases.Test_Case} is derived from
@code{AUnit.Simple_Test_Cases.Test_Case} and defines its
@code{Run_Test} procedure.

It allows a very flexible composition of Test routines inside a single
test case, each being reported independently.

The following subprograms must be considered for inheritance, overriding or
completion:

@itemize

@item @code{function Name (T : Test_Case) return Message_String is abstract;}
Inherited. @xref{AUnit.Simple_Test_Cases}.

@item @code{procedure Set_Up (T : in out Test_Case)} and @code{procedure
Tear_Down (T : in out Test_Case)}
Inherited. @xref{AUnit.Simple_Test_Cases}.

@item @code{procedure Set_Up_Case (T : in out Test_Case)} and
@code{procedure Tear_Down_Case (T : in out Test_Case)}
Default implementation does nothing.


The latter procedures provide an opportunity to Set Up and Tear Down the test
case before and after all test routines have been executed. In contrast, the
inherited @code{Set_Up} and @code{Tear_Down} are called before and after the
execution of each individual test routine.

@item @code{procedure Register_Tests (T : in out Test_Case) is
abstract}
This procedure must be overridden. It is responsible for registering all
the test routines that will be run. You need to use either
@code{Registration.Register_Routine} or the generic
@code{Specific_Test_Case.Register_Wrapper} methods defined in
@code{AUnit.Test_Cases} to register a routine. A test routine has the
form:
@AEXP{procedure Test_Routine (T : in out Test_Case'Class);}
or
@AEXP{procedure Test_Wrapper (T : in out Specific_Test_Case'Class);}

The former procedure is used mainly for dispatching calls
(@pxref{OOP considerations}).

@end itemize

Using this type to test our money addition, the package spec is:

@AEXP{with AUnit; use AUnit;
with AUnit.Test_Cases; use AUnit.Test_Cases;

package @b{Money_Tests} is

   type @b{Money_Test} is new Test_Cases.Test_Case with @b{null record};

   procedure Register_Tests (@b{T}: in out @b{Money_Test});
   -- Register routines to be run

   function Name (@b{T}: @b{Money_Test}) return Message_String;
   -- Provide name identifying the test case

   -- Test Routines:
   procedure @b{Test_Simple_Add} (@b{T} : in out Test_Cases.Test_Case'Class);
end @b{Money_Tests};}

The package body is:

@AEXP{with AUnit.Assertions; use AUnit.Assertions;

package body @b{Money_Tests} is

   procedure @b{Test_Simple_Add} (@b{T} : in out Test_Cases.Test_Case'Class) is
      @b{X, Y : Some_Currency;}
   begin
      @b{X := 12; Y := 14;}
      @b{Assert (X + Y = 26, "Addition is incorrect");}
   end @b{Test_Simple_Add};

   -- Register test routines to call
   procedure Register_Tests (@b{T}: in out @b{Money_Test}) is

      use AUnit.Test_Cases.Registration;

   begin
      -- Repeat for each test routine:
      Register_Routine (@b{T}, @b{Test_Simple_Add}'Access, @b{"Test Addition"});
   end Register_Tests;

   -- Identifier of test case

   function Name (@b{T}: @b{Money_Test}) return Test_String is
   begin
      return Format (@b{"Money Tests"});
   end Name;

end @b{Money_Tests};}

@c -----------------------
@node AUnit.Test_Caller
@section AUnit.Test_Caller

@noindent
@code{Test_Caller} is a generic package that is used with
@code{AUnit.Test_Fixtures.Test_Fixture}. @code{Test_Fixture} is a very
simple type that provides only the @code{Set_Up} and @code{Tear_Down}
procedures. This type is meant to contain a set of user-defined test
routines, all using the same Set up and Tear down mechanisms. Once those
routines are defined, the Test_Caller package is used to incorporate them
directly into a test suite.

With our money example, the Test_Fixture is:

@AEXP{with AUnit.Test_Fixtures;
package @b{Money_Tests} is
   type @b{Money_Test} is new AUnit.Test_Fixtures.Test_Fixture @b{with null record};

   procedure @b{Test_Simple_Add} (@b{T} : in out @b{Money_Test});

end @b{Money_Tests};}

The test suite (@pxref{Suite}) calling the test cases created from
this Test_Fixture is:

@AEXP{with AUnit.Test_Suites;

package Money_Suite is
   function Suite return AUnit.Test_Suites.Access_Test_Suite;
end Money_Suite;}

With the corresponding body:

@AEXP{with AUnit.Test_Caller;
with Money_Tests;

package body Money_Suite is

   package Money_Caller is new AUnit.Test_Caller
     (Money_Tests.Money_Test);

   function Suite return Aunit.Test_Suites.Access_Test_Suite is
      Ret : AUnit.Test_Suites.Access_Test_Suite :=
              AUnit.Test_Suites.New_Suite;
   begin
      Ret.Add_Test
        (Money_Caller.Create
           (@b{"Money Test : Test Addition"},
            @b{Money_Tests.Test_Simple_Add}'Access));
      return Ret;
   end Suite;

end Money_Suite;}

Note that @code{New_Suite} and @code{Create} are fully compatible with
limited run-times (in particular, those without dynamic allocation support).
Note, however, that for non-native run-time libraries, you cannot extend
@code{Test_Fixture} with a controlled component.

You can find a compilable example of
@code{AUnit.Test_Caller} use in the AUnit installation
directory: <aunit-root>/share/examples/aunit/test_caller/ or from the
source distribution aunit-@value{VERSION}-src/examples/test_caller/

@c ======================================================================

@node Fixture
@chapter Fixture

@noindent
Tests need to run against the background of a set of known entities.
This set is called a test fixture. When you are
writing tests you will often find that you spend more time writing
code to set up the fixture than you do in actually testing values.

You can make writing fixture code easier by sharing it.
Often you will be able to use the same fixture for several different
tests. Each case will send slightly different messages or parameters to the
fixture and will check for different results.

When you have a common fixture, here is what you do:

@enumerate
@item Create a Test Case package as in previous section.

@item Declare variables or components for elements of the fixture either
as part of the test case type or in the package body.

@item According to the Test_Case type used, override its @code{Set_Up}
and/or @code{Set_Up_Case} method:

@itemize
@item @code{AUnit.Simple_Test_Cases}: @code{Set_Up} is called before
@code{Run_Test}.

@item @code{AUnit.Test_Cases}: @code{Set_Up} is called before each test
routine while @code{Set_Up_Case} is called once before the routines are run.

@item @code{AUnit.Test_Fixture}: @code{Set_Up} is called before each
test case created using @code{Aunit.Test_Caller}.
@end itemize

@item You can also override @code{Tear_Down} and/or
@code{Tear_Down_Case} that are executed after the test is run.

@end enumerate

@noindent
For example, to write several test cases that want to work with
different combinations of 12 Euros, 14 Euros, and 26 US Dollars, first
create a fixture. The package spec is now:

@AEXP{with @b{AUnit}; use @b{AUnit};

package @b{Money_Tests} is
   use Test_Results;

   type @b{Money_Test} is new Test_Cases.Test_Case with @b{null record};

   procedure Register_Tests (@b{T}: in out @b{Money_Test});
   -- Register routines to be run

   function Name (@b{T} : @b{Money_Test}) return Test_String;
   -- Provide name identifying the test case

   procedure Set_Up (@b{T} : in out @b{Money_Test});
   --  Set up performed before each test routine

   -- Test Routines:
   procedure @b{Test_Simple_Add} (@b{T} : in out Test_Cases.Test_Case'Class);
end @b{Money_Tests};}

The body becomes:

@AEXP{package body @b{Money_Tests} is

   use Assertions;

   -- Fixture elements

   @b{EU_12, EU_14 : Euro;
   US_26        : US_Dollar;}

   -- Preparation performed before each routine

   procedure Set_Up (@b{T}: in out @b{Money_Test}) is
   begin
      @b{EU_12 := 12; EU_14 := 14;
      US_26 := 26;}
   end Set_Up;

   procedure @b{Test_Simple_Add} (@b{T} : in out Test_Cases.Test_Case'Class) is
       @b{X, Y : Some_Currency;}
   begin
       @b{Assert
         (EU_12 + EU_14 /= US_26,
          "US and EU currencies not differentiated");}
   end @b{Test_Simple_Add};

   -- Register test routines to call
   procedure Register_Tests (@b{T}: in out @b{Money_Test}) is

      use @b{Test_Cases.Registration};

   begin
      -- Repeat for each test routine:
      Register_Routine (@b{T}, @b{Test_Simple_Add}'Access, @b{"Test Addition"});
   end Register_Tests;

   -- Identifier of test case
   function Name (@b{T}: @b{Money_Test}) return Test_String is
   begin
      return Format (@b{"Money Tests"});
   end Name;

end @b{Money_Tests};}

@noindent
Once you have the fixture in place, you can write as many test
routines as you like. Calls to @code{Set_Up} and @code{Tear_Down}
bracket the invocation of each test routine.

Once you have several test cases, organize them into a Suite.

You can find a compilable example of fixture set up using
@code{AUnit.Test_Fixture} in your AUnit installation
directory: <aunit-root>/share/examples/aunit/test_fixture/ or from the
AUnit source distribution aunit-@value{VERSION}-src/examples/test_fixture/.

@c ======================================================================

@node Suite
@chapter Suite

@c ---------------------------
@section Creating a Test Suite

How do you run several test cases at once?

As soon as you have two tests, you'll want to run them together.
You could run the tests one at a time yourself, but you would quickly
grow tired of that. Instead, AUnit provides an object, @code{Test_Suite},
that runs any number of test cases together.

@noindent
To create a suite of two test cases and run them together, first create
a test suite:

@AEXP{with AUnit.Test_Suites;
package @b{My_Suite} is
   function @b{Suite} return AUnit.Test_Suites.Access_Test_Suite;
end @b{My_Suite};}

@AEXP{--  Import tests and sub-suites to run
with @b{Test_Case_1, Test_Case_2};

package body @b{My_Suite} is
   use AUnit.Test_Suites;

   -- Statically allocate test suite:
   @b{Result} : aliased Test_Suite;

   --  Statically allocate test cases:
   @b{Test_1 : aliased Test_Case_1.Test_Case;}
   @b{Test_2 : aliased Test_Case_2.Test_Case;}

   function @b{Suite} return Access_Test_Suite is
   begin
      Add_Test (@b{Result'Access, Test_Case_1'Access});
      Add_Test (@b{Result'Access, Test_Case_2'Access});
      return @b{Result'Access};
   end @b{Suite};
end @b{My_Suite};}

Instead of statically allocating test cases and suites,
you can also use @code{AUnit.Test_Suites.New_Suite} and/or
@code{AUnit.Memory.Utils.Gen_Alloc}. These routines emulate dynamic
memory management (@pxref{Using AUnit with Restricted Run-Time Libraries}).
Similarly, if you know that the tests will always be executed for a run-time
profile that supports dynamic memory management, you can allocate these
objects directly with the Ada @code{"new"} operator.

@noindent
The harness is:
@AEXP{with @b{My_Suite};
with AUnit.Run;
with AUnit.Reporter.Text;

procedure @b{My_Tests} is
  procedure @b{Run} is new AUnit.Run.Test_Runner (@b{My_Suite.Suite});
  Reporter : AUnit.Reporter.Text.Text_Reporter;
begin
   @b{Run} (Reporter);
end @b{My_Tests};}

@c ---------------------------
@section Composition of Suites

@noindent
Typically, one will want the flexibility to execute a complete set
of tests, or some subset of them. In order to facilitate this, we can
compose both suites and test cases, and provide a harness for any given
suite:

@AEXP{-- Composition package:
with @b{AUnit}; use @b{AUnit};
package @b{Composite_Suite} is
   function @b{Suite} return Test_Suites.Access_Test_Suite;
end @b{Composite_Suite};

--  Import tests and suites to run
with @b{This_Suite, That_Suite};
with AUnit.Tests;

package body @b{Composite_Suite} is
   use Test_Suites;

   --  Here we dynamically allocate the suite using the New_Suite function
   --  We use the 'Suite' functions provided in This_Suite and That_Suite
   --  We also use Ada 2005 distinguished receiver notation to call Add_Test

   function @b{Suite} return Access_Test_Suite is
      @b{Result} : Access_Test_Suite := AUnit.Test_Suites.New_Suite;
   begin
      @b{Result}.Add_Test (@b{This_Suite.Suite});
      @b{Result}.Add_Test (@b{That_Suite.Suite});
      return @b{Result};
   end @b{Suite};
end @b{Composite_Suite};}

@noindent
The harness remains the same:

@AEXP{with @b{Composite_Suite};
with AUnit.Run;

procedure @b{My_Tests} is
  procedure @b{Run} is new AUnit.Run.Test_Runner (@b{Composite_Suite.Suite});
  Reporter : AUnit.Reporter.Text.Text_Reporter;
begin
   @b{Run} (Reporter);
end @b{My_Tests};}

@noindent
As can be seen, this is a very flexible way of composing test cases
into execution runs: any combination of test cases and sub-suites can
be collected into a suite.

@c ======================================================================

@node Reporting
@chapter Reporting

Test results can be reported using several 'Reporters'. By default, two
reporters are available in AUnit:
@code{AUnit.Reporter.Text.Text_Reporter} and
@code{AUnit.Reporter.XML.XML_Reporter}. The first one is a simple
console reporting routine, while the second one outputs the result using
an XML format. These are invoked when the @code{Run} routine of an
instantiation of @code{AUnit.Run.Test_Runner} is called.

@noindent
New reporters can be created using children of
@code{AUnit.Reporter.Reporter}.

@noindent
The Reporter is selected by specifying it when calling @b{Run}:

@AEXP{with A_Suite;
with AUnit.Run;
@b{with AUnit.Reporter.Text;}

procedure My_Tests is
  procedure Run is new AUnit.Run.Test_Runner (A_Suite.Suite);
  @b{Reporter : AUnit.Reporter.Text.Text_Reporter;}
begin
   Run (@b{Reporter});
end My_Tests;}

The final report is output once all tests have been run, so that they can be
grouped depending on their status (passed or fail). If you need to output the
tests as they are run, you should consider extending the @code{Test_Result}
type and do some output every time a success or failure is registered.

@section Text output

Here is an example where the test harness runs 4 tests, one reporting an
assertion failure, one reporting an unexpected error (exception):

@smallexample
--------------------

   Total Tests Run: 4

   Successful Tests: 2
      Test addition
      Test subtraction

   Failed Assertions: 1

      Test addition (failure expected)
            Test should fail this assertion, as 5+3 /= 9
            at math-test.adb:29


   Unexpected Errors: 1

      Test addition (error expected)
            CONSTRAINT_ERROR



Time: 2.902E-4 seconds
@end smallexample

@cindex colors
This reporter can optionally use colors (green to report success, red to report
errors). Since not all consoles support it, this is off by default, but you can
call @code{Set_Use_ANSI_Colors} to activate support for colors.

@section XML output

Following is the same harness run using XML output. The XML format used
matches the one used by CppUnit.

Note that text set in the Assert methods, or as test case names should
be compatible with utf-8 character encoding, or the XML will not be
correctly formatted.

@smallexample
<?xml version='1.0' encoding='utf-8' ?>
<TestRun elapsed='1.107E-4'>
  <Statistics>
    <Tests>4</Tests>
    <FailuresTotal>2</FailuresTotal>
    <Failures>1</Failures>
    <Errors>1</Errors>
  </Statistics>
  <SuccessfulTests>
    <Test>
      <Name>Test addition</Name>
    </Test>
    <Test>
      <Name>Test subtraction</Name>
    </Test>
  </SuccessfulTests>
  <FailedTests>
    <Test>
      <Name>Test addition (failure expected)</Name>
      <FailureType>Assertion</FailureType>
      <Message>Test should fail this assertion, as 5+3 /= 9</Message>
      <Location>
        <File>math-test.adb</File>
        <Line>29</Line>
      </Location>
    </Test>
    <Test>
      <Name>Test addition (error expected)</Name>
      <FailureType>Error</FailureType>
      <Message>CONSTRAINT_ERROR</Message>
    </Test>
  </FailedTests>
</TestRun>
@end smallexample

@c ======================================================================

@node Test Organization
@chapter Test Organization

@menu
* General considerations::
* OOP considerations::
* Testing generic units::
@end menu

@c ---------------------------
@node General considerations
@section General considerations

This section will discuss an approach to organizing an AUnit test harness,
considering some possibilities offered by Ada language features.

The general idea behind this approach to test organization is that making the
test case a child of the unit under test gives some useful facilities.
The test case gains visibility to the private part of the unit under test.
This offers a more ``white box'' approach to examining the state of the unit
under test than would, for instance, accessor functions defined in a separate
fixture that is a child of the unit under test. Making the test case a child of
the unit under test also provides a way to make the test case share certain
characteristics of the unit under test.  For instance, if the unit under test
is generic, then any child package (here the test case) must be also generic:
any instantiation of the parent package will require an instantiation of the
test case in order to accomplish its aims.

Another useful concept is matching the test case type to that of the unit
under test:

@itemize
@item When testing a generic package, the test package should also be
generic.
@item When testing a tagged type, then test routines should be
dispatching, and the test case type for a derived tagged type should be a
derivation of the test case type for the parent.
@item etc.
@end itemize

Maintaining such similarity of properties between the test case and unit under
test can facilitate the testing of units derived in various ways.

The following sections will concentrate on applying these concepts to
the testing of tagged type hierarchies and to the testing of generic units.

A full example of this kind of test organization is available in the AUnit
installation directory: <AUnit-root>/share/examples/aunit/calculator, or
from the AUnit source distribution
aunit-@value{VERSION}-src/examples/calculator.

@c ---------------------------
@node OOP considerations
@section OOP considerations

When testing a hierarchy of tagged types, one will often want to run tests
for parent types against their derivations without rewriting those tests.

We will illustrate some of the possible solutions available in AUnit,
using the following simple example that we want to test:

First we consider a @code{Root} package defining the @code{Parent}
tagged type, with two procedures P1 and P2.

@AEXP{package Root is
   type Parent is tagged private;

   procedure P1 (P : in out Parent);
   procedure P2 (P : in out Parent);
private
   type Parent is tagged record
      Some_Value : Some_Type;
   end record;
end Root;}

We will also consider a derivation of type @code{Parent}:

@AEXP{with Root;
package Branch is
   type Child is new Root.Parent with private;

   procedure P2 (C : in out Child);
   procedure P3 (C : in out Child);
private
   type Child is new Root.Parent with null record;
end Branch;}

@noindent
Note that @code{Child} retains the parent implementation of @code{P1},
overrides @code{P2} and adds @code{P3}. Its test will override
@code{Test_P2} when we override @code{P2} (not necessary, but certainly
possible).

@subsection Using AUnit.Test_Fixtures

@noindent
Using @code{Test_Fixture} type, we first test @code{Parent} using the
following test case:
@AEXP{with AUnit; use AUnit;
with AUnit.Test_Fixtures; use AUnit.Test_Fixtures;

--  We make this package a child package of Parent so that it can have
--  visibility to its private part
package @b{Root.Tests} is

   type @b{Parent_Access} is access all @b{Root.Parent'Class};

   --  Reference an object of type Parent'Class in the test object, so
   --  that test procedures can have access to it.
   type @b{Parent_Test} is new Test_Fixture @b{with record}
      @b{Fixture : Parent_Access;}
   @b{end record};

   --  This will initialize P.
   procedure Set_Up (@b{P} : in out @b{Parent_Test});

   --  Test routines. If derived types are declared in child packages,
   --  these can be in the private part.
   procedure @b{Test_P1} (@b{P} : in out @b{Parent_Test});
   procedure @b{Test_P2} (@b{P} : in out @b{Parent_Test});

end @b{Root.Tests};

package body @b{Root.Tests} is

   @b{Fixture : aliased Parent;}

   --  We set Fixture in Parent_Test to an object of type Parent.
   procedure Set_Up (@b{P} : in out @b{Parent_Test}) is
   begin
      @b{P.Fixture := Parent_Access (Fixture'Access)};
   end Set_Up;

   --  Test routines: References to the Parent object are made via
   --  P.Fixture.all, and are thus dispatching.
   procedure @b{Test_P1} (@b{P} : in out @b{Parent_Test}) is ...;
   procedure @b{Test_P2} (@b{P} : in out @b{Parent_Test}) is ...;

end @b{Root.Tests};}

@noindent
The associated test suite will be:

@AEXP{with AUnit.Test_Caller;
with @b{Root.Tests};

package body @b{Root_Suite} is
   package @b{Caller} is new AUnit.Test_Caller with (@b{Root.Tests.Parent_Test});

   function Suite return AUnit.Test_Suites.Access_Test_Suite is
      @b{Ret} : Access_Test_Suite := AUnit.Test_Suites.New_Suite;
   begin
      AUnit.Test_Suites.Add_Test
        (@b{Ret}, Caller.Create (@b{"Test Parent : P1"}, @b{Root.Tests.Test_P1'Access}));
      AUnit.Test_Suites.Add_Test
        (@b{Ret}, Caller.Create (@b{"Test Parent : P2"}, @b{Root.Tests.Test_P2'Access}));
      return @b{Ret};
   end Suite;
end @b{Root_Suite};}

@noindent
Now we define the test suite for the @code{Child} type. To do this,
we inherit a test fixture from @code{Parent_Test},
overriding the @code{Set_Up} procedure to initialize @code{Fixture} with
a @code{Child} object. We also override @code{Test_P2} to adapt it
to the new implementation. We define a new @code{Test_P3} to test
@code{P3}. And we inherit @code{Test_P1}, since @code{P1} is unchanged.

@AEXP{with @b{Root.Tests}; use @b{Root.Tests};
with AUnit; use AUnit;
with AUnit.Test_Fixtures; use AUnit.Test_Fixtures;

package @b{Branch.Tests} is

   type @b{Child_Test} is new @b{Parent_Test} @b{with null record};

   procedure Set_Up (@b{C} : in out @b{Child_Test});

   --  Test routines:
   --  Test_P2 is overridden
   procedure @b{Test_P2} (@b{C} : in out @b{Child_Test});
   --  Test_P3 is new
   procedure @b{Test_P3} (@b{C} : in out @b{Child_Test});

end @b{Branch.Tests};

package body @b{Branch.Tests} is
   use Assertions;

   @b{Fixture : Child;}
   --  This could also be a field of Child_Test

   procedure Set_Up (@b{C} : in out @b{Child_Test}) is
   begin
      --  The Fixture for this test will now be a Child
      @b{C.Fixture := Parent_Access (Fixture'Access)};
   end Set_Up;

   --  Test routines:
   procedure @b{Test_P2} (@b{C} : in out @b{Child_Test}) is ...;
   procedure @b{Test_P3} (@b{C} : in out @b{Child_Test}) is ...;

end @b{Branch.Tests};}

The suite for Branch.Tests will now be:

@AEXP{with AUnit.Test_Caller;
with @b{Branch.Tests};

package body @b{Branch_Suite} is
   package @b{Caller} is new AUnit.Test_Caller with (@b{Branch.Tests.Parent_Test});

   --  In this suite, we use Ada 2005 distinguished receiver notation to
   --  simplify the code.

   function Suite return Access_Test_Suite is
      Ret : Access_Test_Suite := AUnit.Test_Suites.New_Suite;
   begin
      --  We use the inherited Test_P1. Note that it is
      --  Branch.Tests.Set_Up that will be called, and so Test_P1 will be run
      --  against an object of type Child
      @b{Ret}.Add_Test
        (@b{Caller}.Create (@b{"Test Child : P1"}, @b{Branch.Tests.Test_P1'Access}));
      --  We use the overridden Test_P2
      @b{Ret}.Add_Test
        (@b{Caller}.Create (@b{"Test Child : P2"}, @b{Branch.Tests.Test_P2'Access}));
      --  We use the new Test_P2
      @b{Ret}.Add_Test
        (@b{Caller}.Create (@b{"Test Child : P3"}, @b{Branch.Tests.Test_P3'Access}));
      return @b{Ret};
   end Suite;
end @b{Branch_Suite};}

@subsection Using AUnit.Test_Cases

@noindent
Using an @code{AUnit.Test_Cases.Test_Case} derived type, we obtain the
following code for testing @code{Parent}:

@AEXP{with AUnit; use AUnit;
with AUnit.Test_Cases;
package @b{Root.Tests} is

   type @b{Parent_Access} is access all @b{Root.Parent'Class};

   type @b{Parent_Test} is new AUnit.Test_Cases.Test_Case @b{with record}
      @b{Fixture : Parent_Access;}
   @b{end record};

   function Name (@b{P} : @b{Parent_Test}) return Message_String;
   procedure Register_Tests (@b{P} : in out @b{Parent_Test});

   procedure Set_Up_Case (@b{P} : in out @b{Parent_Test});

   --  Test routines. If derived types are declared in child packages,
   --  these can be in the private part.
   procedure @b{Test_P1} (@b{P} : in out @b{Parent_Test});
   procedure @b{Test_P2} (@b{P} : in out @b{Parent_Test});

end @b{Root.Tests};}

@noindent
The body of the test case will follow the usual pattern, declaring one or
more objects of type @code{@b{Parent}}, and executing statements in the
test routines against them.  However, in order to support dispatching to
overriding routines of derived test cases, we need to introduce class-wide
wrapper routines for each primitive test routine of the parent type that
we anticipate may be overridden. Instead of registering the parent's
overridable primitive operations directly using @code{Register_Routine},
we register the wrapper using @code{Register_Wrapper}. This latter routine
is exported by instantiating
@code{@b{AUnit}.Test_Cases.Specific_Test_Case_Registration} with the actual
parameter being the parent test case type.

@AEXP{with AUnit.Assertions; use AUnit.Assertions
package body @b{Root.Tests} is

   --  Declare class-wide wrapper routines for any test routines that will be
   --  overridden:
   procedure @b{Test_P1_Wrapper} (@b{P} : in out @b{Parent_Test}'Class);
   procedure @b{Test_P2_Wrapper} (@b{P} : in out @b{Parent_Test}'Class);

   function Name (@b{P} : @b{Parent_Test}) return Message_String is ...;

   --  Set the fixture in P
   @b{Fixture : aliased Parent;}
   procedure Set_Up_Case (@b{P} : in out @b{Parent_Test}) is
   begin
      @b{P.Fixture := Parent_Access (Fixture'Access)};
   end Set_Up_Case;

   --  Register Wrappers:
   procedure Register_Tests (@b{P} : in out @b{Parent_Test}) is

      package @b{Register_Specific} is
        new Test_Cases.Specific_Test_Case_Registration (@b{Parent_Test});

      use Register_Specific;

   begin
      Register_Wrapper (@b{P}, @b{Test_P1_Wrapper}'Access, @b{"Test P1"});
      Register_Wrapper (@b{P}, @b{Test_P2_Wrapper}'Access, @b{"Test P2"});
   end Register_Tests;

   --  Test routines:
   procedure @b{Test_P1} (@b{P} : in out Parent_Test) is ...;
   procedure @b{Test_P2} (@b{C} : in out Parent_Test) is ...;

   --  Wrapper routines. These dispatch to the corresponding primitive
   --  test routines of the specific types.
   procedure @b{Test_P1_Wrapper} (@b{P} : in out @b{Parent_Test}'Class) is
   begin
      @b{Test_P1} (@b{P});
   end @b{Test_P1_Wrapper};

   procedure @b{Test_P2_Wrapper} (@b{P} : in out @b{Parent_Test}'Class) is
   begin
      @b{Test_P2} (@b{P});
   end @b{Test_P2_Wrapper};

end @b{Root.Tests};}

@noindent
The code for testing the @code{Child} type will now be:

@AEXP{with @b{Parent_Tests}; use @b{Parent_Tests};
with AUnit; use AUnit;
package @b{Branch.Tests} is

   type @b{Child_Test} is new @b{Parent_Test} @b{with private};

   function Name (@b{C} : @b{Child_Test}) return Message_String;
   procedure Register_Tests (@b{C} : in out @b{Child_Test});

   --  Override Set_Up_Case so that the fixture changes.
   procedure Set_Up_Case (@b{C} : in out @b{Child_Test});

   --  Test routines:
   procedure @b{Test_P2} (@b{C} : in out @b{Child_Test});
   procedure @b{Test_P3} (@b{C} : in out @b{Child_Test});

private
   type @b{Child_Test} is new @b{Parent_Test} @b{with null record};
end @b{Branch.Tests};

with AUnit.Assertions; use AUnit.Assertions;
package body @b{Branch.Tests} is

   --  Declare wrapper for Test_P3:
   procedure @b{Test_P3_Wrapper} (@b{C} : in out @b{Child_Test}'Class);

   function Name (@b{C} : @b{Child_Test}) return Test_String is ...;

   procedure Register_Tests (@b{C} : in out @b{Child_Test}) is

      package @b{Register_Specific} is
         new Test_Cases.Specific_Test_Case_Registration (@b{Child_Test});
      use @b{Register_Specific};

   begin
      -- Register parent tests for P1 and P2:
      @b{Parent_Tests}.Register_Tests (@b{Parent_Test} (@b{C}));

      -- Repeat for each new test routine (Test_P3 in this case):
      @b{Register_Wrapper} (@b{C}, @b{Test_P3_Wrapper}'Access, @b{"Test P3"});
   end Register_Tests;

   --  Set the fixture in P
   @b{Fixture : aliased Child;}
   procedure Set_Up_Case (@b{C} : in out @b{Child_Test}) is
   begin
      @b{C.Fixture := Parent_Access (Fixture'Access)};
   end Set_Up_Case;

   --  Test routines:
   procedure @b{Test_P2} (@b{C} : in out @b{Child_Test}) is ...;
   procedure @b{Test_P3} (@b{C} : in out @b{Child_Test}) is ...;

   --  Wrapper for new routine:
   procedure @b{Test_P3_Wrapper} (@b{C} : in out @b{Child_Test}'Class) is
   begin
      @b{Test_P3} (@b{C});
   end @b{Test_P3_Wrapper};

end @b{Branch.Tests};}

@noindent
Note that inherited and overridden tests do not need to be explicitly
re-registered in derived test cases - one just calls the parent version of
@code{Register_Tests}. If the application tagged type hierarchy is organized
into parent and child units, one could also organize the test cases into a
hierarchy that reflects that of the units under test.

@c ---------------------------
@node Testing generic units
@section Testing generic units

When testing generic units, one would like to apply the same generic tests
to all instantiations in an application.  A simple approach is to make the
test case a child package of the unit under test (which then must also be
generic).

For instance, suppose the generic unit under test is a package (it could
be a subprogram, and the same principle would apply):
@AEXP{generic
   -- Formal parameter list
package Template is
   -- Declarations
end Template;}

@noindent
The corresponding test case would be:
@AEXP{with AUnit; use AUnit;
with AUnit.Test_Fixtures;
generic
package @b{Template.Gen_Tests} is

   type @b{Template_Test} is new AUnit.Test_Fixtures.Test_Fixture with @b{...};

   --  Declare test routines

end @b{Template.Gen_Tests};}

The body will follow the usual patterns with the fixture based on the
parent package @code{Template}. Note that due to an Ada AI, accesses to
test routines, along with the test routine specifications, must be defined
in the package specification rather than in its body.

Instances of @code{Template} will define automatically the Tests child
package that can be directly instantiated as follow:

@AEXP{with Template.Gen_Test;
with Instance_Of_Template;
package Instance_Of_Template.Tests is new Instance_Of_Template.Gen_Test;}

The instantiated test case objects are added to a suite in the usual manner.

@c =================================================================

@node Using AUnit with Restricted Run-Time Libraries
@chapter Using AUnit with Restricted Run-Time Libraries

@noindent
AUnit 3 - like AUnit 2 - is designed so that it can be used in
environments with restricted Ada run-time libraries, such as ZFP and the cert
run-time profile on Wind River Systems' VxWorks 653.  The patterns given in
this document for writing tests, suites and harnesses are not the only
patterns that can be used with AUnit, but they are compatible with the
restricted run-time libraries provided with GNAT Pro.

In general, dynamic allocation and deallocation must be used carefully in test
code.  For the cert profile on VxWorks 653, all dynamic allocation must be
done prior to setting the application partition into ``normal'' mode.
Deallocation is prohibited in this profile. For the default ZFP profile,
dynamic memory management is not provided as part of the run-time, as it is
not available on a bare board environment, and should not be used unless
you have provided implementations as described in the GNAT Pro High Integrity
User Guide.

Starting with AUnit 3, a simple memory management mechanism has been
included in the framework, using a kind of storage pool. This memory
management mechanism uses a static array allocated at startup, and simulates
dynamic allocation afterwards by allocating parts of this array upon request.
Deallocation is not permitted.

By default, the allocated array is a 100 KB array. This value can be changed
by modifying its size in the file:
@file{aunit-@value{VERSION}-src/aunit/framework/staticmemory/aunit-memory.adb}

To allocate a new object, you use @code{AUnit.Memory.Utils.Gen_Alloc}.

Additional restrictions relevant to the default ZFP profile include:
@enumerate
@item
Normally the ZFP profile requires a user-defined
@code{__gnat_last_chance_handler} routine
to handle raised exceptions. However, AUnit now provides a mechanism to
simulate exception propagation using gcc builtin setjmp/longjmp mechanism.
This mechanism defines the @code{__gnat_last_chance_handler} routine, so it
should not be redefined elsewhere.

@item
AUnit requires @code{GNAT.IO} provided in @file{g-io.ad?} in the full or cert
profile run-time library sources (or as implemented by the user). Since this
is a run-time library unit it must be compiled with the gnatmake ``-a''
switch.

@item
The AUnit framework has been modified so that no call to the secondary
stack is performed, nor any call to memcpy or memset. However, if the unit
under test, or the tests themselves require use of those routines, then the
application or test framework must define those symbols and provide the
requisite implementations.

@item
The timed parameter of the Harness @code{Run} routine has no effect when used
with the ZFP profile, and on profiles not supporting Ada.Calendar.
@end enumerate

@node Installation and Use
@chapter Installation and Use

@menu
* Note on gprbuild::
* aunit project file and support for other platforms/run-times::
* Installing AUnit on UNIX systems::
* Installing AUnit on Windows systems::
* Installing AUnit for customized run-times::
* Installed files::
@end menu

@noindent
AUnit 3 contains support for limited run-times such as zero-foot-print
(ZFP) and certified run-time (cert). It can now be installed simultaneously
for several targets and run-times.

@c --------------------------------------
@node Note on gprbuild
@section Note on gprbuild

@noindent
In order to compile and install AUnit, you need gprbuild. On
cross-platforms gprbuild version 1.1 or later is required, while on native
platforms any version can be used.

@c ---------------------------------------------------------
@node aunit project file and support for other platforms/run-times
@section aunit project file and support for other platforms/run-times

AUnit can be installed once for several targets and run-times.
To support this, the AUnit project includes scenario variables
to select those targets and/or run-times. The scenario variables
used are:
@itemize
@item @b{PLATFORM}: a free-form value used to differenciate installed libraries.
This value is set to "native" by default.
@item @b{RUNTIME}: the runtime used to compile AUnit. Many values are defined
there, you can have a look at the aunit_shared project for a comprehensive
list. This scenario variable is used to adapt the AUnit to the run-time profile.
Is set to "full" by default.
@end itemize

@c --------------------------------------
@node Installing AUnit on UNIX systems
@section Installing AUnit on UNIX systems

@noindent
@itemize
@item
Extract the archive:
@smallexample
   $ gunzip -dc aunit-@value{VERSION}-src.tgz | tar xf -
@end smallexample

@item
To build AUnit for a full Ada run-time:
@smallexample
   $ cd aunit-@value{VERSION}-src
   $ make
@end smallexample

To build AUnit for a zfp run-time targeting powerpc-elf platform@footnote{
Note that cross platforms require gprbuild version 1.1 or later}:
@smallexample
   $ cd aunit-@value{VERSION}-src
   $ make TARGET=powerpc-elf RTS=zfp
@end smallexample

For platforms providing a full Ravenscar run-time (eg. leon3-elf), or when
using ZFP for a native target, add the parameter below that excludes extra
ZFP support for builds using that library:
@smallexample
   $ cd aunit-@value{VERSION}-src
   $ make TARGET=powerpc-elf RTS=ravenscar NO_ZFP_SUPPORT=1
@end smallexample



Once the above build procedure has been performed for all
desired platforms, you can install AUnit:
@smallexample
   $ make install INSTALL=<gnat-root>
@end smallexample
   Where <gnat-root> is for example /opt/gnat/6.0.1. If INSTALL is not
specified, then AUnit will use the root directory where gprbuild is installed.

@item
Specific installation:

   The AUnit makefile supports some specific options, activated using
   environment variables. The following options are defined:

@itemize
@item @b{INSTALL}: defines the AUnit base installation directory, set to
gprbuild's base installation directory as found in the PATH.

@item @b{TARGET}: defines the gnat tools prefix to use. For example, to compile
AUnit for powerpc VxWorks, TARGET should be set to powerpc-wrs-vxworks. If not
set, the native compiler will be used.

@item @b{RTS}:  defines both the run-time used to compile AUnit and the value
given to the AUnit project as RUNTIME scenario variable.

@item @b{RTS_CONF}: defines the gprbuild Runtime config flag. The value is
set to "--RTS=$(RTS)" by default. Can be used when compiling AUnit for a
configurable run-time.
@end itemize

@item
To test AUnit:

   The AUnit test suite is in the test subdirectory of the source package.
@smallexample
   $ cd test
   $ make
@end smallexample
   The test suite's makefile supports the following variables:
   * RTS
   * TARGET
@end itemize

@c -----------------------------------------
@node Installing AUnit on Windows systems
@section Installing AUnit on Windows systems

On Windows, an InstallShield wizard is available to easily install AUnit.

The InstallShield will go through the following steps:

@itemize

@item
Selection of the GNAT compiler to consider: this page allows you to select
which GNAT compiler to use to compile AUnit.

@item
Selection of the directory used to install AUnit: by default the same directory
as the GNAT compiler.

@item
Selection of targets: the InstallShield will try to detect all GNAT compilers
available on your system. You can then select the compilers/runtimes that you
want AUnit installed for.

@item
At this stage, the AUnit library starts compiling. And is then installed in the
destination directory.
@end itemize

Note that in contrast to the AUnit 2 installation procedures, support for
exception handling, memory allocation and Ada.Calendar is automatically
selected depending on the run-times used.

@c -----------------------------------------------
@node Installing AUnit for customized run-times
@section Installing AUnit for customized run-times

@noindent
The AUnit library can also be compiled for custom-built run-times. To do so,
you can either use the Makefile (@pxref{Installing AUnit on UNIX systems}) or
use directly the project aunit_build.gpr that is installed in <prefix>/lib/gnat.

To use the Makefile, you will need to specify RTS_CONF so that the correct
parameter is passed to gprbuild. For example, if your custom run-time is
powerpc-elf/ravenscar-full-prep, then you need to use the command:

@smallexample
make TARGET=powerpc-elf RTS=ravenscar-full \
  RTS_CONF=--RTS=powerpc-elf/ravenscar-full-prep
@end smallexample

If AUnit comes pre-installed or you can't use the Makefile, then you can also
directly use the aunit_build.gpr project file to compile and use AUnit.

@smallexample
gprbuild --target=powerpc-elf --RTS=powerpc-elf/ravenscar-full-prep \
  -XPLATFORM=powerpc-elf -XRUNTIME=ravenscar-full -Paunit_build -p
@end smallexample

The aunit_build project will install the AUnit library in <prefix>/lib/aunit/<TARGET>-<RUNTIME> and use the object directory <prefix>/lib/aunit-obj/<TARGET>-<RUNTIME>.

If the AUnit installation directory is readonly, you can override those paths
 by setting the LIBDIR and OBJDIR scenario variables. Note that you still need
 to provide the RUNTIME scenario variable in this case, but PLATFORM can be
 omitted:

@smallexample
gprbuild --target=powerpc-elf --RTS=powerpc-elf/ravenscar-full-prep \
  -XRUNTIME=ravenscar-full LIBDIR=$HOME/aunit-lib OBJDIR=/tmp -Paunit_build
@end smallexample

Once built this way, the object directory can safely be removed, and you can
use the regular aunit project to build your test suites.

@c ---------------------
@node Installed files
@section Installed files

@noindent
The AUnit library is installed in the specified directory (<aunit-root>
identifies the root installation directory as specified during the installation
procedures above):

@itemize
@item
   the aunit.gpr project is installed in <aunit-root>/lib/gnat
@item
   the AUnit source files are installed in <aunit-root>/include/aunit
@item
   the AUnit library files are installed in <aunit-root>/lib/aunit
@item
   the AUnit documentation is installed in <aunit-root>/share/doc/aunit
@item
   the AUnit examples are installed in <aunit-root>/share/examples/aunit
@end itemize

@node GPS Support
@chapter GPS Support

@noindent
GPS IDE relies on gnattest tool that creates unit-test skeletons as well as
a test driver infrastructure (harness). Harness can be generated for project
hierarchy, single project or a package. Generation process can be launched
from @b{Tools -> GNATtest} menu or from contextual menu.

@bye
