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