美文网首页
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