1

I need to write test cases using unit test in Python for testing circle creation.

  • Define a class Circle with method __init__ which initializes a circle with attribute radius, having following restrictions:

    • radius must be numeric value, if not raise type error with error message "radius must be number".

    • radius must be between 0 to 1000 inclusive on both sides, if not raise the value error with error message "radius must be between 0 and 1000 inclusive"

    • Define a class method area and circumference which must return values rounded off to 2 decimals.

    Complete the definition of class TestingCircleCreation which tests the behavior of __init__ method as specification below.

  • Define the test method of test_creating_circle_with_numerical_radius which creates circle with radius 2.5 and check if radius matches to value 2.5

  • Define the test method test_creating_circle_with_negative_radius which checks if value error exception is raised with the error message "radius must be between 0 and 1000 inclusive", while creating circle of radius 2.5.

  • Define the test method test_creating_circle_with_greaterthan_radius which checks if ValueError exception is raised with error message "radius must be between 0 and 1000 inclusive", while creating circle of radius 1000.1.

  • Define the test method test_creating_circle_with_nonnumeric_radius, which checks if TypeError exception is raised with error message "radius must be number" while creating circle of radius 'hello'.

I tried below but it is failing with error as

Traceback (most recent call last):
  File "..\Playground\", line 86, in <module>
    pass_count = pass_count[0]
IndexError: list index out of range

The code:

import inspect
import re
import unittest
import math

# Define below the class 'Circle' and it's methods with proper doctests.
class Circle:
    def __init__(self, radius):
        # Define the initialization method below
        try:
            if not isinstance(radius, (int, float)):
                raise TypeError 
            elif 1000 >=radius>=0:
                    self.radius=radius 
            else:
                raise ValueError        
        except ValueError:
            raise ValueError("radius must be between 0 and 1000 inclusive")
        except TypeError:
            raise TypeError("radius must be a number")
        
    def area(self):
        # Define the area functionality below
        y=math.pi*(self.radius**2)
        return round(y,2)
               
    def circumference(self):
        # Define the circumference functionality below
        x=math.pi*2*self.radius
        return round(x,2)
        
class TestCircleCreation(unittest.TestCase):
    def test_creating_circle_with_numeric_radius(self):
        # Define a circle 'c1' with radius 2.5 and check if 
        # the value of c1.radius equal to 2.5 or not
        c1=Circle(2.5)        
        self.assertEqual(c1.radius,2.5)

    def test_creating_circle_with_negative_radius(self):
        # Try Defining a circle 'c' with radius -2.5 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"
        c=Circle(-2.5)
        self.assertEqual(c.radius,-2.5)
        self.assertRaises(ValueError)      

    def test_creating_circle_with_greaterthan_radius(self):
        # Try Defining a circle 'c' with radius 1000.1 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"
        c=Circle(1000.1)        
        self.assertEqual(c.radius,1000.1)
        self.assertRaises(ValueError)        
        
    def test_creating_circle_with_nonnumeric_radius(self):
        # Try Defining a circle 'c' with radius 'hello' and see 
        # if it raises a TypeError with the message
        # "radius must be a number"
        c=Circle('hello')      
        self.assertEqual(c.radius,'hello')
        self.assertRaises(TypeError)        

if __name__ == '__main__':
    fptr = open('output.txt', 'w')
    
    runner = unittest.TextTestRunner(fptr)
    
    unittest.main(testRunner=runner, exit=False)
    
    fptr.close()
    
    with open('output.txt') as fp:
        output_lines = fp.readlines()
    
    pass_count = [ len(re.findall(r'\.', line)) for line in output_lines if line.startswith('.')
                     and line.endswith('.\n')]
    
    pass_count = pass_count[0]
    print(str(pass_count))
                       
    doc1 = inspect.getsource(TestCircleCreation.test_creating_circle_with_numeric_radius)
    doc2 = inspect.getsource(TestCircleCreation.test_creating_circle_with_negative_radius)
    doc3 = inspect.getsource(TestCircleCreation.test_creating_circle_with_greaterthan_radius)
    doc4 = inspect.getsource(TestCircleCreation.test_creating_circle_with_nonnumeric_radius)
    
    assert1_count = len(re.findall(r'assertEqual', doc1))
    print(str(assert1_count))
    
    assert1_count = len(re.findall(r'assertEqual', doc2))
    assert2_count = len(re.findall(r'assertRaises', doc2))
    print(str(assert1_count), str(assert2_count))
    
    assert1_count = len(re.findall(r'assertEqual', doc3))
    assert2_count = len(re.findall(r'assertRaises', doc3))
    print(str(assert1_count), str(assert2_count))
    
    assert1_count = len(re.findall(r'assertEqual', doc4))
    assert2_count = len(re.findall(r'assertRaises', doc4))
    print(str(assert1_count), str(assert2_count))

