python unit testing

To use plain old python without installing any additional packages, we can use the following code setup ad run our unit tests.


test_simple.py

import unittest

def add(x, y):
    return x + y

class TestMath(unittest.TestCase):
    def test_add(self):
        self.assertEqual(add(2, 3), 5)
   
    def test_add_success(self):
        self.assertEqual(add(2, 3), 5)
     
    def test_add_success_with_extra(self):
        self.assertEqual(add(2, 3), 5)

if __name__ == '__main__':
    unittest.main()


To run the unit test we can use:

python -m unittest discover 

or 

python -m unittest discover -s tests  (if we have our tests in a tests subfolder)


To setup Mocking 

With python, we can use the Mock from unittest package. Let's say we have the following classes. A simple Animal class and its echo service.


class Animal:
    def __init__(self):
        pass

    def sayHello() -> str:
        pass
     
class Dog(Animal):
    def __init__(self):
        pass

    def sayHello(self) -> str:
        return "woof"

class Cat(Animal):
    def __init__(self):
        pass

    def sayHello(self) -> str:
        return "meow"

class Echo:
    target: Animal

    def __init__(self, target: Animal):
        self.target = target

    def sayHello(self) -> str:
        return self.target.sayHello()


We can use Cat and Dog for the implementation. But somethings we just wanna mock it. Here is an example of using the mock.

In the first test, test_target_hello, we change the return value after calling sayHello(). It returns "Grrr"

In the second test cases, we are trying to simulate an error by forcefully throwing an exception


## Testing Echo Service
class EchoTestService(unittest.TestCase):
   
    def test_target_hello(self):
        mockAnimal = Mock()

        ## fake the sayHello method to return a hard coded value "Grrr"
        mockAnimal.sayHello.return_value = "Grrr"
       
        target = Echo(mockAnimal)
        result = target.sayHello()
       
        self.assertEqual(result, "Grrr")
        mockAnimal.sayHello.assert_called_once()

    # test to fake an exception; Exception type here could be too general. It should be something like ValueError
    # or SystemError
    def test_target_hello_error(self):

        mockAnimal = Mock()
        mockAnimal.sayHello.side_effect = Exception("")

        with self.assertRaises(Exception):
            target = Echo(mockAnimal)
            result = target.sayHello()

The code can be found here

https://github.com/mitzenjeremywoo/python-test-mock

unit test references page 

https://docs.python.org/3/library/unittest.mock.html


Comments

Popular posts from this blog

gemini cli getting file not defined error

NodeJS: Error: spawn EINVAL in window for node version 20.20 and 18.20

vllm : Failed to infer device type