Unit test assert exception python

2 Ways to use Python Unittest assertRaises() in Python

Python Unittest assertRaises

Python Clear

Python unittest assertraises allows you to verify that a certain exception is raised when your code is run. Python’s unittest module provides a set of tools for testing your code. Note that the python unittest assertRaises function does not call the exceptions __init__ method. It can be used to test both your own code and code from third-party libraries.

How to Use Python Unittest Assertraises

To use python unittest assertRaises , you pass in the exception, you expect to be raised as well as a callable that will execute the code you want to test. assertRaises will then automatically verify that the correct exception is raised.

In this article, we’ll take a closer look at how to use the assertRaises method, with some practical examples.

Parameters

assertRaises(exception, callable, *args, **kwds)
  • exception – Exception class expected to be raised by callable .
  • callable – Function to be called. A string identifying a callable object may also be supplied. The callable will be invoked with args and kwds as appropriate.
  • *args – Positional arguments passed to callable when invoked.
  • **kwds – Keyword arguments passed to callable when invoked.

Returns:

Returns : The return value from calling callable (or None if an exception is not raised).

Читайте также:  Img no repeat in html

Basic usage

Example – 1

Let’s start with a very simple example for python unittest assertraises. We have a function that raises a ValueError if the input value is negative:

def raise_if_negative(value): if value < 0: raise ValueError('Value cannot be negative')

We can write a test for this using assertRaises :

import unittest class TestRaiseIfNegative(unittest.TestCase): def test_raise_if_negative(self): with self.assertRaises(ValueError): raise_if_negative(-1)

The with the statement is used here to create a context manager. This allows us to write the test in a more “Pythonic” way, without having to explicitly call the assertRaises method. The advantage of this approach is that it makes the text more readable and easier to maintain.

Example – 2

We have a function that converts a string to uppercase, but it fails if the input string is empty:

def to_upper(value): if not value: raise ValueError('Value cannot be empty') return value.upper()

We can write a test for this using assertRaises :

import unittest class TestToUpper(unittest.TestCase): def test_to_upper(self): with self.assertRaises(ValueError): to_upper('')

If you run this test, you’ll see that it fails with the following error message:

AssertionError: ValueError not raised by to_upper

How can this be? We clearly defined a ValueError in our function, so why is the test failing?

The reason is that the assertRaises method only catches exceptions that are raised in the with block. In our case, the to_upper function is never called, so the exception is never raised.

To fix this, we can explicitly call the function inside the with block:

import unittest class TestToUpper(unittest.TestCase): def test_to_upper(self): with self.assertRaises(ValueError): to_upper('')

Now if you run the test, it passes:

If you want to be able to call the function outside of the with block, you can store it in a variable:

import unittest class TestToUpper(unittest.TestCase): def test_to_upper(self): to_upper_fn = to_upper('') with self.assertRaises(ValueError): to_upper_fn() 

Verifying the Exception Message

In the previous section, we saw how to verify that a certain code path is reached when an exception is raised. But sometimes it’s also important to verify the exception message.

The assertRaises method allows us to do this by passing it an additional argument: a function that receives the raised exception as an argument and verifies its contents.

Let’s see how this works with our example from the previous section:

import unittest def test_to_upper(self): with self.assertRaises(ValueError): to_upper('')

If we run this test, it fails:

AssertionError: ValueError not raised by to_upper

To fix this, we can pass a function that verifies the exception message:

import unittest def test_to_upper(self): with self.assertRaises(ValueError) as cm: to_upper('') self.assertEqual(str(cm.exception), 'Value cannot be empty')

The assertEqual method is used here to verify that the exception message is equal to the expected message.

If you run the test now, it passes:

Python Unittest assertRaises Output

Verifying the Exception Type

In addition to verifying the exception message, there are also cases where you need to verify the exception type. For example, you might have a function that can raise either a ValueError or an AttributeError , and you want to verify that only a ValueError is raised:

def do_something(value): if value == 'a': raise ValueError('Invalid value') elif value == 'b': raise AttributeError('Invalid value')

In this case, we can use the assertRaises the method with multiple arguments:

import unittest def test_do_something(self): with self.assertRaises(ValueError): do_something('a') with self.assertRaises(AttributeError): do_something('b')

If we try to call do_something with a value that doesn’t raise any exception, the test fails:

AssertionError: AttributeError not raised by do_something

To fix this, we can add a third with block that verifies that no exception is raised:

import unittest def test_do_something(self): with self.assertRaises(ValueError): do_something('a') with self.assertRaises(AttributeError): do_something('b') with self.assertRaises(Exception): # any exception do_something('c')

If you run the test now, it passes:

Conclusion

In this article, we’ve seen how to use python unittest assertRaises method to write tests that verify that a certain code path is reached when an exception is raised. We’ve also seen how to use this method to verify the exception message and type.

Keep in mind that the assertRaises method can only be used with exceptions that are raised in the with block. This means that you might need to explicitly call the function that raises the exception, as we saw in the examples above.