4 Answers 4

2
import inspect
import re
import unittest
import math

class Circle:    
    def __init__(self, radius):
        # Define the initialization method below
        self.radius=radius
        if not isinstance(self.radius,(int,float)):
            raise TypeError("radius must be a number")
        elif(self.radius>1000 or self.radius<0):
            raise ValueError("radius must be between 0 and 1000 inclusive")
        else:
            pass
    def area(self):
        # Define the area functionality below
        return math.pi*(self.radius**2)
    def circumference(self):
        return 2*math.pi*self.radius
        # Define the circumference functionality below

class TestCircleCreation(unittest.TestCase):
    def test_creating_circle_with_numeric_radius(self):
        # Define a circle 'c1' with radius 2.5 and check if 
        # the value of c1.radius equal to 2.5 or not
        c1=Circle(2.5)
        self.assertEqual(c1.radius,2.5)
       
    def test_creating_circle_with_negative_radius(self):
        # Try Defining a circle 'c' with radius -2.5 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"
        with self.assertRaises(ValueError) as e:
            c=Circle(-2.5)
        self.assertEqual(str(e.exception),"radius must be between 0 and 1000 inclusive")
        
    def test_creating_circle_with_greaterthan_radius(self):
        # Try Defining a circle 'c' with radius 1000.1 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"        
        with self.assertRaises(ValueError) as e:
            c=Circle(1000.1)
        self.assertEqual(str(e.exception),"radius must be between 0 and 1000 inclusive")
       
    def test_creating_circle_with_nonnumeric_radius(self):
        # Try Defining a circle 'c' with radius 'hello' and see 
        # if it raises a TypeError with the message
        # "radius must be a number"   
        with self.assertRaises(TypeError) as e:
            c=Circle("hello")
        self.assertEqual(str(e.exception),"radius must be a number")     

if __name__ == '__main__':
    fptr = open('output.txt', 'w')
    
    runner = unittest.TextTestRunner(fptr)
    
    unittest.main(testRunner=runner, exit=False)
    
    fptr.close()
    
    with open('output.txt') as fp:
        output_lines = fp.readlines()
    
    pass_count = [ len(re.findall(r'\.', line)) for line in output_lines if line.startswith('.')
                     and line.endswith('.\n')]
    
    pass_count = pass_count[0]          
    print(str(pass_count))
                       
    doc1 = inspect.getsource(TestCircleCreation.test_creating_circle_with_numeric_radius)
    doc2 = inspect.getsource(TestCircleCreation.test_creating_circle_with_negative_radius)
    doc3 = inspect.getsource(TestCircleCreation.test_creating_circle_with_greaterthan_radius)
    doc4 = inspect.getsource(TestCircleCreation.test_creating_circle_with_nonnumeric_radius)
    
    assert1_count = len(re.findall(r'assertEqual', doc1))
    print(str(assert1_count))
    
    assert1_count = len(re.findall(r'assertEqual', doc2))
    assert2_count = len(re.findall(r'assertRaises', doc2))
    print(str(assert1_count), str(assert2_count))
    
    assert1_count = len(re.findall(r'assertEqual', doc3))
    assert2_count = len(re.findall(r'assertRaises', doc3))
    print(str(assert1_count), str(assert2_count))
    
    assert1_count = len(re.findall(r'assertEqual', doc4))
    assert2_count = len(re.findall(r'assertRaises', doc4))
    print(str(assert1_count), str(assert2_count))
Sign up to request clarification or add additional context in comments.

Comments

2
class Circle:
    def __init__(self, radius):
        # Define initialization method:
        self.radius = 0
        if not isinstance(radius,(int,float)):
            raise TypeError("radius must be a number")
        elif radius < 0 or radius > 1000:
            raise ValueError("radius must be between 0 and 1000 inclusive")
        else:
            self.radius = radius
        
    def area(self):
        # Define area functionality:
        return round(math.pi*(self.radius**2),2)
               
    def circumference(self):
        # Define circumference functionality:
        return round(2*math.pi*self.radius)

