Python测试代码1之--unittest

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiangxuefengsboke456/article/details/72843148

        在程序员编写函数或者类时,也可以为其编写测试代码,我们可以把这种测试称之为--单元测试。通过测试,可以确定代码面对各种输入都能够按要求的那样工作。在程序中添加新代码时,我们也同样有必要对其进行测试,确认它们不会破坏程序既有的行为,从而在用户发现问题之前在最早期找出它们。

        这一节我们将学习使用Python模块unittest中的工具来测试代码。包括学习编写测试用例,核实一系列输入都将得到预期的输出。我们也会看到测试通过了是什么样子,测试未通过是什么样子,以及测试未通过时如何有助于改进代码。接下来我们进入今天的主题。

        要学习使用unittest模块中的工具来进行函数和类的测试,那我们首先要有测试的代码。如下所示,我写了一个简单的函数,它用来接受名和姓并返回整洁的姓名:


      


函数get_formatted_name()方法讲名和姓通过full_name合并起来,并将首字母通过title()方法变成大写,最后返回结果。接下来,我们来编写一个使用这个函数的程序names.py,具体如下:




可以看到,我们首先在代码的第三行从name_function.py总导入了get_formatted_name()方法,然后用户可以输入一系列姓和名并看到完整的输出结果,如下所示:



可以看到,在dos界面中,运行names.py,用户输入姓和名,当输入q是程序结束。最后我们看到了完整的姓名Stephen Curry。说明现在程序是正常运行的。接下来我们用单元测试来测试一下这个程序,并返回一个测试结果。

Python标准库中的模块unittest提供了代码测试工具。单元测试用于核实函数的某个方面没有问题。这些单元测试仪器核实函数在各种情形下的行为都符合要求。

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

下面是一个只包含一个方法的测试用例,用来检查函数get_formatted_name()在给定名和姓时能否正确的工作:




在这段代码中,我们首先导入了unittest模块,以及要测试的函数get_formatted_name(),然后在第六行创建了一个名为NamesTestCase的类,这个类里面包含了一系列针对get_formatted_name()的单元测试方法。其中每一个单元测试最好以test开头。在这里第12行的assertEqual()方法用来检验得到的结果与预期的Stephen Curry是否相符。现在我们来运行一下程序:




可以看到,我们在第11行的get_formatted_name()方法里面输入了stephen和curry姓和名,最后和12行的Stephen Curry比较输出结果,在DOS界面显示了OK,说明程序运行正常,测试通过,该程序能够正确的执行姓和名并将完整的姓名输出。

注意:DOS界面第一行输出了一个句点,表示的是测试通过了,接下来的Ran 1 test in 0.000s表示Python运行了一个测试,以及消耗的时间,最后的OK表明了该测试用例中的所有单元测试都通过了。

测试通过的样子是这样的,那测试不通过是什么样子呢。很简单,接下来我们演示一下。




很明显,我们更新了get_formatted_name()函数的功能,使其能够处理带有中间名的功能。然后我们继续输入 stephen 和curry这两个姓和名,运行如下:




很明显,最后的测试结果是不通过的。因为我们在get_formatted_name()中添加了一个middle中间名,但是我们在测试用例中的单元测试方法里,只输入了2个参数,一个姓和一个名。最后DOS界面反馈的错误信息就是箭头所指的:方法中缺少了一个必要的参数。由此可以看出,我们更新了一个功能,使得get_formatted_name()可以完整的返回带有中间名的名字,但是原来的行为却被破坏了,那么我们要怎么解决呢,能够让这个函数既能够返回名和姓的完整姓名,也能够返回带有中间名的完整姓名。

注意:如果我们检查的条件没有错,那么测试未通过意味着你编写的新代码有错。因此,当测试未通过时,不要试图去修改测试用例里的单元测试方法,而应该修复导致测试不能通过的代码。检查刚刚对函数所做的修改,找出导致函数行为不符合预期的修改。


在修改后的代码中,我们能够看出,get_formatted_name()方法以前只有两个实参,也就是名和姓。现在加入了middle这个中间名,而且这个参数又是不可缺少的,这就导致了get_formatted_name()以前可以返回名和姓的功能行为被破坏了。在这里,我们如果把middle这个中间名设置为可选的,然后在加一个if判断,类似与Stephen Curry的测试就会通过了,并且新功能类似于Kevin A Durant带有中间名的测试也会通过。具体代码如下:



由于middle参数时可选的,所以要移到参数列表最后。现在我们在运行之前的单元测试,输入stephen 和curry,看看运行结果,测试通过:





我们再来看看返回带有中间名的完整姓名测试是否通过:




很明显,我们输入了stephen 和curry以及中间名mvp后,和预期的结果Stephen Mvp Curry对比后,测试通过

如果我把期望的结果修改一下,变成Stephen mvp Curry,那么测试显然不会通过,因为get_formatted_name()函数中,把输出的完整姓名的首字母都大写了。而我们的预期结果没有大写,所以错误反馈中会告诉我们,预期结果和实际结果不一致,测试不通过。



这样,通过以上实例的练习,我们看到了如何测试一个更新过的函数,如何来确定新功能没有影响函数原来的行为以及新功能是否运行符合预期。关于Python语言通过unittest模块中的测试工具来进行函数和类的单元测试,先讲到这里。后续会持续更新。讲一讲如何在测试用例中添加新的单元测试。













展开阅读全文

没有更多推荐了,返回首页