Creating unit tests: basic tests
Now let’s write some tests to make sure our function works correctly. We’ll use the Python unittest module. Create a new file called test_key_of_max.py and add the following code:
import unittest
from key_of_max import key_of_max ## Import our function
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
if __name__ == '__main__':
unittest.main()
Explanation:
-
import unittestImports the testing framework.
-
from key_of_max import key_of_maxImports the function we want to test.
-
class TestKeyOfMax(unittest.TestCase):Defines a test case. Test cases group related tests together.
-
def test_basic_case(self):Defines a test case. Each test case tests a specific aspect of our function. Test case names should start with test_.
-
self.assertEqual(…)This is an assertion. It checks if two values are equal. If they are not equal, the test fails. In this case, we are checking if key_of_max({‘a’: 4, ‘b’: 0, ‘c’: 13}) returns ‘c’, which it should.
-
def test_another_case(self):Added another test case to test the max key, which may not be unique.
-
if __name__ == ‘__main__’: unittest.main()This standard Python idiom runs tests when you execute a script directly (e.g., python3 test_key_of_max.py).
Run the tests from the terminal: python3 test_key_of_max.py You should see output indicating that both tests passed.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Testing an empty dictionary (edge case)
Let’s add a test specifically for the case of an empty dictionary. Add this method to your TestKeyOfMax class in test_key_of_max.py:
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
-
self.assertIsNone(…)This assertion checks whether a value is exactly None. This is important because self.assertEqual(…, None) can be passed values that evaluate to None but are not actually None. assertIsNone is more strict.
Run the tests again (python3 test_key_of_max.py). All three tests (the two basic tests and the empty dictionary test) should now pass.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
Testing with all negative values
As a final test, consider the case where all the values in the dictionary are negative. Add this method to TestKeyOfMax:
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
This test ensures that our function correctly determines the smallest negative value (which in this case is the maximum) and returns the associated key. Run the tests again (python3 test_key_of_max.py). All four tests should pass. This gives us a high level of confidence that our function is working correctly.
Your complete test_key_of_max.py should now look like this:
import unittest
from key_of_max import key_of_max
class TestKeyOfMax(unittest.TestCase):
def test_basic_case(self):
self.assertEqual(key_of_max({'a': 4, 'b': 0, 'c': 13}), 'c')
def test_another_case(self):
self.assertEqual(key_of_max({'apple': 10, 'banana': 5, 'orange': 10}), 'apple')
def test_empty_dictionary(self):
self.assertIsNone(key_of_max({}))
def test_all_negative_values(self):
self.assertEqual(key_of_max({'x': -5, 'y': -2, 'z': -10}), 'y')
if __name__ == '__main__':
unittest.main()
Run the tests again (python3 test_key_of_max.py). All four tests should pass. This gives us high confidence that our function is working correctly.
python3 test_key_of_max.py
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
Conclusion
We created a simple but powerful function key_of_max() that allows you to quickly find the key with the largest value in a Python dictionary. During the development, we took into account all the important details step by step: handling empty dictionaries, checking for duplicate values, and even testing with negative numbers. Thanks to unit tests, we made sure that the function works consistently in all scenarios.
This approach not only teaches you to think correctly in terms of clean and reliable code, but also demonstrates how to build small but effective utilities that make working with data in Python faster and clearer.
If you are looking to improve your Python skills, this example is a great example of how even a simple function can teach you to think like a real developer.