1.. |nbsp| unicode:: 0xA0
2   :trim:
3
4.. _Overview:
5
6********
7Overview
8********
9
10How do you write testing code?
11
12The simplest approach is as an expression in a debugger. You can change
13debug expressions without recompiling, and you can wait to decide
14what to write until you have seen the running objects. You can also
15write test expressions as statements that print to the standard
16output stream. Both styles of tests are limited because they require
17human judgment to analyze their results. Also, they don't compose
18nicely - you can only execute one debug expression at a time and a
19program with too many print statements causes the dreaded "Scroll
20Blindness".
21
22AUnit tests do not require human judgment to interpret, and it is
23easy to run many of them at the same time. When you need to test
24something, here is what you do:
25
26.. index:: AUnit.Simple_Test_Cases.Test_Case type
27.. index:: AUnit.Test_Cases.Test_Case type
28.. index:: AUnit.Test_Fixtures.Test_Fixture type
29
30* Derive a test case type from ``AUnit.Simple_Test_Cases.Test_Case``.
31
32  Several test case types are available:
33
34  * ``AUnit.Simple_Test_Cases.Test_Case``: the base type for all test
35    cases. Needs overriding of ``Name`` and ``Run_Test``.
36  * ``AUnit.Test_Cases.Test_Case``: the traditional AUnit test case type,
37    allowing multiple test routines to be registered, where each one is run
38    and reported independently.
39  * ``AUnit.Test_Fixtures.Test_Fixture``: used together with
40    ``AUnit.Test_Caller``, this allows easy creation of test suites comprising
41    several test cases that share the same fixture (see :ref:`Fixture`).
42
43  See :ref:`Test_Case` for simple examples of using these types.
44
45* When you want to check a value [#]_ use one of the following Assert [#]_ methods:
46
47  .. [#] While :index:`JUnit` and some other
48     members of the xUnit family of unit test frameworks provide specialized forms
49     of assertions (e.g. `assertEqual`), we took a design decision in AUnit
50     not to provide such forms.  Ada has a much richer type system giving a
51     large number of possible scalar types, and leading to an explosion of possible
52     special forms of assert routines.  This is exacerbated by the lack of a single
53     root type for most types, as is found in Java.  With the introduction of
54     AUnit |nbsp| 2 for use with restricted run-time profiles, where even ``'Image`` is
55     missing, providing a comprehensive set of special assert routines in the
56     framework itself becomes even more unrealistic. Since AUnit is intended to
57     be an extensible toolkit, users can certainly write their own custom
58     collection of such assert routines to suit local usage.
59
60  .. index::
61     see: Assert subprogram; AUnit.Assertions.Assert
62
63  .. [#] Note that in AUnit |nbsp| 3, and contrary to
64     AUnit |nbsp| 2, the procedural form of `Assert` has the same behavior whatever
65     the underlying Ada run-time library: a failed assertion will cause the
66     execution of the calling test routine to be abandoned. The functional form of
67     `Assert` always continues on a failed assertion, and provides you
68     with a choice of behaviors.
69
70  .. index:: AUnit.Assertions.Assert
71
72  .. code-block:: ada
73
74     AUnit.Assertions.Assert (Boolean_Expression, String_Description);
75
76  or:
77
78  .. code-block:: ada
79
80     if not AUnit.Assertions.Assert (Boolean_Expression, String_Description) then
81       return;
82     end if;
83
84  .. index:: Assert_Exception subprogram
85
86  If you need to test that a subprogram raises an expected exception, there
87  is the procedure ``Assert_Exception`` that takes an access value designating the procedure
88  to be tested as a parameter:
89
90  .. code-block:: ada
91
92     type Throwing_Exception_Proc is access procedure;
93
94     procedure Assert_Exception
95     (Proc    : Throwing_Exception_Proc;
96     Message : String;
97     Source  : String := GNAT.Source_Info.File;
98     Line    : Natural := GNAT.Source_Info.Line);
99     --  Test that Proc throws an exception and record "Message" if not.
100
101
102  Example:
103
104  .. code-block:: ada
105
106     -- Declared at library level:
107     procedure Test_Raising_Exception is
108     begin
109       call_to_the_tested_method (some_args);
110     end Test_Raising_Exception;
111
112     -- In test routine:
113     procedure My_Routine (...) is
114     begin
115       Assert_Exception (Test_Raising_Exception'Access, **String_Description**);
116     end My_Routine;
117
118  This procedure can handle exceptions with all run-time profiles (including
119  zfp).  If you are using a run-time library capable of propagating exceptions,
120  you can use the following idiom instead:
121
122  .. code-block:: ada
123
124     procedure My_Routine (...) is
125     begin
126       ...
127       -- Call subprogram expected to raise an exception:
128       Call_To_The_Tested_Method (some_args);
129       Assert (False, 'exception not raised');
130     exception
131       when desired_exception =>
132         null;
133     end My_Routine;
134
135  An unexpected exception will be recorded as such by the framework.  If you want
136  your test routine to continue beyond verifying that an expected exception has
137  been raised, you can nest the call and handler in a block.
138
139.. index:: ZFP profile
140.. index:: cert profile
141.. index:: AUnit.Memory.Utils.Gen_Alloc
142.. index:: AUnit.Test_Caller.Create
143.. index:: AUnit.Test_Suites.New_Suite
144
145* Create a suite function inside a package to gather together test cases
146  and sub-suites. (If either the ZFP or the cert run-time profiles ia being
147  used, test cases and suites must be allocated using
148  ``AUnit.Memory.Utils.Gen_Alloc``, ``AUnit.Test_Caller.Create``,
149  ``AUnit.Test_Suites.New_Suite``, or else they must be statically allocated.)
150
151.. index:: AUnit.Run.Test_Runner
152.. index:: AUnit.Run.Test_Runner_With_Status
153
154* At any level at which you wish to run tests, create a harness by
155  instantiating procedure ``AUnit.Run.Test_Runner`` or function
156  ``AUnit.Run.Test_Runner_With_Status`` with the top-level suite
157  function to be executed. This instantiation provides a routine
158  that executes all of the tests in the suite. We will call this
159  user-instantiated routine `Run` in the text for backward compatibility
160  with tests developed for AUnit |nbsp| 1. Note that only one instance of `Run`
161  can execute at a time.  This is a tradeoff made to reduce the stack requirement
162  of the framework by allocating test result reporting data structures
163  statically.
164
165
166  .. index::
167     see: Test_Runner; AUnit.Run.Test_Runner
168
169  .. index:: ZFP profile
170
171  It is possible to pass a filter to a `Test_Runner`, so that only a
172  subset of the tests run. In particular, this filter could be initialized from
173  a command line parameter. See the package ``AUnit.Test_Filters`` for an
174  example of such a filter. AUnit does not automatically initialize this filter
175  from the command line both because it would not be supported with some of the
176  limited run-time profiles (ZFP for instance), and because you might want to
177  pass the argument in different ways (as a parameter to switch, or a stand-alone
178  command line argument for instance).
179
180  .. index:: AUnit.Options package
181
182  It is also possible to control the contents of the output report by passing an
183  object of type ``AUnit_Options`` to the `Test_Runner`. See package
184  ``AUnit.Options`` for details.
185
186* Build the code that calls the harness `Run` routine using
187  `gnatmake` or `gprbuild`. The GNAT project file :file:`aunit.gpr` contains all
188  necessary switches, and should be imported into your root project file.
189
190
191