Ada: AUnit
This article describes how to use
AUnit, a unit test framework for Ada, and
GNATtest, a tool for creating test scaffolds.
An overview of AUnit can be found in the AUnit cookbook. GNATtest is described in the GNATtest user guide.
Installation
AUnit
Check out the GitHub repository and compile.
git clone https://github.com/AdaCore/aunit.git
cd aunit
make
Next, install.
make install
Note
On some systems gprbuild needs to be called with an -aP flag: gprbuild -aP /usr/share/gpr. Alternatively, if you use an Ailre-based workflow, you might use the Alire installation as the root directory: make install INSTALL=~/.alire.
GNATtest
alr install gnattest
Assertions
Assert
To use the following examples outside a test harness generated with GNATtest you need to add with "aunit"; to your project’s .gpr file.
with "aunit";
project Hello is
for Languages use ("Ada");
for Source_Dirs use ("src");
for Object_Dir use "build";
for Main use ("main.adb");
package Compiler is
for Switches ("Ada") use ("-g", "-gnat2022", "-gnatw.e", "-gnatw.Y", "-gnatw.N");
end Compiler;
end Hello;
At the lowest level, a unit test consists of assertions. To this end, AUnit provides the procedure AUnit.Assertions.Assert.
-- src/main.adb
with AUnit.Assertions; use AUnit.Assertions;
procedure Main is
begin
Assert (
True, -- Expected : Boolean
"should not be false"); -- Message : String
end Main;
Assert_Exception
To ensure that an exception is raised, we use the procedure Assert_Exception.
-- src/lib.ads
package Lib is
My_Exception : exception;
procedure Proc;
end Lib;
-- src/lib.adb
package body Lib is
procedure Proc is
begin
raise My_Exception with "This has gone very wrong.";
end Proc;
end Lib;
Next we alter our main.adb source file like so:
-- src/main.adb
with AUnit.Assertions; use AUnit.Assertions;
with Lib; use Lib;
procedure Main is
begin
Assert_Exception (
Proc'Access, -- Procedure
"should raise exception", -- Message : String
"lib.adb", -- Source : String (optional)
5); -- Line : Natural (optional)
end Main;
Test Fixture
The central concept in AUnit is a test fixture. We create a test fixture by extending the class AUnit.Test_Fixtures.Test_Fixture.
This class allows us to overwrite two base operation procedures:
Set_UpTear_Down
We use both to alter the state of the test fixture object. In addition, a test fixture can have more base operation procedures each implementing a test.
GNATtest
Instead of setting up a test fixture by hand, we use the tool GNATtest to create a test scaffold. Part of that scaffold is a test harness that allows us to run the tests.
We create the scaffold assuming the project is described in hello.gpr.
gnattest -Phello --subdirs=tests
This creates a directory for the test scaffold in ./src/tests and a directory for the test harness in ./build/gnattest/harness.
We build the test harness using the generated Makefile. This creates an executable test_runner.
cd build/gnattest/harness
make
./test_runner
GNU Make Workflow
-- Makefile
PROJECT := hello
HARNESS := build/gnattest/harness
.PHONY: all
all:
gprbuild -P$(PROJECT)
.PHONY: clean
clean:
$(RM) -r build
$(RM) -r lib
.PHONY: test
test: $(HARNESS)
(cd $^ && make && ./test_runner)
$(HARNESS):
gnattest -P$(PROJECT) --subdirs=tests