How to check for ValueError in Python?

One of the most fundamental aspects in software engineering is error handling. Software applications can break for many different reasons and therefore it is quite important to be able to write code in such a way that it can handle and report exceptions effectively.

Handling exceptions in the source code isn’t enough though. Testing that your code handles and reports exceptions as expected is even more important. Testing ensures that an exception is being raised when appropriate and with the correct message.

In today’s article we will demonstrate how to write test cases that test whether a function raises the expected Exception when a certain event occurs. More specifically, we will showcase how to do so using two of the most popular test packages in Python, namely unittest and pytest.

First, let’s create one example function that raises an Exception when a particular event happens. We will then go through a step by step guide that will eventually help you test exception handling.

def greet(greeting):
if greeting not in ('hello', 'hi'):
raise ValueError(f'{greeting} is not allowed')

print(greeting + ' world!')

Our greet function will raise a ValueError if the input

import unittestclass MyTestCase(unittest.TestCase):    def test_greet_raises(self):
self.assertRaises(ValueError, greet, 'bye')
if __name__ == '__main__':
unittest.main()
0 argument does not equal to
import unittestclass MyTestCase(unittest.TestCase):    def test_greet_raises(self):
self.assertRaises(ValueError, greet, 'bye')
if __name__ == '__main__':
unittest.main()
1 or
import unittestclass MyTestCase(unittest.TestCase):    def test_greet_raises(self):
self.assertRaises(ValueError, greet, 'bye')
if __name__ == '__main__':
unittest.main()
2. Now let’s see in practice how we can properly test that the function raises an exception as expected with unittest and pytest.

Testing exception handling with unittest

In order to create a test case to test whether a ValueError is being raised by

import unittestclass MyTestCase(unittest.TestCase):    def test_greet_raises(self):
self.assertRaises(ValueError, greet, 'bye')
if __name__ == '__main__':
unittest.main()
6 when the input argument does not hold an expected value, we can take advantage of
import unittestclass MyTestCase(unittest.TestCase):    def test_greet_raises(self):
self.assertRaises(ValueError, greet, 'bye')
if __name__ == '__main__':
unittest.main()
7 method as outlined below:

import unittestclass MyTestCase(unittest.TestCase):    def test_greet_raises(self):
self.assertRaises(ValueError, greet, 'bye')
if __name__ == '__main__':
unittest.main()

Alternatively, you can even use a Context Manager as demonstrated in the example below:

import unittestclass MyTestCase(unittest.TestCase):def test_greet_raises(self):
with self.assertRaises(ValueError) as context:
greet('bye')
if __name__ == '__main__':
unittest.main()

We can even test the actual message reported by the Exception being raised using the following approach:

import unittestclass MyTestCase(unittest.TestCase):def test_greet_raises(self):
with self.assertRaises(ValueError) as context :
greet('bye')
self.assertEqual('bye is not allowed', str(context.exception))
if __name__ == '__main__':
unittest.main()

Testing exception handling with pytest

In the same way we can use pytest in order to assert that a function raises an exception.

import pytestdef test_greet():
with pytest.raises(ValueError):
greet('bye')

Likewise, we can also test the error message reported by the Exception we expect to be raised:

import pytestdef test_greet():
with pytest.raises(ValueError, match='bye is not allowed'):
greet('bye')

Final Thoughts

Testing coverage is one of the most important metrics that you can use to tell how well your source code is tested. Apart from good design and efficient code, it is crucial to ensure that every aspect of your code works as expected so that you can minimise the bugs. And this can only be achieved through thorough testing.

In today’s short tutorial we demonstrated how to test functions that raise Exceptions. Apart from testing the “good path” of the flow, it is also important to ensure that errors are handled properly within your source code.

Become a member and read every story on Medium. Your membership fee directly supports me and other writers you read. You’ll also get full access to every story on Medium.

How do you catch a ValueError in Python?

To resolve the ValueError in Python code, a try-except block can be used. The lines of code that can throw the ValueError should be placed in the try block, and the except block can catch and handle the error.

Do I need to import ValueError?

You don't need to import ValueError . It's a built-in so you can always raise ValueError() .

What is the difference between TypeError and ValueError in Python?

Passing arguments of the wrong type (e.g. passing a list when an int is expected) should result in a TypeError , but passing arguments with the wrong value (e.g. a number outside expected boundaries) should result in a ValueError .

How do you check for specific exceptions in Python?

To handle the exception, we have put the code, result = numerator/denominator inside the try block. Now when an exception occurs, the rest of the code inside the try block is skipped. The except block catches the exception and statements inside the except block are executed.