diff --git a/docs/source/testing/unit_test.rst b/docs/source/testing/unit_test.rst index ab24a06fe8..e8bfd3f9e7 100644 --- a/docs/source/testing/unit_test.rst +++ b/docs/source/testing/unit_test.rst @@ -14,8 +14,8 @@ This framework provides a Fortran abstraction to the popular along with OpenFAST through CMake when the CMake variable ``BUILD_TESTING`` is turned on. -The BeamDyn module has been unit tested and should serve as a reference for -future development and testing. +The BeamDyn and NWTC Library modules contain some sample unit tests and should +serve as a reference for future development and testing. Dependencies ------------ @@ -38,7 +38,7 @@ framework named ``[module]_utest``. Then, ``make`` the target to test: make beamdyn_utest This creates a unit test executable at -``openfast/build/unit_tests/beamdyn_utest``. +``openfast/build/unit_tests/beamdyn/beamdyn_utest``. Executing --------- @@ -46,7 +46,7 @@ To execute a module's unit test, simply run the unit test binary. For example: .. code-block:: bash - >>>$ ./openfast/build/unit_tests/beamdyn_utest + >>>$ ./openfast/build/unit_tests/beamdyn/beamdyn_utest ............. Time: 0.018 seconds @@ -60,7 +60,7 @@ the failure. Failure cases display the following output: .. code-block:: bash - >>>$ ./unit_tests/beamdyn_utest + >>>$ ./unit_tests/beamdyn/beamdyn_utest .....F....... Time: 0.008 seconds @@ -91,27 +91,31 @@ or function). What is testable is the discretion of the developer, but an element of the pull request review process will be evaluating test coverage. New unit tests can be added to a ``tests`` directory alongside the ``src`` -directory included in each module. For example, the BeamDyn module directory is +directory included in each module. For example, a module directory may be structured as :: openfast/ └── modules/ - └── beamdyn/ + └── sampledyn/ ├── src/ - │ ├── BeamDyn.f90 - │ └── BeamDyn_Subs.f90 + │ ├── SampleDyn.f90 + │ └── SampleDyn_Subs.f90 └── tests/ - ├── test_BD_Subroutine1.F90 - ├── test_BD_Subroutine2.F90 - └── test_BD_Subroutine3.F90 + ├── test_SampleDyn_Subroutine1.F90 + ├── test_SampleDyn_Subroutine2.F90 + └── test_SampleDyn_Subroutine3.F90 Each unit test must be contained in a unique file called ``test_[SUBROUTINE].F90`` where ``[SUBROUTINE]`` is the code block being -tested. Finally, update the CMake configuration for building a module's unit -test executable by copying the BeamDyn CMake configuration into a new module -directory: +tested. The new files should contain a Fortran `module` which itself +contains a Fortran `subroutine` for each specific test case. Generally, +multiple tests will be required to fully test one subroutine. + +Finally, update the CMake configuration for building a module's unit +test executable by copying an existing unit test CMake configuration +into a new module directory: .. code-block:: bash diff --git a/unit_tests/test_SUBROUTINE.F90 b/unit_tests/test_SUBROUTINE.F90 index 12be6a4b02..01807ab051 100644 --- a/unit_tests/test_SUBROUTINE.F90 +++ b/unit_tests/test_SUBROUTINE.F90 @@ -1,61 +1,89 @@ -@test -subroutine test_SUBROUTINE() - ! test branches +module test_SUBROUTINE + + use pFUnit_mod + use NWTC_IO + ! use MODULE ! Import the module that will be tested here. + + implicit none + + real(ReKi) :: tolerance = 1e-14 + character(1024) :: testname + +contains + + ! Test branches ! - branch 1 ! - branch 2 ! - branch 3 - ! Note that this subroutine is *not* conforming Fortran code. + ! Note that this module is *not* conforming Fortran code. ! This is passed through a Python preprocessor included with pFUnit which parses ! pFUnit directives like `@test` and `@assertEqual` to generate proper Fortran code. - - use pFUnit_mod - use NWTC_Num - - implicit none - - integer :: flag - character(1024) :: testname - real(BDKi) :: tolerance - - ! initialize NWTC_Num constants - call SetConstants() - - tolerance = 1e-14 - - ! -------------------------------------------------------------------------- - testname = "branch 1:" - - ! describe this test - ! what is the expected result from the test subroutine - ! how are the baselines obtained - - call SUBROUTINE() - - @assertEqual(baseline, test, tolerance, testname) - - - ! -------------------------------------------------------------------------- - testname = "branch 2:" - - ! describe this test - ! what is the expected result from the test subroutine - ! how are the baselines obtained - - call SUBROUTINE() - - @assertEqual(baseline, test, tolerance, testname) - - - ! -------------------------------------------------------------------------- - testname = "branch 3:" - - ! describe this test - ! what is the expected result from the test subroutine - ! how are the baselines obtained - - call SUBROUTINE() - - @assertEqual(baseline, test, tolerance, testname) - -end subroutine + + @test + subroutine test_branch1() + + ! Describe this test. + ! What is the expected result from the tested subroutine? + ! Why is the expected result the result that is expected? + + real(ReKi) :: zero = 0.0 + real(ReKi) :: test_result + integer(IntKi) :: error_status + + testname = "Branch 1" + expected = 0.0 + + ! Assume SUBROUTINE( intent(in), intent(out), intent(out) ) + call SUBROUTINE(zero, test_result, error_status) + + @assertEqual(expected, test_result, tolerance, testname) + @assertEqual(0, error_status, tolerance, testname) + + end subroutine + + @test + subroutine test_branch2() + + ! Describe this test. + ! What is the expected result from the tested subroutine? + ! Why is the expected result the result that is expected? + + real(ReKi) :: pi = 3.14159 + real(ReKi) :: test_result + integer(IntKi) :: error_status + + testname = "Branch 2" + expected = 0.0 + + ! Assume SUBROUTINE( intent(in), intent(out), intent(out) ) + call SUBROUTINE(pi, test_result, error_status) + + @assertEqual(expected, test_result, tolerance, testname) + @assertEqual(0, error_status, tolerance, testname) + + end subroutine + + @test + subroutine test_branch3() + + ! Describe this test. + ! What is the expected result from the tested subroutine? + ! Why is the expected result the result that is expected? + + real(ReKi) :: pi_by_2 = 1.57079 + real(ReKi) :: test_result + integer(IntKi) :: error_status + + testname = "Branch 3" + expected = 99.9 + + ! Assume SUBROUTINE( intent(in), intent(out), intent(out) ) + call SUBROUTINE(pi_by_2, test_result, error_status) + + @assertEqual(expected, test_result, tolerance, testname) + @assertEqual(0, error_status, tolerance, testname) + + end subroutine + +end module