美文网首页
79、测试函数

79、测试函数

作者: 陈容喜 | 来源:发表于2017-10-20 21:33 被阅读0次

    函数get_formatted_name() 将名和姓合并成姓名,在名和姓之间加上一个空格,并将它们的首字母都大写,再返回结果。为核实get_formatted_name() 像期望的那样工作,我们来编写一个使用这个函数的程序。程序names.py让用户输入名和姓,并显示整洁的全名:

    # -*- coding: utf-8 -*-
    def get_formatted_name(first,last):
        """Generate a neatly formatted full name."""
        full_name = first + " " + last
        return  full_name.title()
    

    再编写一段测试代码,从name_function.py中导入函数get_formatted_name() 。用户可输入一系列的名和姓,并看到格式整洁的全名:

    # -*- coding: utf-8 -*-
    from name_function import get_formatted_name
    
    print("Enter 'q' at any time to quit.")
    while True:
        first = raw_input("\nPlease give me a first name: ")
        if first == "q":
            break
        last = raw_input("Please give me a last name: ")
        if last == "q":
            break
    
        formatted_name = get_formatted_name(first,last)
        print("\nNeatly formatted name: " + formatted_name + ".")
    

    测试结果如下:

    Enter 'q' at any time to quit.
    
    Please give me a first name: janis
    Please give me a last name: joplin
    
    Neatly formatted name: Janis Joplin.
    
    Please give me a first name: leilei
    Please give me a last name: 23
    
    Neatly formatted name: Leilei 23.
    
    Please give me a first name: bob
    Please give me a last name: dylan
    
    Neatly formatted name: Bob Dylan.
    
    Please give me a first name: q
    
    Process finished with exit code 0
    

    从测试的结果可以看到,得到的姓名正确无误。
    可通过的测试
    为函数编写测试用例,可先导入模块
    unittest 以及要测试的函
    数,再创建一个继承unittest.TestCase 的类,并编写一系列方法对函数行为的不同方面进行测试。

    # -*- coding: utf-8 -*-
    import unittest
    from name_function import  get_formatted_name
    
    class NamesTestCase(unittest.TestCase): # 子类NamesTestCase继承unittest.TestCase类
        """测试name_function.py"""
    
        def test_first_last_name(self):
            """能否正确处理像Janis Joplin这样的姓名?"""
            formatted_name = get_formatted_name("janis","joplin")
            self.assertEqual(formatted_name,"Janis Joplin") # self.assertEqual测试代码并返回结果
    
    unittest.main()
    

    们使用了unittest 类的断言的方法用来核实得到的结果是否与期望的结果是否一致。我们知道在函数get_formatted_name中,输入"janis","joplin",最后得到的结果应为"Janis Joplin",接下来就看测试的结果是否是预测的那样。
    代码行self.assertEqual(formatted_name, 'Janis Joplin') 的意思是说:“将formatted_name 的值同字符串'Janis Joplin' 进行比较,并把结果返回。
    测试结果如下:

    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.000s
    
    OK
    
    Process finished with exit code 0
    

    在测试结果中第1行的句点表明有一个测试通过了。
    接下来的一行指出Python运行了一个测试,消耗的时间不到0.001秒。
    最后的OK 表明该测试用例中的所有单元测试都通过了。
    未通过的测试
    我们来修改函数get_formatted_name() ,使其能够处理中间名,故意让这个函数无法正确地处理像Janis Joplin这样只有名和姓的姓名。

    # -*- coding: utf-8 -*-
    def get_formatted_name(first,middle,last):
        """Generate a neatly formatted full name."""
        full_name = first + " " + middle + " " +  last
        return  full_name.title()
    

    再运行程序测试

    # -*- coding: utf-8 -*-
    import unittest
    from name_function import  get_formatted_name
    
    class NamesTestCase(unittest.TestCase):
        """测试name_function.py"""
    
        def test_first_last_name(self):
            """能否正确处理像Janis Joplin这样的姓名?"""
            formatted_name = get_formatted_name("janis","joplin")
            self.assertEqual(formatted_name,"Janis Joplin") 
    
    unittest.main()
    

    测试结果如下:

    E
    ======================================================================
    ERROR: test_first_last_name (__main__.NamesTestCase)
    能否正确处理像Janis Joplin这样的姓名?
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "D:/Python/python_work/test/test_name_function.py", line 10, in test_first_last_name
        formatted_name = get_formatted_name("janis","joplin")
    TypeError: get_formatted_name() takes exactly 3 arguments (2 given)
    
    ----------------------------------------------------------------------
    Ran 1 test in 0.001s
    
    FAILED (errors=1)
    
    Process finished with exit code 1
    

    从测试结果可以看出测试未通过。
    其中第1行输出只有一个字母E,它指出测试用例中有一个单元测试导致了错误。
    接下来可以看到出错的原因是:NamesTestCase 中的test_first_last_name() 函数导致了错误。
    "Ran 1 test in 0.001s"这一句指出Python运行了一个测试,消耗的时间不到0.001秒。
    "FAILED (errors=1)"这一句整个测试用例都未通过,因为运行该测试用例时发生了一个错误。

    当遇到测试未通过时,先检查测试的条件是否有错,如果没错那就着重检查导致测试不能通过的代码:像上面的例子就要检查刚对函数所做的修改,找出导致函数行为不符合预期的修改。
    在上述例子中,get_formatted_name() 函数以前只需要两个实参——名和姓,但现在它要求提供名、中间名和姓。因此,我们把新增的中间名变为可选的,可在函数定义中将形参
    middle 移到形参列表末尾,并将其默认值指定为一个空字符串。我们还要添加一个if 测试,如果提供了中间名就创建 名 + 中间名 + 姓,如果不提供中间名就创建 名 + 姓
    所以函数get_formatted_name()修改为:

    # -*- coding: utf-8 -*-
    def get_formatted_name(first,last,middle = ""):
        """生成整洁的姓名"""
        if middle:
            full_name = first + " " + middle + " " +  last
        else:
            full_name = first + " " +  last
        return  full_name.title()
    

    测试结果为:

    # -*- coding: utf-8 -*-
    import unittest
    from name_function import  get_formatted_name
    
    class NamesTestCase(unittest.TestCase): 
        """测试name_function.py"""
    
        def test_first_last_name(self):
            """能否正确处理像Janis Joplin这样的姓名?"""
            formatted_name = get_formatted_name("janis","joplin")
            self.assertEqual(formatted_name,"Janis Joplin") 
    
    unittest.main()
    
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.001s
    
    OK
    
    Process finished with exit code 0
    

    如果要增加测试中间名,我们需要在NamesTestCase 类中再添加一个方法:

    # -*- coding: utf-8 -*-
    import unittest
    from name_function import  get_formatted_name
    
    class NamesTestCase(unittest.TestCase):
        """测试name_function.py"""
    
        def test_first_last_name(self):
            """能否正确处理像Janis Joplin这样的姓名?"""
            formatted_name = get_formatted_name("janis","joplin")
            self.assertEqual(formatted_name,"Janis Joplin")
    
        def test_first_last_middle_name(self):
            """是否能够正确地处理像Wolfgang Amadeus Mozart这样的姓名?"""
            formatted_name = get_formatted_name("wolfgang","mozart","amadeus")
            self.assertEqual(formatted_name,"Wolfgang Amadeus Mozart")
    
    unittest.main()
    

    测试结果:

    ..
    ----------------------------------------------------------------------
    Ran 2 tests in 0.000s
    
    OK
    
    Process finished with exit code 0
    

    相关文章

      网友评论

          本文标题:79、测试函数

          本文链接:https://www.haomeiwen.com/subject/ftivuxtx.html