Skip to content

Commit 3862523

Browse files
authored
Merge pull request #39 from UCL-ARC/pf-syntax-split-challenge-up
2 parents 5cf1ef1 + 69ca515 commit 3862523

1 file changed

Lines changed: 150 additions & 3 deletions

File tree

episodes/4-pfunit-syntax.md

Lines changed: 150 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,46 @@ end type my_test_case
136136
- We then define a single type-bound value which is of the test parameter type we have just
137137
defined.
138138

139+
140+
::::::::::::::::::::::::::::::::::::: challenge
141+
142+
#### Challenge: Add derived types to pFUnit tests of temperature conversions
143+
144+
Continuing with part two of [3-writing-your-first-unit-test/challenge][exercises-challenge] from the
145+
exercises repo. Begin re-writing your standard Fortran test using pFUnit. First, add some derived
146+
types to the provided template file,
147+
[test_temp_conversions.pf](https://github.com/UCL-ARC/fortran-unit-testing-exercises/blob/main/episodes/3-writing-your-first-unit-test/challenge/test/pfunit/test_temp_conversions.pf#L9-L19).
148+
149+
:::::::::::::::::::::::::::::::: solution
150+
151+
These types could look something like this...
152+
153+
```f90
154+
!> Test parameter type to package the test parameters
155+
@TestParameter
156+
type, extends(AbstractTestParameter) :: temp_conversions_test_params_t
157+
!> The temperature to input into the function being tested
158+
real :: input
159+
!> Theb temperature expected to be returned from the function being tested
160+
real :: expected_output
161+
!> A description of the test to be outputted for logging
162+
character(len=100) :: description
163+
contains
164+
procedure :: toString => temp_conversions_test_params_t_toString
165+
end type temp_conversions_test_params_t
166+
167+
!> Test case type to specify the style of test (paramaterized)
168+
@TestCase(constructor=new_test_case)
169+
type, extends(ParameterizedTestCase) :: temp_conversions_test_case_t
170+
type(temp_conversions_test_params_t) :: params
171+
end type temp_conversions_test_case_t
172+
```
173+
174+
A full solution is provided in [3-writing-your-first-unit-test/solution](exercises-solution).
175+
176+
:::::::::::::::::::::::::::::::::::::::::
177+
:::::::::::::::::::::::::::::::::::::::::::::::
178+
139179
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
140180

141181
:::::::::::::::::::::::::::::::::::::::::::::::::::: spoiler
@@ -162,6 +202,38 @@ end function my_test_suite
162202
- We are using a constructor function to define each parameter set which we do not need to
163203
define ourselves.
164204

205+
::::::::::::::::::::::::::::::::::::: challenge
206+
207+
#### Challenge: Add a test suite to pFUnit tests of temperature conversions
208+
209+
Continuing with your pFUnit test of `temp_conversions`, add a test suite for tests of the
210+
function `fahrenheit_to_celsius` in the indicated section of the template file,
211+
[test_temp_conversions.pf](https://github.com/UCL-ARC/fortran-unit-testing-exercises/blob/main/episodes/3-writing-your-first-unit-test/challenge/test/pfunit/test_temp_conversions.pf#L27-L28)
212+
213+
:::::::::::::::::::::::::::::::: solution
214+
215+
This test suites could look something like this...
216+
217+
```f90
218+
!> Test Suite for tests of fahrenheit_to_celsius
219+
function fahrenheit_to_celsius_testsuite() result(params)
220+
!> An array of test parameters, each specifying an individual test
221+
class(temp_conversions_test_params_t), allocatable :: params(:)
222+
223+
params = [ &
224+
temp_conversions_test_params_t(0.0, -17.777779, "0.0 °F"), &
225+
temp_conversions_test_params_t(32.0, 0.0, "0.0 °C"), &
226+
temp_conversions_test_params_t(-100.0, -73.333336, "100 °F"), &
227+
temp_conversions_test_params_t(1.23,-17.094444, "Decimal °F") &
228+
]
229+
end function fahrenheit_to_celsius_testsuite
230+
```
231+
232+
A full solution is provided in [3-writing-your-first-unit-test/solution](exercises-solution).
233+
234+
:::::::::::::::::::::::::::::::::::::::::
235+
:::::::::::::::::::::::::::::::::::::::::::::::
236+
165237
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
166238

167239
:::::::::::::::::::::::::::::::::::::::::::::::::::: spoiler
@@ -210,6 +282,44 @@ subroutine TestMySrcProcedure(this)
210282

211283
:::::::::::::::::::::::::::::::::::::::::::
212284

285+
::::::::::::::::::::::::::::::::::::: challenge
286+
287+
#### Challenge: Add a test function to pFUnit tests of temperature conversions
288+
289+
Continuing with your pFUnit test of `temp_conversions`, add some test logic for tests of
290+
the function `fahrenheit_to_celsius` in the indicated section of the template file,
291+
[test_temp_conversions.pf](https://github.com/UCL-ARC/fortran-unit-testing-exercises/blob/main/episodes/3-writing-your-first-unit-test/challenge/test/pfunit/test_temp_conversions.pf#L30-L31)
292+
293+
:::::::::::::::::::::::::::::::: solution
294+
295+
This test logic could look something like this...
296+
297+
```f90
298+
!> Test Logic, unit test subroutine for fahrenheit_to_celsius
299+
@Test(testParameters={fahrenheit_to_celsius_testsuite()})
300+
subroutine test_fahrenheit_to_celsius(this)
301+
!> The test case which indicates the type of test we are running
302+
class(temp_conversions_test_case_t), intent(inout) :: this
303+
304+
character(len=200) :: failure_message
305+
real :: actual_output
306+
307+
! Get the actual celsius value returned from fahrenheit_to_celsius
308+
actual_output = fahrenheit_to_celsius(this%params%input)
309+
310+
! Populate the failure message
311+
write(failure_message, '(A,F7.2,A,F7.2,A,F7.2,A)') "Failed With ", this%params%input, " °F: Expected ", &
312+
this%params%expected_output, "°C but got ", actual_output, "°C"
313+
@assertEqual(this%params%expected_output, actual_output, tolerance=1e-6, message=trim(failure_message))
314+
315+
end subroutine test_fahrenheit_to_celsius
316+
```
317+
318+
A full solution is provided in [3-writing-your-first-unit-test/solution](exercises-solution).
319+
320+
:::::::::::::::::::::::::::::::::::::::::
321+
:::::::::::::::::::::::::::::::::::::::::::::::
322+
213323
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
214324

215325
:::::::::::::::::::::::::::::::::::::::::::::::::::: spoiler
@@ -251,18 +361,55 @@ function my_test_params_toString(testParameter) result(string)
251361
end function my_test_params_toString
252362
```
253363

364+
::::::::::::::::::::::::::::::::::::: challenge
365+
366+
#### Challenge: Add type constructors to pFUnit tests of temperature conversions
367+
368+
Continuing with your pFUnit test of `temp_conversions`, add some type constructors for
369+
tests of the `temp_conversions` in the indicated section of the template file,
370+
[test_temp_conversions.pf](https://github.com/UCL-ARC/fortran-unit-testing-exercises/blob/main/episodes/3-writing-your-first-unit-test/challenge/test/pfunit/test_temp_conversions.pf#L49-L59)
371+
372+
:::::::::::::::::::::::::::::::: solution
373+
374+
These type constructors could look something like this...
375+
376+
```f90
377+
!> Constructor for converting test parameters into a test case
378+
function new_test_case(testParameter) result(tst)
379+
!> The parameters to be converted to a test case
380+
type(temp_conversions_test_params_t), intent(in) :: testParameter
381+
!> The test case to return after conversion from parameters
382+
type(temp_conversions_test_case_t) :: tst
383+
384+
tst%params = testParameter
385+
end function new_test_case
386+
387+
!> Constructor for converting test parameters into a string
388+
function temp_conversions_test_params_t_toString(this) result(string)
389+
!> The parameters to be converted to a string
390+
class(temp_conversions_test_params_t), intent(in) :: this
391+
character(:), allocatable :: string
392+
393+
string = trim(this%description)
394+
end function temp_conversions_test_params_t_toString
395+
```
396+
397+
A full solution is provided in [3-writing-your-first-unit-test/solution](exercises-solution).
398+
399+
:::::::::::::::::::::::::::::::::::::::::
400+
:::::::::::::::::::::::::::::::::::::::::::::::
401+
254402
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
255403

256404
::::::::::::::::::::::::::::::::::::: challenge
257405

258406
## Challenge: Test temperature conversions using pFUnit
259407

260-
Continuing with part two of [3-writing-your-first-unit-test/challenge][exercises-challenge] from the
261-
exercises repo. Re-write your standard Fortran test using pFUnit.
408+
Finalising your pFUnit test of `temp_conversions` add an additional test of the function `celsius_to_kelvin`.
262409

263410
:::::::::::::::::::::::::::::::: solution
264411

265-
A solution is provided in [3-writing-your-first-unit-test/solution](exercises-solution).
412+
The full solution is provided in [3-writing-your-first-unit-test/solution](exercises-solution).
266413

267414
:::::::::::::::::::::::::::::::::::::::::
268415
:::::::::::::::::::::::::::::::::::::::::::::::

0 commit comments

Comments
 (0)