References

That’s all for this post. To be up to date with our latest posts follow Python Clear. Let’s learn together!

Источник

Python Assert Exception

Python Assert Exception

  1. Using Context Manager to Catch Python Assert Exception
  2. Using Keyword Arguments to Catch Python Assert Exception

This article brings one to an understanding of assert as a unit of test, to test that the functions can throw exceptions(errors detected during code execution) without necessarily exiting the execution. In other words, the thrown exception is encapsulated.

This test will pass if an exception is raised. An error is thrown if a different exception other than the one expected is thrown. In an instance where there is no raised exception at all, the test fails.

Using Context Manager to Catch Python Assert Exception

Similar to how it allows the allocation and release of resources when necessarily required in the general python concept, the context here gets hold of the actual exception object being thrown during the test.

It stores this exception attribute in the object if there is a need for an additional performance check on the raised exception.

To test that a function fails or passes whether an exception is thrown or not, we will employ TestCase.assertRaises from the unittest module.

Let’s see a practical example using the context manager.

import unittest class TestCase(unittest.TestCase):  def test_nameerror(self):  with self.assertRaises(Exception):  100 * (someNumber/5)  if __name__ == '__main__':  unittest.main() 

In the example code,the test passes because we expect an exception to be thrown. We are dividing 5 by an undefined variable someNumber . Therefore, the function throws a NameError exception. Hence, our test passes as displayed by the . in the first line of the output.

Let’s see an example where the test fails when an exception is not thrown.

import unittest class TestCase(unittest.TestCase):  def test_nameerror(self):  with self.assertRaises(Exception):  someNumber = 10  100 * (someNumber/5)  if __name__ == '__main__':  unittest.main() 
F ====================================================================== FAIL: test_nameerror (__main__.MyTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example Articles\Article Requirement Spec and Example Articles\fah.py", line 106, in test_nameerror  100 * (someNumber/5) AssertionError: Exception not raised  ---------------------------------------------------------------------- Ran 1 test in 0.002s  FAILED (failures=1) 

In this example code, we define a value for someNumber then we perform the arithmetic expression with it.

The output shows us that the test fails as expected. We do not expect any NameError exception to be thrown this time since a defined value for someNumber does exist.

We can as well implement the context manager using user-defined exceptions like in the following example.

import unittest def user_function():  raise Exception('A use defined exception')  class MyTestCase(unittest.TestCase):  def test_userexception(self):  with self assertRaises(Exception) as context:  user_function()   self.assertTrue('A use defined exception' in str(context.exception))  if __name__ == '__main__':  unittest.main() 

Remember to use str to enclose the context.exception to avoid getting a TypeError.

We introduce assertTrue , a unittest library that compares a test value with true in unit testing.

You can also opt to use assertIn instead of assertTrue.

import unittest def user_function():  raise Exception('A use defined exception')  class MyTestCase(unittest.TestCase):  def test_userexception(self):  with self assertRaises(Exception) as context:  user_function()   self.assertIn('A use defined exception', str(context.exception))  if __name__ == '__main__':  unittest.main() 

We see the same output where the test passes will be produced.

Using Keyword Arguments to Catch Python Assert Exception

Unlike with the context manager, where we only pass the exception to assertRaises() , we also pass the function call and the function’s parameters as keyword arguments to evoke the exception.

Syntax

assertRaises(exception, function, *args, **keywords) 
import unittest class MyTestCase(unittest.TestCase):  def test_division_by_error(self):  import operator  self.assertRaises(ZeroDivisionError, operator.floordiv, 55, 0)  if __name__ == '__main__':  unittest.main() 

The example code above used assertRaises() with keyword arguments. We passed to it the ZeroDivisionError exception expected after trying to divide a number with zero. We imported the operator function used with the floordiv operator function as the second argument. Parameter values here are the third parameters - 55 to be divided by 0.

The last application of assert is when we pass in a different exception other than the expected one to assertRaises(). An error is produced instead.

Using the same example code we have just used above, let’s implement this.

import unittest class MyTestCase(unittest.TestCase):  def test_division_by_error(self):  import operator  self.assertRaises(TypeError, operator.floordiv, 55, 0)  if __name__ == '__main__':  unittest.main() 
E ====================================================================== ERROR: test_division_by_error (__main__.MyTestCase) ---------------------------------------------------------------------- Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example Articles\user.py", line 16, in test_division_by_error  self.assertRaises(TypeError, operator.floordiv, 55, 0)  File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 733, in assertRaises  return context.handle('assertRaises', args, kwargs)  File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 201, in handle  callable_obj(*args, **kwargs) ZeroDivisionError: integer division or modulo by zero  ---------------------------------------------------------------------- Ran 1 test in 0.031s  FAILED (errors=1) 

From the output, an error traceback is produced. We expect a ZeroDivisionError exception when we divide a number by zero. Instead, we pass in a TypeError exception applied when performing an arithmetic operation between different data types, say a string and an integer.

Related Article - Python Exception

Источник

Оцените статью