Running your code with a set of input parameters, where you already know what the output should be - and checking that your code output and “model answers” match
A more structured testing suite… - Ensures code doesn’t slip through the cracks - Makes sure that the code still works every time it is updated - Can be integrated with other tools (such as GitHub)
Example function:
def CrankNicolsonSolver(arg1, arg2, arg3, arg4):
“““Your Docstring Goes Here”””
amazingly complex math goes here
return(output1, output2, output3)
How do we test this?
assert
statements!In general, Python tests rely on assert statements, comparing example data outputs with the return values of one of your functions.
Essentially:
def test_CrankNicolsonSolver():
example_input = [ex_in1, ex_in2, ex_in3, ex_in4]
example_output = [ex_out1, ex_out2, ex_out3]
test_output = CrankNicolsonSolver(example_input)
assert test_output == example_output
This test will pass (nothing will happen) if the test output matched the expected example output, and will fail and throw an error if there’s a difference
==
cause problems?If your test output and your expected example output are not both integers or identical strings!
With scientific code, it’s very likely that the output will be… - Floating point numbers - Arrays of floating point numbers
This is when functions such as pytest.approx()
(and equivalent functions in numpy
and other libraries which allow comparison of arrays), which allow you to build in a tolerance to your tests, are used.
It’s likely you’ll rarely use the pure equal-to operator.
Testing the code…
Ensure that the code is doing what you think it’s doing:
Testing the science…
Build the test first!
First, build your test - imagine the Crank-Nicolson solver function doesn’t exist yet!
Essentially:
def test_CrankNicolsonSolver():
example_input = [ex_in1, ex_in2, ex_in3, ex_in4]
example_output = [ex_out1, ex_out2, ex_out3]
test_output = CrankNicolsonSolver(example_input)
assert test_output == example_output
This test will fail because an error will be thrown because test_CrankNicolsonSolver()
doesn’t exist yet!
Example function scaffolding:
If you run the test function, it will fail, with a different error this time: the function now exists, but it has no output.
If you call all of your test functions test_something()
, and if you put all your tests in a file called test_something.py
, and if you put any test scripts/files in a folder called tests in the main project folder…
You can create/use a conda environment with pytest
installed, and simply run:
pytest
from the terminal; it will collect and run any test functions in the tests folder.
Test suites using pytest
can be incorporated into your repository.
You can create a GitHub action that will:
Testing can feel complex and scary until you try implementing it!
Start testing your code in the next practical.