I have a file testtest.py that i contains the code
import unittest
def add(self, a, b):
return a + b
class Test(unittest.TestCase):
def test_additon(self):
self.assertRaises(TypeError, add, 1 + '1', msg="Additon failed")
#self.assertRaises(TypeError, lambda: add(1 + '1'), msg="Addition failed")
if __name__ == '__main__':
unittest.main()
The problem is that assertRaises
doesn't catch the exception properly and all my tests keep failing as errors not based on the condition, this is the output that I'm getting:
E
======================================================================
ERROR: test_additon (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "testtest.py", line 9, in test_additon
self.assertRaises(TypeError, add, 1 + '1', msg="Additon failed")
TypeError: unsupported operand type(s) for +: 'int' and 'str'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
I know i can get around it by using lambda (i commented it out in the code) to make my tests properly catch the exceptions, but according to the docs, passing a callable and the arguments to assertRaises
should work, as it will call the function internally by itself and be able to trap any exception that was raised.
assertRaises(*callable*, *args*, *kwargs*)
but it doesn't
if i run it with lambda which is a callable that would be evaluated later by assertRaises
, it works as expected and i get this
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
I'm running python 3.5
Python 3.5.2 (default, Jun 28 2016, 08:46:01)
[GCC 6.1.1 20160602] on linux
but i also get the same behaviour with python2.7
There are two ways you can use assertRaises: using keyword arguments. Just pass the exception, the callable function and the parameters of the callable function as keyword arguments that will elicit the exception. Make a function call that should raise the exception with a context.
pytest supports running Python unittest -based tests out of the box. It's meant for leveraging existing unittest -based test suites to use pytest as a test runner and also allow to incrementally adapt the test suite to take full advantage of pytest's features.
Pytest has rich inbuilt features which require less piece of code compared to unittest. In the case of unittest, we have to import a module, create a class and then define testing functions inside the class. But in the case of pytest, we have to define the functions and assert the conditions inside them.
In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause. We can thus choose what operations to perform once we have caught the exception.
You should be passing arguments to the callable separately, as separate arguments:
self.assertRaises(TypeError, add, 1, '1', msg="Additon failed")
Try
def test_additon(self):
with self.assertRaises(TypeError):
add(1 + '1')
The problem is that the exception is raised during argument evaluation before self.assertRaises can kick in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With