Testing and Debugging

Writing and Running Unit Tests with Unittest or Pytest

  • Unittest and Pytest are two of the most used unit testing frameworks in Python1.

  • Unittest supports running Python unittest-based tests out of the box2. It’s meant for leveraging existing unittest-based test suites to use pytest as a test runner and also allows to incrementally adapt the test suite to take full advantage of pytest’s features2.

  • Pytest will automatically collect unittest.TestCase subclasses and their test methods in test_*.py or *_test.py files2.

  • Almost all unittest features are supported: @unittest.skip style decorators; setUp/tearDown; setUpClass/tearDownClass; setUpModule/tearDownModule2.

Example

# Example 1: Basic structure of unittest
import unittest

class Testing(unittest.TestCase):
    def test_string(self):
        a = 'some'
        b = 'some'
        self.assertEqual(a, b)

    def test_boolean(self):
        a = True
        b = True
        self.assertEqual(a, b)

if __name__ == '__main__':
    unittest.main()
# Example 2: Basic structure of a class to be tested
class Person:
    name = []

    def set_name(self, user_name):
        self.name.append(user_name)
        return len(self.name) - 1

    def get_name(self, user_id):
        if user_id >= len(self.name):
            return 'There is no such user'
        else:
            return self.name[user_id]
# Example 3: Running the class with some data
if __name__ == '__main__':
    person = Person()
    print('User Abbas has been added with id ', person.set_name('Abbas'))
    print('User associated with id 0 is ', person.get_name(0))

Debugging Techniques and Tools

  1. Example of coding:

# Example 1: Using print statements for debugging
def add(a, b):
    print(f"Adding {a} and {b}")
    return a + b

print(add(2, 3))  # Output: Adding 2 and 3 \n 5

# Example 2: Using assert statements for debugging
def avg(marks):
    assert len(marks) != 0, "List is empty."
    return sum(marks)/len(marks)

print(avg([]))  # Output: AssertionError: List is empty.

# Example 3: Using a debugger (pdb module in Python)
import pdb

def seq(n):
    for i in range(n):
        pdb.set_trace()  # breakpoint
        print(i)
    return

seq(5)

Code Profiling and Optimization

Example

# Example 1: Using cProfile for profiling
import cProfile
import re
cProfile.run('re.compile("foo|bar")')

# Example 2: Using timeit for performance measurement
import timeit
print(timeit.timeit('"-".join(str(n) for n in range(100))', number=10000))

# Example 3: Using memory_profiler for memory profiling
from memory_profiler import profile

@profile
def my_func():
    a = [1] * (10 ** 6)
    b = [2] * (2 * 10 ** 7)
    del b
    return a

if __name__ == '__main__':
    my_func()

Last updated

Was this helpful?