# 4. Fixture

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:

- Create a Test Case package as in previous section.

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

- According to the Test_Case type used, override its `Set_Up` and/or `Set_Up_Case` subprogram:

  - `AUnit.Simple_Test_Cases`: `Set_Up` is called before `Run_Test`.

  - `AUnit.Test_Cases`: `Set_Up` is called before each test routine while `Set_Up_Case` is called once before the routines are run.

  - `AUnit.Test_Fixtures`: `Set_Up` is called before each test case created using `Aunit.Test_Caller`.

- You can also override `Tear_Down` and/or `Tear_Down_Case` that are executed after the test is run.

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:

    with AUnit; use AUnit;
    package Money_Tests is
       use Test_Results;

       type Money_Test is new Test_Cases.Test_Case with null record;

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

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

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

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

The body becomes:

    package body Money_Tests is
       use Assertions;

       -- Fixture elements

       EU_12, EU_14 : Euro;
       US_26        : US_Dollar;

       -- Preparation performed before each routine

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

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

       -- Register test routines to call
       procedure Register_Tests (T: in out Money_Test) is
          use Test_Cases.Registration;
       begin
          -- Repeat for each test routine:
          Register_Routine (T, Test_Simple_Add'Access, "Test Addition");
       end Register_Tests;

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

    end Money_Tests;

Once you have the fixture in place, you can write as many test routines as you like. Calls to `Set_Up` and `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 `AUnit.Test_Fixtures` in your AUnit installation directory: `<aunit-root>/share/examples/aunit/test_fixture/` or from the AUnit source distribution `aunit-<version>-src/examples/test_fixture/`.