. ├── fruit │ └── fruit.f90 ├── mod ├── src │ └── main │ └── <your_module>.f90 └── test ├── <your_module>_test.f90 └── fruit_driver.f90 |
module load itm-gcc/7.3.0 |
Download fruit.f90 https://github.com/mortele/FRUIT/blob/master/src/fruit.f90 into .<project_dir>/fruit directory.
cd <project_dir>/fruit wget https://raw.githubusercontent.com/mortele/FRUIT/master/src/fruit.f90 |
NOTE: While compiling fruit.f90 an error "Logicals must be compared with .eqv. instead of .eq." may occure. In this case you will need to modify fruit.f90 lines 912 and 913 editing ".eq." to ".eqv.".
Create file named <your_module>_test.f90 and put it into ./test directory.
This is you file that contains unit tests for your program.
!file: <project_dir>/test/calculator_test.f90 module calculator_test use fruit contains subroutine test_calculator !use <your_module_name> use calculator integer :: result !test add subroutine call add (2,2,result) call assert_equals(4,result) end subroutine test_calculator end module calculator_test |
Create file named fruit_driver.f90. It will call your tests and handle fruit init and summary. You will need to modify it everytime you add new tests.
!file: <project_dir>/test/fruit_driver.f90 program fruit_driver use fruit use calculator_test call init_fruit !if you want to generate XML result !call init_fruit_xml call test_calculator !call fruit_summary_xml call fruit_summary end program fruit_driver |
Create file named <your_module>.f90 and put it into ./src directory. This file will be tested by module created in step 3.1.
!file: <project_dir>/src/calculator.f90 module calculator implicit none contains subroutine add(a,b,output) integer, intent (in) :: a,b integer, intent (out) :: output output=a+b end subroutine add end module calculator |
Create file named main.f90 and put it into ./src directory. We won't use this file, but it is needed to compile and build calculator executable.
!file: <project_dir>/src/main.f90 program main use calculator integer :: result call add(2,2,result) end program main |
This directory will contains built modules. Unlikely GNU make will not create it itself.
cd <project_dir> mkdir mod |
It is a build instruction that makes compiling your project easy.
To use this code without modification you will need to follow convention:
Otherwise you will need to modify some of it's lines.
#file: <project_dir>/Makefile C=gfortran -O3 FFLAGS=-c -J ./mod OBJS=$(patsubst %.f90,%.o,$(wildcard src/*.f90)) TESTED_OBJS=$(filter-out src/main.o, $(OBJS)) TESTS=$(patsubst %.f90,%.o,$(wildcard test/*test.f90)) LIB=$(patsubst %.f90,%.o,$(wildcard fruit/*.f90)) DRIVER_SOURCE=test/fruit_driver.f90 DRIVER_OBJ=$(patsubst %.f90,%.o, $(DRIVER_SOURCE)) all: run run: $(OBJS) @echo "Building executable" $(FC) $(OBJS) -o $@ $(OBJS): src/%.o: src/%.f90 @echo "Compiling objects" $(FC) $(FFLAGS) $< -o $@ test: fruit/fruit.o $(TESTED_OBJS) $(TESTS) $(DRIVER_OBJ) @echo "Building executable" $(FC) $^ -o run_test $(TESTS): test/%.o: test/%.f90 @echo "Compiling tests" $(FC) $(FFLAGS) $< -o $@ $(DRIVER_OBJ): $(DRIVER_SOURCE) @echo "Compiling driver" $(FC) $(FFLAGS) $< -o $@ fruit/fruit.o: fruit/fruit.f90 @echo "Compiling FRUIT library" $(FC) $(FFLAGS) $< -o $@ clean: rm mod/*.mod -f rm src/*.o -f rm test/*.o -f rm fruit/*.o -f rm run -f |
cd <project_dir> #to compile and run tests make test ./run_test #to clean after build make clean #to compile and run you program without tests make ./run |
NOTE: This step is optional and is needed to be done only if you want to use setup and teardown subroutines.
NOTE: Using setup and teardown subroutines with this library is complex and unellegant. Consider using another framework or FRUIT+Ruby version.
First you need to define setup and teardown subroutines.
!file: <project_dir>/test/calculator_test.f90 module calculator_test use fruit contains subroutine setup !... end subroutine setup subroutine teardown !... end subroutine teardown subroutine test_calculator use calculator integer :: result !test add subroutine call add (2,2,result) call assert_equals(4,result) end subroutine test_calculator end module calculator_test |
Basket file handles setup and teardown subroutines calls and also captures responsibility of running tests from test_driver module. It should be created in ./test directory.
!file: <project_dir>/test/fruit_basket.f90 module fruit_basket use fruit contains subroutine calculator_test_all_tests use calculator_test call setup write (*, *) " ..running test: test_calculator" call set_unit_name('test_calculator') call run_test_case (test_calculator, "test_calculator") if (.not. is_case_passed()) then write(*,*) write(*,*) ' Un-satisfied spec:' write(*,*) ' -- calculator' write(*,*) call case_failed_xml("test_calculator", & & "calculator_test") else call case_passed_xml("test_calculator", & & "calculator_test") end if call teardown end subroutine calculator_test_all_tests subroutine fruit_basket1 call calculator_test_all_tests end subroutine fruit_basket1 end module fruit_basket |
Pay attention to code lines presented below. They come from code above. You can use them to call tests from desired test module.
call set_unit_name('test_calculator') call run_test_case (test_calculator, "test_calculator") |
Now test subroutines calls are moved from test_driver to test_basket. You need to import test_basket module and call it's main subroutine. In this case it is "fruit_basket" subroutine.
!file: <project_dir>/test/fruit_driver.f90 program fruit_driver use fruit use fruit_basket call init_fruit call fruit_basket1 call fruit_summary end program fruit_driver |
Add lines presented below at the end of the Makefile.
test/fruit_basket.o: test/fruit_basket.f90 @echo "Compiling FRUIT basket file" $(FC) $(FFLAGS) $< -o $@ |
Also you need to modify this line:
test: fruit/fruit.o $(TESTED_OBJS) $(TESTS) $(DRIVER_OBJ) |
as follows:
test: fruit/fruit.o $(TESTED_OBJS) $(TESTS) test/fruit_basket.o $(DRIVER_OBJ) |
NOTE: FRUIT prints "." for every assert passed and "F" for every assert failed, not for every procedure call.
NOTE: Screenshoot below contains list of failed assertions and messages defined by user as optional assert subroutine argument.
The scientific work is published for the realization of the international project co-financed by Polish Ministry of Science and Higher Education in 2019 from financial resources of the program entitled "PMW"; Agreement No. 5040/H2020/Euratom/2019/2
This work has been carried out within the framework of the EUROfusion Consortium and has received funding from the Euratom research and training programme 2014–2020 under grant agreement No 633053. The views and opinions expressed herein do not necessarily reflect those of the European Commission or ITER