The Fortuno (Fortran Unit Testing Objects) project offers a flexible, extensible, object oriented unit testing framework for the Fortran language. It puts strong emphasis on the simplicity of the user interface by minimizing the amount of boiler plate code when writing unit tests, as well as to modularity and extensibility by offering building blocks for customized unit testing systems.
Fortuno provides
- simple unit tests,
- fixtured tests,
- parametrized tests,
- serial unit testing,
- parallel unit testing for MPI- and coarray-parallel projects, and
- integration with the fpm, CMake and Meson build systems.
Documentation is available on the Fortuno documentation page. You can also have a look at the examples in the example folder.
The development can be followed and joined at the Fortuno project page on GitHub.
If you want to start a new project utilizing the Fortuno unit testing framework, use the Cookiecutter-Fortran-project template generator to obtain a minimal, ready to build, test and install project with selectable build system (CMake, Fpm or Meson) and Fortuno integration.
If you wish to add Fortuno unit tests to an already existing project, follow the
instructions below. In the examples it will be assumed that your library has a
module mylib
, which provides a function factorial()
for calculating the
factorial of integers. Adapt those names to your actual library and routine
names.
The easiest way to obtain Fortuno is to download and build it as part of your project's build process. The actual steps depend on your build system:
fpm: Register Fortuno as a development dependency by adding the following lines to your
fpm.toml
file:[dev-dependencies] fortuno = { git = "https://github.com/fortuno-repos/fortuno" }
CMake: Add the following snippet to the
CMakeLists.txt
file in the root folder of your project:include(FetchContent) FetchContent_Declare( Fortuno GIT_REPOSITORY "https://github.com/fortuno-repos/fortuno" GIT_TAG "main" ) FetchContent_MakeAvailable(Fortuno)
Meson: Create the file
fortuno.wrap
in thesubprojects/
folder of your project (create the folder, if it does not exist yet) with following content:[wrap-git] directory=fortuno url=https://github.com/fortuno-repos/fortuno revision=main
Register Fortuno as a subproject by adding the following to your main
meson.build
file:fortuno_serial_dep = dependency('fortuno-serial', fallback: ['fortuno', 'fortuno_serial_dep'])
For the basic cases, Fortuno unit tests are plain subroutines without any arguments. Apart of your test routines, you only need a minimal amount of code to register them in the test framework and to provide access to them via a command line test driver app.
Given the hypothetical library mylib
providing the function factorial()
,
the minimal test program checking the results for two different input values
could look as follows:
! file: testapp.f90 !> Test app driving Fortuno unit tests. program testapp use mylib, only : factorial use fortuno_serial, only : execute_serial_cmd_app, is_equal, test => serial_case_item,& & check => serial_check implicit none ! Register tests by providing name and subroutine to run for each test. ! Note: this routine does not return but stops the program with the right exit code. call execute_serial_cmd_app(& testitems=[& test("factorial_0", test_factorial_0),& test("factorial_1", test_factorial_1)& ]& ) contains ! Test: 0! = 1 subroutine test_factorial_0() call check(factorial(0) == 1) end subroutine test_factorial_0 ! Test: 1! = 1 ! This routine uses is_equal() for comparison in order to obtain detailed ! information in case of a failure. subroutine test_factorial_1() call check(is_equal(factorial(1), 1)) end subroutine test_factorial_1 end program testapp
In order to run the unit tests, you must first build the test driver app with your build system:
fpm: If you stored the test-driver app source
testapp.f90
in thetest/
folder, fpm will automatically compile it and link it with the Fortuno library when you build your project withfpm build
CMake: Declare an executable
testapp
withtestapp.f90
as source and targetFortuno::fortuno_serial
as dependency in theCMakeLists.txt
file. Add also the target name of your library (e.g.mylib
) as dependency. Additionally, register the executable as a test, so that it can be executed viactest
:add_executable(testapp testapp.f90) target_link_libraries(testapp PRIVATE mylib Fortuno::fortuno_serial) add_test(NAME factorial COMMAND testapp)
Make also sure to call
enable_testing()
in your mainCMakeLists.txt
file before the rules fortestapp
are processed, so that you can usectest
for the testing.Now configure and build your project as usual:
cmake -B _build cmake --build _build
Meson: Declare an executable
testapp
withtestapp.f90
as source andfortuno_serial_dep
as dependency in themeson.build
file. Add also your library (e.g.mylib_dep
) as dependency:testapp_exe = executable( 'testapp', sources: ['testapp.f90'], dependencies: [mylib_dep, fortuno_serial_dep], ) test('factorial', testapp_exe)
Build your project as usual:
meson setup _build ninja -C _build
You run the units tests by executing the test app via the testing feature of your build system:
fpm:
fpm test
CMake:
ctest --verbose --test-dir _build
Meson:
meson test -v -C _build
The result is communicated via the testapp's exit code to the build framework (zero for success, and non-zero for failure). Additionally, Fortuno logs details to the console:
=== Fortuno - extensible unit testing framework for Fortran === # Executing test items .. # Test runs Total: 2 Succeeded: 2 (100.0%) === Succeeded ===
Check out the Fortuno documentation for more detailed explanations, further features and use cases.
In order to offer a simple user interface and to allow for maximal reusability and extensibility, Fortuno uses modern Fortran constructs extensively. Building Fortuno requires a compiler with Fortran 2018 support. The following table gives an overview over the compilers which were successfully tested for building Fortuno. We recommend to use those compilers or any newer versions of them.
Compiler | Status |
---|---|
Intel 2024.0 [1] |
|
NAG 7.2 (build 7202) |
|
GNU 13.2, 14.1 |
|
If you are aware of any other compilers being able to build Fortuno, please, open a pull request to update the table.
- Please ensure you are using Intel 2024.0, as newer versions (2024.1 and 2024.2) have a confirmed compiler bug that creates an incorrect binary, leading to segmentation faults due to the loss of pointer association status. For more details, refer to the Intel community discussion.
Fortuno is licensed under the BSD-2-Clause Plus Patent License. This OSI-approved license combines the 2-clause BSD license with an explicit patent grant from contributors. The SPDX license identifier for this project is BSD-2-Clause-Patent.