class TestCircleCreation(unittest.TestCase):
    def test_creating_circle_with_numeric_radius(self):
        # Define a circle 'c1' with radius 2.5, and check if 
        # the value of c1.radius is equal to 2.5 or not.
        c1 = Circle(2.5)
        self.assertEqual(c1.radius, 2.5)

    def test_creating_circle_with_negative_radius(self):
        # Define a circle 'c' with radius -2.5, and check 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive".
        with self.assertRaises(ValueError) as e:
            c = Circle(-2.5)
        self.assertEqual(str(e.exception),"radius must be between 0 and 1000 inclusive")
     
    def test_creating_circle_with_greaterthan_radius(self):
        # Define a circle 'c' with radius 1000.1, and check 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive".        
        with self.assertRaises(ValueError) as e:
            c = Circle(1000.1)
        self.assertEqual(str(e.exception),"radius must be between 0 and 1000 inclusive")      

    def test_creating_circle_with_nonnumeric_radius(self):
        # Define a circle 'c' with radius 'hello' and check 
        # if it raises a TypeError with the message
        # "radius must be a number".        
        with self.assertRaises(TypeError) as e:
            c = Circle("hello")
        self.assertEqual(str(e.exception), "radius must be a number")

Comments

0

I removed repeated self.assertEqual(c.radius,-2.5) assertions as they are already handled by another unit test (test_creating_circle_with_numeric_radius(self)), and causing your unittests to fail. See here for example:

    def test_creating_circle_with_negative_radius(self):
        c=Circle(-2.5)
        self.assertEqual(c.radius,-2.5) # Throwing ValueError
        self.assertRaises(ValueError)

In your code, the assertEquals(c.radius,-2.5) attempts to determine whether the value c.radius is equal to -2.5. This value is not set though because -2.5 is outside the acceptable range and a ValueError is thrown instead. This prevents the self.assertRaises(ValueError) from being checked. By removing assertEquals from the tests and leaving it as it's own independent test, self.assertRaises(ValueError) executes and allows you to see where your code does not adhere to the requirements.

I've changed your tests to use context management to catch the exceptions thrown which has made the tests work correctly

class TestCircleCreation(unittest.TestCase):

    def test_creating_circle_with_numeric_radius(self):
        # Define a circle 'c1' with radius 2.5 and check if 
        # the value of c1.radius equal to 2.5 or not
        c1 = Circle(2.5)        
        self.assertEqual(c1.radius, 2.5)

    def test_creating_circle_with_negative_radius(self):
        # Try Defining a circle 'c' with radius -2.5 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"
        with self.assertRaises(ValueError) as E:
            c = Circle(-2.5)     

    def test_creating_circle_with_greaterthan_radius(self):
        # Try Defining a circle 'c' with radius 1000.1 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"
        with self.assertRaises(ValueError) as E:
            c = Circle(1000.1)        

    def test_creating_circle_with_nonnumeric_radius(self):
        # Try Defining a circle 'c' with radius 'hello' and see 
        # if it raises a TypeError with the message
        # "radius must be a number"
        with self.assertRaises(TypeError) as E:
            c = Circle('hello')        

Although this would also have worked:

class TestCircleCreation(unittest.TestCase):

    def test_creating_circle_with_numeric_radius(self):
        c1 = Circle(2.5)        
        self.assertEqual(c1.radius, 2.5)

    def test_creating_circle_with_negative_radius(self):
        self.assertRaises(ValueError, Circle, -2.5)

    def test_creating_circle_with_greaterthan_radius(self):
        self.assertRaises(ValueError, Circle, 1000.1)


    def test_creating_circle_with_nonnumeric_radius(self):
        self.assertRaises(TypeError, Circle, 'hello')

PS: I advise you to use with open when writing to the file, as you did when reading it back.

    with open('output.txt', 'w') as fptr:
        runner = unittest.TextTestRunner(fptr)
        unittest.main(testRunner=runner, exit=False)

Your checks could be streamlined from

        try:
            if not isinstance(radius, (int, float)):
                raise TypeError 
            elif 1000 >=radius>=0:
                    self.radius=radius 
            else:
                raise ValueError        
        except ValueError:
            raise ValueError("radius must be between 0 and 1000 inclusive")
        except TypeError:
            raise TypeError("radius must be a number")

