Unit Testing
uEMEP uses a custom unit testing system, which is inspired by neural-fortran, and is integrated with cmake and ctest. Unit tests are stored in the test directory.
Writing tests
The unit testing system are simple Fortran programs and should not have any external dependencies. They have the following overall structure:
program test_example_module
use example_module
implicit none
! Variables
logical :: ok = .true. ! Overall test suite check
real :: expected, result ! Individual test check
real :: test_par ! Test parameter
! Test case 1: Expected return value
test_par = 2.0
expected = 42.0
result = example_function(test_par)
if (abs(expected - result) >= 1.0e-5) then
ok = .false.
print "(a)", "Test case 1 failed!"
end if
! Return test summary
if (ok) then
print "(a)", "test_example_module: All tests passed."
else
print "(a)", "test_example_module: One or more tests failed."
stop 1
end if
end program test_example
Including tests in the build system
By default, unit tests are build automatically when uEMEP is compiled. To add a new unit test to the build system, add the unit test filename, excluding the test_ prefix in the foreach loop in ./test/CMakeLists.txt.
foreach(execid
utility_functions
read_namefile_routines
time_functions
uemep_logger
io_functions
)
add_executable(test_${execid} test/test_${execid}.f90)
target_link_libraries(test_${execid} PRIVATE uemeplib ${NETCDF_LIBRARIES})
add_test(NAME test_${execid} COMMAND test_${execid})
endforeach()
The new unit test will then be built the next time uEMEP is compiled.
Running tests
Run the unit tests from the build directory as:
# Run all unit tests
make test
In addition, as each unit test is a standalone fortran program, unit tests can also be run individually, e.g.:
# Run units tests for a single module
./test_io_functions