0


python之测试代码

测试函数:

要学习测试,就必须要测试的代码,下面是一个简单的函数,他接受名和性并返回整洁的姓名:

举例:
name_function文件中的内容为:

#功能为返回以标题为形式的简洁的姓名
defget_formatted_name(first,last):
    full_name=f"{first}{last}"return full_name.title()
from name_function import get_formatted_name
print("Enter 'q' at any time to quit")while True:
    first=input("\nplease give me a first name:")if first=='q':break
    last=input("please give me a last name:")if last=='q':break
    formatted_name=get_formatted_name(first,last)#调用name_function函数
    print(f"\tNeatly formatted name:{formatted_name}")

输出结果如下所示:

Enter 'q' at any time to quit

please give me a first name:jains
please give me a last name:joplin
    Neatly formatted name:Jainsjoplin#首字母大写,标题形式

please give me a first name:q

Process finished with exit code 0

现在假设要修改get_formatted_name,使其还能处理中间名,这样所时,要确保这个函数处理只含有名和姓的姓名的方式,为此,可在每次修改get_formatted_name后都进行测试,再运行程序,并输入像jains/joplin的姓名。

但是这样很繁琐,好在python提供了一种自动测试函数输出的高效方式,倘若对get_formatted_name()进行自动测试,就能始终确信当前提供测试过的姓名时,该函数都能正确工作。

单元测试和测试用例:

python标准库中的模块unittest提供了代码测试工具,但单元测试用于核实函数的某个方面没有问题。

测试用例是一组单元测试,它们一道核实函数在各种情形下的行为都符合要求,良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形下的测试。

全覆盖的测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。对于大型项目,要进行全覆盖测试可能很难,通常,最初只要针对代码的重要行为编写测试即可,等到项目被广泛使用时在考虑全覆盖。

可通过的测试:

要为函数编写测试用例,可先导入模块unittest和要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。

举例:
使用我们上述提到的实例,返回以标题为形式的简洁的姓名

test_name_function.py
运行该文件时,所有以test_打头的方法都将自动运行

import unittest
from name_function import get_formatted_name
classNameTestCase(unittest.TestCase):#创建名为NameTestCase的类,用于包含一系列针对get_formatted_name的单元测试#这个类的命名并不是唯一的,但是最好让他看起来与要测试的函数相关并包含Test的字样#这个类必须继承unittest.TesetCase类,这样python才知道如何运行编写的程序的运行deftest_first_last_name(self):#NameTestCase类只包含test_first_last_name一个方法# 用于测试get_formatted_name的一个方面
        formatted_name=get_formatted_name("janis","joplin")
        self.assertEqual(formatted_name,"Janis Joplin")
        #断言方法:用来核实得到的结果与期望的结果一致
        #assertEqual(arg1,arg2,msg(期望值)),arg1==arg2通过, False返回msg
if __name__=='__main__':#if代码块是用来检验特殊变量__name__,这个变量是在程序执行时设置的。
#如果这个文件作为主程序执行,变量__name__将被设置'__main__'
'''
在这里,调用 unittest.main()来运行测试用例,但他如果不是作为主程序运行,
则变量__name__的值将不是'__main__',因此不会调用unittest.main()
'''
    unittest.main()

name_function.py

defget_formatted_name(first,last):
    full_name=f"{first}{last}"return full_name.title()

输出结果如下所示:

.      #表明有一个测试通过了
----------------------------------------------------------------------
Ran 1 test in0.000s  #指出python运行了一个测试,消耗时间不到0.001秒

OK    #表明该测试用例中的所有单元测试都通过了

未通过的测试:

现在我们给get_formatted_name指定一个新的版本,使其能够处理中间名,但同时故意让该函数无法正确处理像’janis joplin‘这种,只有姓和名的名字,看看会发生什么情况:

defget_formatted_name(first, last):
    full_name=f"{first}{middle}{last}"return full_name.title()

输出结果:

E                   #测试用例中有一个单元测试导致了该错误
======================================================================
ERROR: test_first_last_name (__main__.NameTestCase)#test_first_last_name导致了该错误----------------------------------------------------------------------
#下面的Traceback 指出调用get_formatted_name("janis","joplin")有问题,由于缺少一个必不可少的位置参数
Traceback (most recent call last):
  File "C:/Users/Lenovo/PycharmProjects/pythonProject4/test_name_function.py", line 19,in test_first_last_name
    formatted_name=get_formatted_name("janis","joplin")
TypeError: get_formatted_name() missing 1 required positional argument:'last'----------------------------------------------------------------------
Ran 1 test in0.001s

FAILED (errors=1)#整个测试未通过,因为在运行该测试用例的时候发生了一个错误

测试未通过怎么办:

如果你检查的条件没错,测试通过意味着函数的行为是对的,而测试未通过意味着编写的新代码有错,因此,测试未通过时,不要修改测试,而应修复导致测试不能通过的代码,检查刚刚对函数所做的修改,找出导致函数行为不符合预期的修改。

在上述示例中,get_formatted_name()以前只需要名和姓两个实参,但是现在要求提供名,中间名,和姓,新增的中间名参数是必不可少的,这导致get_formatted_name()的行为不符合预期。就这里而言,最佳的选择是让中间名变为可选的,这样做后,使用只有姓和名而没有中间名的姓名进行测试时,测试也能顺利通过,而且也可以接受中间名。

下面我们就对get_formatted_name()进行修改,将中间名设置为可选的,然后再次运行这个测试用例。如果通过了,就接着确认该函数能够妥善处理中间名。

具体操作如下:

defget_formatted_name(first,last, middle=''):if middle:#存在即返回含有middle的姓名
        full_name=f"{first}{middle}{last}"else:#不存在即返回不含有middle的姓名
        full_name=f"{first}{last}"return full_name.title()

此时,测试顺利通过。

.----------------------------------------------------------------------
Ran 1 test in0.000s

OK

添加新测试:

确定get_formatted_name()又能正确处理简单的姓名后,我们再编写一个测试,用于测试含中间名。为此,在NameTestCase类中再添加一个方法:

test_name_function.py中添加新的测试:

#该测试我们想测试的目的是正确处理像"Wolfgang Amadeus Mozart"这样的姓名
    deftest_first_last_middle_name(self):#方法名必须以test_开头,这样我们在运行test_name_function.py时自动运行。
        formatted_name = get_formatted_name("wolfgang",'mozart',"amadeus")
        self.assertEqual(formatted_name,"Wolfgang Amadeus Mozart")

可以在TestCase类中使用很长的方法名,而这些方法名必须是描述性的,这样你才能看懂测试未通过时的输出,而这些方法由python自动调用,因此,你根本不用编写调用它们的代码。

输出结果如下:

两个测试都通过了!

..----------------------------------------------------------------------
Ran 2 tests in0.000s

OK

现在我们能够无比信任get_formatted_name()不仅可以处理像’janis joplin‘这种,还可以处理像"Wolfgang Amadeus Mozart"这样的姓名了。


本文转载自: https://blog.csdn.net/m0_64365419/article/details/125961823
版权归原作者 从未止步.. 所有, 如有侵权,请联系我们删除。

“python之测试代码”的评论:

还没有评论