Original link: https://controlnet.space/2022/07/28/tutorial/python-fund/py-prog-fund-08/
Life is too short, I use Python![1]
This series is a tutorial to help beginners get started with programming. This article mainly introduces unit testing and exception handling in Python.
test
In the software development process, testing is a very important step to ensure the correctness and quality of the program. Errors and deficiencies in programs can also be identified and corrected prior to final deployment.
Fig. 1. Major bugs can have serious consequences. Adapted from [2] and [3]
Some fatal software bugs can have serious consequences, such as the failure of the 737MAX aircraft and the failure of Uber’s autopilot system, as shown in Figure 1 [2, 3]. In addition, some other software bugs that have a serious negative impact on society can be found here ( List_of_software_bugs ). To avoid this, we need to add tests to the program.
The test is divided into 4 levels, namely:
- Unit testing
- Individual units or components in the program are tested
- Make sure every unit is running well without any errors
- Integration testing
- Multiple units are combined and tested as a set
- In integrating interactions between multiple units, errors may be exposed
- System testing
- The entire system is tested as a whole
- Ensure all functions and requirements are met
- Acceptance testing
- The complete program is tested before user deployment
- Assess that the system meets all business requirements
Here we mainly focus on how to write unit tests for Python, other types of tests are part of the software engineering section.
So how do you write tests? The basic idea is to start by thinking about defining a good testing strategy with many different test cases, which is important to ensure the correctness of the program.
Then an excellent testing strategy:
- To ensure that all functions of the program can be covered and tested in a limited time
- Consists of reasonable, manageable and maintainable test cases
- Maximize the likelihood of detecting errors or defects
As an example, consider a program that requires input scores to calculate whether a student has passed an exam.
1 |
if mark >= 50 and mark <= 100 : |
Valid (positive) use cases:
- Based on correct input data
- Example: 55, 60, 65, …, 85, 90, 95, …
Invalid (negative) use case:
- Based on incorrect input data
- For example: -1, 0, 5, …, 45, 49, 101, 200, …
Edge use cases:
- Some boundary values in valid use cases
- For example: (49, 50) and (100, 101)
Debug
Debug refers to the process of finding and solving defects or problems in computer programs. When writing a program or testing a bug, you need to debug to solve it.
In Python, there are two basic approaches:
-
print
statement -
assert
statement
We are already familiar with print
, which outputs the value of this variable, which is convenient for observing the value of a variable at runtime.
As for assert
:
- It checks whether an expression is true, and if not, throws an
AssertionError
exception - Syntax:
assert (condition), "<error_message>"
for example:
1 |
assert size <= 5 , "size should not exceed 5" |
But in short, the best debugging is to actually understand the program you wrote.
Unit Testing in Python
In Python, we need to use the unittest
standard library for testing.
- Create a test class by inheriting
unittest.TestCase
- Define one or more test methods in the test class
Suppose we have a function product_func
defined and we need to write unit tests for it.
1 |
def product_func ( first_arg, second_arg ): |
Then the unit test can be written like this:
1 |
import unittest |
When running this test, there will be possibilities: OK, FAIL, ERROR.
If in Jupyter Notebook, we can run the test like this.
1 |
suite = unittest.TestLoader().loadTestsFromTestCase(TestForProduct) |
In unittest
, Python provides the following assert methods:
Method | Checks that | New in |
---|---|---|
assertEqual(a, b) | a == b |
|
assertNotEqual(a, b) | a != b |
|
assertTrue(x) | bool(x) is True |
|
assertFalse(x) | bool(x) is False |
|
assertIs(a, b) | a is b |
3.1 |
assertIsNot(a, b) | a is not b |
3.1 |
assertIsNone(x) | x is None |
3.1 |
assertIsNotNone(x) | x is not None |
3.1 |
assertIn(a, b) | a in b |
3.1 |
assertNotIn(a, b) | a not in b |
3.1 |
assertIsInstance(a, b) | isinstance(a, b) |
3.2 |
assertNotIsInstance(a, b) | not isinstance(a, b) |
3.2 |
For a more comprehensive introduction and explanation of unittest
, please refer to this page [4].
Errors and exceptions in Python
In programming, errors are generally divided into the following three categories:
- Syntax errors (Syntax erros)
- The code is syntactically wrong and the compiler/interpreter cannot understand the code
- Example in Python:
SyntaxError
- Runtime errors
- The code encountered an error at runtime and can be handled appropriately
- Examples in Python:
ValueError
,TypeError
,NameError
- Logic errors
- Incorrect implementation of program logic
- The program runs without error, but the result is wrong
Let’s take some Python examples to illustrate.
SyntaxError
:
- Syntax error in program
1 |
if a_number > 2 |
NameError
:
- An undefined variable or module is used in the program
1 |
a_number = random.random() |
TypeError
:
- Attempt to use incompatible object types
1 |
if a_number > 2 : |
ValueError
:
- Attempt to pass in a parameter, the type is correct but the value is wrong
1 |
sum_of_two = int ( '1' ) + int ( 'b' ) |
For more Python error exceptions, please refer to this page [5].
Exception Handling in Python
In Python, the try
and except
keywords are mainly used to handle exceptions.
try
and except
:
- The statement inside the
try
block will be executed, if no exception occurs, theexcept
block will be skipped - If an exception occurs and the conditions in
except
are met, the correspondingexcept
block will be executed - If an exception occurs, but no
except
condition is met, the program will still report an error and exit
The following is an example. If a non-numeric string is input, or the divisor is 0, it can be processed in the corresponding except
code block.
1 |
try : |
else
:
- If no exception occurs, the
else
block will be executed - This is useful if you need to run some code when no exception occurs
example:
1 |
file_name = "input_file.txt" |
finally
:
- as a cleanup block of code
- A block of code that will be executed whether or not an exception occurs
1 |
file_name = "input_file.txt" |
practice test
In this exercise, let’s try to write code in a way that handles all exceptions, and also needs to write unit tests for the program. If necessary, add comments to aid development.
Debugging
We need to write a program to calculate a student’s GPA. Each student needs to calculate the grades of 5 courses, and the calculation rules are as follows:
1 |
A ----- 4.0 |
There is a buggy code here and we need to fix it.
1 |
number_of_courses = 3 |
Let’s find out what’s wrong.
The first is that number_of_courses
should be 5 instead of 3. You need to add an assert
to check that this variable will not go wrong.
1 |
number_of_courses = 5 |
Then there is a TypeError
because len in len
len(number_of_courses)
needs to accept a collection type instead of a number.
1 |
for i in range (number_of_courses): |
Then input_grade.append
is a method, which needs to be called instead of assignment.
Second, in the combination of strings, (i+1)
needs to be converted to strings, because strings cannot be added to numbers.
And input_grade
has a NameError
because it is not defined.
So this line would be changed to
1 |
course_grades.append( input ( "Please enter the grade for " + str (i+ 1 ) + " unit: " )) |
Next input_grades
also has a NameError
error and needs to use the correct variable name. The same goes for grade
.
Then there is a logic error, the user may enter a lowercase letter, and this will skip the processing of the following code block. should be changed to
1 |
for grades in course_grades: |
test
In the previous section, we have written a simple program to calculate a student’s GPA. Think about how tests for the program above should be written to check for potential errors. Let’s try writing some unit tests.
First we put the above program into a function.
1 |
def calculate_GPA ( grade_list ): |
The next step is to write unit tests.
1 |
import unittest |
In Jupyter Notebook, we need to run the following code to run the tests.
1 |
test = TestForGPA() |
exception handling
Let’s improve the code of practice questions for Python Programming Fundamentals 05 .
Below is the original code.
1 |
# Open simple_file.txt for reading |
The text in simple_file.txt
needs to be processed, each line of the file contains three values, the first two are numbers, and the third is an English string representing a number, say “one”. What we need to do is convert the third value to a number and write the result of the entire file to output_file.txt
, we only take 1~5 as an example.
1 |
1 2 five |
After this study, we can use the try-catch code block to better handle exception errors. The following is a reference example.
1 |
try : |
Series Summary
So far, the basics of Python programming have all been covered. A total of 8 blogs above cover most of the syntax and programming ideas related to Python basics. I believe that after learning the above 8 articles, you will be able to independently write Python programs without encountering great obstacles. As for the future content, I plan to write a few more post-mortem talks for some advanced Python syntax, which may include type annotations, metaclasses, decorators, functional programming and concurrency and so on.
references
- [1] B. Eckel, “sebsauvage.net – Python”, Sebsauvage.net, 2021. [Online]. Available: http://sebsauvage.net/python/ .
- [2] C. Nast, “Boeing Plans to Fix the 737 MAX Jet With a Software Update”, Wired, 2022. [Online]. Available: https://www.wired.com/story/boeing-737-max- 8-ethiopia-crash-faa-software-fix-lion-air/ .
- [3] “So who’s to blame when a driverless car has an accident?”, Abc.net.au, 2022. [Online]. Available: https://www.abc.net.au/news/2018-03- 20/uber-driverless-car-accident-who-is-to-blame/9567766 .
- [4] “unittest — Unit testing framework — Python 3.10.5 documentation”, Docs.python.org, 2022. [Online]. Available: https://docs.python.org/3/library/unittest.html .
- [5]”Built-in Exceptions — Python 3.10.5 documentation”, Docs.python.org, 2022. [Online]. Available: https://docs.python.org/3/library/exceptions.html .
This article is reprinted from: https://controlnet.space/2022/07/28/tutorial/python-fund/py-prog-fund-08/
This site is for inclusion only, and the copyright belongs to the original author.