Reputation: 1401
I am trying the unitest to raise the value error when the value is negative using the code below.
A raise error is added : number should be greater than 0 But when I run the code below:
from functools import reduce
import math
import unittest
def calculate_factorial(number):
if number < 0:
print('about to throw value error')
raise ValueError('number should be greater than 0')
elif type(number) != int:
raise TypeError('number should be an integer type')
else:
data = []
for i in range(number):
data.append(number - i)
print(data)
results = reduce((lambda x, y: x * y), data, 1)
return results
class TestCalc(unittest.TestCase):
def test_factorial(self):
print('Function is starting to check for values')
print()
result = calculate_factorial(n)
print('results are:',result)
print()
self.assertEqual(result,math.factorial(n))
def test_n(self):
print('The value of n taken by the class function is:',n)
run = True
while run:
n = int(input('Enter an integer value: '))
if n != -9999:
unittest.main(argv=[''], verbosity=2, exit=False)
else:
run = False
I am getting the error as following. I can see below that my raise value is getting passed through but somehow the test class is not considering it.
test_factorial (__main__.TestCalc) ... ERROR
test_n (__main__.TestCalc) ... ok
======================================================================
ERROR: test_factorial (__main__.TestCalc)
----------------------------------------------------------------------
Traceback (most recent call last):
File "<ipython-input-3-d89c3d44c70d>", line 5, in test_factorial
result = calculate_factorial(n)
File "<ipython-input-2-2ad930b1e911>", line 5, in calculate_factorial
raise ValueError('number should be greater than 0')
ValueError: number should be greater than 0
----------------------------------------------------------------------
Ran 2 tests in 0.010s
FAILED (errors=1)
Upvotes: 0
Views: 1929
Reputation: 3116
As already mentioned in my comments, your test fails because the raised ValueError
is not expected here.
You can extend you test with an if
to handle positive and non-positive values differently.
class TestCalc(unittest.TestCase):
def test_factorial(self):
print('Function is starting to check for values')
print()
if n < 0:
with self.assertRaises(ValueError) as context:
calculate_factorial(n)
self.assertEqual('number should be greater than 0', str(context.exception))
else:
result = calculate_factorial(n)
print('results are:', result)
print()
self.assertEqual(result, math.factorial(n))
def test_n(self):
print('The value of n taken by the class function is:', n)
However, it could be better to have different tests for different value ranges/kinds with fixed values like this:
class TestCalcFixedValues(unittest.TestCase):
def test_factorial_positive(self):
self.assertEqual(calculate_factorial(42), math.factorial(42))
def test_factorial_negative(self):
with self.assertRaises(ValueError) as context:
calculate_factorial(-42)
self.assertEqual('number should be greater than 0', str(context.exception))
def test_factorial_NaN(self):
with self.assertRaises(TypeError) as context:
calculate_factorial("NaN")
self.assertEqual('number should be an integer type', str(context.exception))
(then you will see, that calculate_factorial
has a bug ;))
Upvotes: 2