Testing in Python
Testing is a crucial aspect of software development, including in Python programming. It involves running a program, function, or module with test inputs to verify that it produces the expected output. Testing can be done manually or through automated tests. Testing is essential to ensure that the code works as expected, meets the functional requirements, and handles errors correctly.
By testing the code, developers can find and fix bugs before the software is deployed in a production environment. This helps to improve the software’s quality, reliability, and maintainability. Testing also helps developers to ensure that new code does not break existing functionality. This is especially important when working on large projects or when multiple developers are working on the same codebase.
With proper testing, changes can be made to the codebase with confidence, knowing that the existing functionality has not been adversely affected. We’ll learn how to write a simple test, run it, and detect errors before your users do! You’ll learn about the tools available for writing and executing tests, as well as testing terminologies such as automated, manual, unit, and integration tests.
Unit Tests
Unit testing operates on a component-by-component basis, so if we need to test a small component, we must use unit testing.
It is included in the standard Python library. The first line of code to use it should be import unittest. It should change depending on the Python version, as later versions of Python support unittest and previous ones support unittest2.
Example:
import unittest
class Testing_Class(unittest.TestCase):
def test_Func(self):
data = [24, 64, 128]
result = sum(data)
print(result)
self.assertEqual(result, 300)
if __name__ == '__main__':
unittest.main()
Output:
216
F
======================================================================
FAIL: test_Func (__main__.Testing_Class)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Desktop/Python/Enablegeek.py", line 9, in test_Func
self.assertEqual(result, 300)
AssertionError: 216 != 300
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
Example:
def Sum_Test_List():
assert sum([10, 20, 30,40]) == 100, "Answer should be 100"
def Sum_Test_Tuple():
assert sum((10, 20, 20, 40)) == 100, "Result should be 100"
if __name__ == "__main__":
Sum_Test_List()
Sum_Test_Tuple()
print("Checking the tests are passed or not")
Output:
Traceback (most recent call last):
File "/Desktop/Python_test.py", line 9, in <module>
Sum_Test_Tuple()
File "/Desktop/Python_test.py", line 5, in Sum_Test_Tuple
assert sum((10, 20, 20, 40)) == 100, "Result should be 100"
AssertionError: Result should be 100
In the above example, we have two methods, and when the code is performed, the second function produces an error since the specified numbers do not equal 100.
Python Doctest
The foundational elements of any effective software development process are testing and documentation. Making sure that code is adequately documented and tested not only guarantees that a program functions as intended, but also promotes collaboration among programmers and user acceptance. A programmer can benefit by first producing documentation, then tests, and finally code. Following a procedure like this ensures that the function is coded (for example) is thoroughly thought out and addresses any potential edge circumstances.
Python’s standard library includes a test framework module known as doctest. The doctest package examines Python code for text fragments within comments that resemble interactive Python sessions. The module then runs those sessions to ensure that the code referenced by a doctest works as intended.
doctest also creates documentation for our code, including input-output examples. Depending on how you approach producing doctests, this can be closer to “literate testing” or “executable documentation,” as explained in the Python Standard Library documentation.
Example:
import doctest
def add(a, b):
"""
Given two integers, return the sum.
:param a: int
:param b: int
:return: int
>>> add(2, 3)
5
"""
return a + b
if __name__ == '__main__':
doctest.testmod(name ='add', verbose = True)
import doctest
def add(a, b):
"""
Given two integers, return the sum.
:param a: int
:param b: int
:return: int
>>> add(2, 3)
5
"""
return a + b
if __name__ == '__main__':
doctest.testmod(name ='add', verbose = True)
Output:
Trying:
add(2, 3)
Expecting:
5
ok
1 items had no tests:
add
1 items passed all tests:
1 tests in add.add
1 tests in 2 items.
1 passed and 0 failed.
Test passed.
This article introduces the doctest module as a means for not just testing and documenting software, but also for thinking about programming before you start by first documenting it, then testing it, and last writing the code.
Failure to write tests may result in not only defects but also program failure. Developing the practice of developing tests before writing code may lead to more productive software that benefits both other developers and end users.
Another example here,
Example:
from doctest import testmod
def count_func(word):
"""
Give me a word, and tell me how many vowels are there in that word.
:param word: str
:return: int
>>> count_func('Enablegeek')
5
>>> count_func('Python')
1
"""
Total = 0
for v in word:
if v in 'aeiouAEIOU':
Total += 1
return Total
if __name__ == "__main__":
testmod(name ='count_func', verbose = True)
Output:
Trying:
Count('Enablegeek')
Expecting:
5
ok
Trying:
Count('Python')
Expecting:
1
ok
1 items had no tests:
Count
1 items passed all tests:
2 tests in Count.Count
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
Python provides several testing frameworks, including unittest, pytest, and doctest. These frameworks make it easy to write and run tests and generate test reports. They also provide features such as test discovery, fixtures, and assertions, which help to simplify the testing process. Testing is a critical aspect of Python programming. It helps to ensure that the code works as intended, meets functional requirements, and is reliable and maintainable. By testing code regularly, developers can catch and fix bugs early, which reduces the cost and complexity of fixing issues later in the development process.