在Python3中使用单元测试进行单元测试

时间:2019-02-10 11:45:06

标签: python-3.x unit-testing

我需要在python中使用单元测试编写测试用例,以测试圈子的创建。

  • 使用方法 init 定义一个Circle类,该方法将初始化一个具有以下限制的属性半径的cicle。 一种。半径必须为数值,如果不加类型错误,则错误消息为“半径必须为数字”。

b。半径在两边都必须介于0到1000之间(如果不包括在内),则错误消息“半径必须在0到1000之间(包括半径)”会提高数值错误

c。定义一个类方法的区域和周长,必须将其值四舍五入到小数点后两位。

按照下面的说明完成测试行为 init 方法的TestingCircleCreation类的定义。

  • 定义“ test_creating_circle_with_numerical_radius”的测试方法,该方法创建半径为2.5的圆并检查半径是否匹配值2.5

  • 定义测试方法test_creating_circle_with_negative_radius,该方法在创建半径为2.5的圆时,检查是否出现错误消息“半径必须在0到1000之间(包括0和1000之间)”,是否引发了值错误异常。

  • 定义测试方法test_creating_circle_with_greaterthan_radius,该方法在创建半径为1000.1的圆时,检查是否引发了ValueError异常并显示错误消息“半径必须在0到1000之间(包括0和1000之间)”。

  • 定义测试方法test_creating_circle_with_nonnumeric_radius,该方法检查在创建半径为“ hello”的圆时是否引发TypeError异常并显示错误消息“ radius必须为数字”。

我在下面尝试过,但由于

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

代码:

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 个答案:

答案 0 :(得分:1)

进口检查 汇入 导入单元测试 导入数学

班级圈子:

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

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")     

如果名称 =='主要':

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 :(得分:0)

我删除了重复的self.assertEqual(c.radius,-2.5)断言,因为它们已经由另一个单元测试(test_creating_circle_with_numeric_radius(self))处理,并导致您的单元测试失败。例如,请参见此处:

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

在您的代码中,assertEquals(c.radius,-2.5)试图确定值c.radius是否等于-2.5。尽管未设置该值,因为-2.5在可接受的范围之外,而是抛出ValueError。这样可以防止self.assertRaises(ValueError)被检查。通过从测试中删除assertEquals并将其保留为自己的独立测试,self.assertRaises(ValueError)会执行并允许您查看代码不符合要求的地方。

我将您的测试更改为使用上下文管理来捕获引发的异常,从而使测试正常工作

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')        

尽管这也可行:

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:建议您在写入文件时使用with open,就像回读文件时一样。

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

您的支票可以简化

        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")

收件人:

            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 

答案 2 :(得分:0)

进口检查 汇入 导入单元测试 导入数学

在“ 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)

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')        

如果名称 =='主要':

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))

答案 3 :(得分:0)

班级圈子:

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)

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")