to:

            if not isinstance(radius, (int, float)):
                raise TypeError("radius must be a number")

            if not 1000 >=radius>=0:
                raise ValueError("radius must be between 0 and 1000 inclusive")

            self.radius=radius 

4 Comments

I am getting answer as 4 1 0 1 0 1 0 1 but its still says your answer is incorrect, It has a three checks for assertEqual where exceptions are getting raised, looks like that is causing the issue please suggest
What says the answer is incorrect? What has three assertEqual checks?
In above question, assert_count1 for doc2, doc3, doc4 is expecting assertEqual count.
The first paragraph states that the assertEquals checks were removed, leaving only the independent check. I have now added more detail to explain this.
0
import inspect
import re
import unittest
import math

# Define below the class 'Circle' and it's methods with proper doctests.
class Circle:
    def __init__(self, radius):
        # Define the initialization method below
        try:
            if not isinstance(radius, (int, float)):
                raise TypeError 
            elif 1000 >=radius>=0:
                    self.radius=radius 
            else:
                raise ValueError        
        except ValueError:
            raise ValueError("radius must be between 0 and 1000 inclusive")
        except TypeError:
            raise TypeError("radius must be a number")

    def area(self):
        # Define the area functionality below
        y=math.pi*(self.radius**2)
        return round(y,2)

    def circumference(self):
        # Define the circumference functionality below
        x=math.pi*2*self.radius
        return round(x,2)

class TestCircleCreation(unittest.TestCase):
    def test_creating_circle_with_numeric_radius(self):
        # Define a circle 'c1' with radius 2.5 and check if 
        # the value of c1.radius equal to 2.5 or not
        c1 = Circle(2.5)        
        self.assertEqual(c1.radius, 2.5)

    def test_creating_circle_with_negative_radius(self):
        # Try Defining a circle 'c' with radius -2.5 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"
        c1 = Circle(2.5)        
        self.assertEqual(c1.radius, 2.5)

        with self.assertRaises(ValueError) as E:
            c = Circle(-2.5)     

    def test_creating_circle_with_greaterthan_radius(self):
        # Try Defining a circle 'c' with radius 1000.1 and see 
        # if it raises a ValueError with the message
        # "radius must be between 0 and 1000 inclusive"

        c1 = Circle(2.5)        
        self.assertEqual(c1.radius, 2.5)
        with self.assertRaises(ValueError) as E:
            c = Circle(1000.1)        

    def test_creating_circle_with_nonnumeric_radius(self):
        # Try Defining a circle 'c' with radius 'hello' and see 
        # if it raises a TypeError with the message
        # "radius must be a number"

        c1 = Circle(2.5)        
        self.assertEqual(c1.radius, 2.5)

        with self.assertRaises(TypeError) as E:
            c = Circle('hello')        

if __name__ == '__main__':
    fptr = open('output.txt', 'w')

    runner = unittest.TextTestRunner(fptr)

    unittest.main(testRunner=runner, exit=False)

    fptr.close()

    with open('output.txt') as fp:
        output_lines = fp.readlines()

    pass_count = [ len(re.findall(r'\.', line)) for line in output_lines if line.startswith('.')
                     and line.endswith('.\n')]

    pass_count = pass_count[0]
    print(str(pass_count))

    doc1 = inspect.getsource(TestCircleCreation.test_creating_circle_with_numeric_radius)
    doc2 = inspect.getsource(TestCircleCreation.test_creating_circle_with_negative_radius)
    doc3 = inspect.getsource(TestCircleCreation.test_creating_circle_with_greaterthan_radius)
    doc4 = inspect.getsource(TestCircleCreation.test_creating_circle_with_nonnumeric_radius)

    assert1_count = len(re.findall(r'assertEqual', doc1))

    print(str(assert1_count))

    assert1_count = len(re.findall(r'assertEqual', doc2))
    assert2_count = len(re.findall(r'assertRaises', doc2))
    print(str(assert1_count), str(assert2_count))

    assert1_count = len(re.findall(r'assertEqual', doc3))
    assert2_count = len(re.findall(r'assertRaises', doc3))
    print(str(assert1_count), str(assert2_count))

    assert1_count = len(re.findall(r'assertEqual', doc4))
    assert2_count = len(re.findall(r'assertRaises', doc4))
    print(str(assert1_count), str(assert2_count))

1 Comment

Try this you will get 4 1 1,1 1,1 1,1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.