In bioinformatics programming, writing accurate code that produces correct output is often far more important than writing code that is fast or even elegant.
The reason is that the primary goal of most bioinformatics programming is to serve a research goal, i.e., answer a question about data.
Despite this, few projects have a testers. Typically, the person who writes the code is also the person who validates it.
For this reason, every bioinformatics programmer needs to develop sense of where code can go wrong and must also learn techniques for testing.
To help you get started learning this valuable skill, you'll use testing code designed for your first python assignment to test your functions.
You are welcome to use the code to check your work, and we'll use this same testing code to check that your functions.py code is working correctly.
How to use the testing script to validate your code
Go to Tools > Attachments and download the attached python script called test_functions.py.
Save the script into the same directory as your copy of functions.py and use chmod to make it executable.
To run it at the UNIX prompt, just type its name, just like any other executable program under UNIX. However, make sure that the current working directory is in your PATH. Some UNIX systems don't automatically add the current working directory to user's PATH environment variables and you may need to configure this yourself by editing your .bash_profile script.
Testing and target functions
The program test_functions.py has multiple testing functions that test aspects of the target functions defined in functions.py.
How this works
The test_functions.py script imports the functions.py module and then runs the testing functions one by one. It then prints a summary from the output from the testing functions in a single line of text.
If all the tests pass, you'll see something like the following when you run test_functions.py:
Interpreting the output of test_functions.py
The testing script prints three sections of output.
The first section is the first line of output, which is a summary of all the tests that were run.
For each test, the testing script prints either a '.' character, an 'F' (for fail) character, and an 'E' for error character.
If a test passes, the script prints '.' but if the test fails or was not able to run because of a syntax or other error, it prints 'F' or 'E'.
If any of the tests fail or produce an error preventing them from being run, then test_functions.py will next print the details of the problem.
Finally, the testing function will report how many tests were run and the number of errors and failures.
Here is another example of output from test_functions.py when testing a functions.py file where all the required functions are implemented except for one: reverseComplement.
In this examle, For example, the test_functions.py script exects that your functions.py file contains a function called reverseComplement. If you try to run test_funtions.py before you implement the function, the result will be an import error from the testing functions that try to use the reverseComplement method.
More about testing functions
The testing functions try to run target functions defined in functions.py using known input and save the result in a variable.
For each known input, an answer is also known, and the testing functions compare the test results answers they get from the target functions to the known answer. If the known answer and the test results answer are the same, the test passes, and test_functions.py prints a "." character. If the answers are not the same, the test fails, and test_functions.py prints an "F" (for fail) character. If either the testing function or its target function couldn't run, perhaps because one or both has a syntax error, then test_functions.py prints an "E" (for error) character.
Technical details (Object-oriented programming)
The PyUnit framework uses object-oriented programming techniques to implement a way for programmers to easily and rapidly write simple tests of individual functions. These tests are called "unit tests" because they typically test individual "units" of code. Technically speaking, how this works is that test_Functions.py contains a single class called FunctionTests, which contains all the testing functions. The test_functions.py script also contains a main method (you'll learn all about main methods later) which invokes the unittest.main method. That main method then creates an instance of the FunctionTests class and then calls all its functions one by one.