Testing
| Hand assert subroutine | |
| Table cases | |
| Run with a script | |
| Red green habit |
Hand assert subroutine
A test module with one check subroutine is enough to start. It prints PASS for good cases and stops with FAIL for bad ones. Keep the module in its own file and reuse it in every test program.
module tiny_test
implicit none
contains
subroutine check(ok, name)
implicit none
logical, intent(in) :: ok
character(len=*), intent(in) :: name
if (ok) then
write(*, "(a)") "PASS: " // name
else
write(*, "(a)") "FAIL: " // name
error stop "test failed"
end if
end subroutine check
end module tiny_test
Table cases
Table driven tests store inputs and answers in arrays and loop over them. Adding a case means adding one array element, not new code. Put the function under test in the contains section while it is small.
program test_twice
use tiny_test
implicit none
integer :: want(4) = [2, 4, 6, 8]
integer :: i
do i = 1, size(want)
call check(twice(i) == want(i), "twice")
end do
contains
integer function twice(k)
implicit none
integer, intent(in) :: k
twice = 2 * k
end function twice
end program test_twice
Run with a script
Compile the module with the test program and run the result. Two commands give a full test run with no tools to install. Save them in a small shell script and rerun after every change.
gfortran -Wall -Wextra tiny_test.f90 test_twice.f90 -o test_twice
./test_twice
sh run_tests.sh
PASS: twice PASS: twice PASS: twice PASS: twice
Red green habit
Work in a red green habit: watch a new test fail, make it pass, then clean up. A failing run proves the test can catch the bug. Never skip the red step or a passing test may prove nothing. The error stop line ends the run with a nonzero code, so scripts notice the failure.
FAIL: twice ERROR STOP test failed
Next: Build with gfortran and make
Article author: Arthur Isaev