当前位置: 首页 > 科技观察

Python中的两个测试工具

时间:2023-03-16 21:46:04 科技观察

我们在编写程序的时候,需要通过测试来验证程序是否有错误或者有问题。但是,编写大量的测试来保证程序的每一个细节都ok会显得很繁琐。在Python中,我们可以使用一些标准模块来帮助我们自动化测试过程,例如:unittest:一个通用的测试框架;doctest:一个更简单的模块,专为检查文档而设计,但也非常适合编写单元测试。下面,笔者将简单介绍一下这两个模块在测试中的应用。doctestdoctest模块搜索似乎在交互式python会话中的代码片段,然后尝试执行它们并验证结果。我们以doctest.testmod为例。函数doctest.testmod会读取模块中的所有文档字符串,找到看起来像是从交互式解释器中取出的示例,并检查这些示例是否反映了实际情况。我们先创建示例代码文件test_string_lower.py,完整代码如下:#-*-coding:utf-8-*-defstring_lower(string):'''returnsthelowercaseofastring:paramstring:type:str:return:thelowerofinputstring>>>string_lower('AbC')'abc'>>>string_lower('ABC')'abc'>>>string_lower('abc')'abc''''returnstring.lower()if__name__=='__main__':importdoctest,test_string_lowerdoctest.testmod(test_string_lower)首先先解释一下程序。函数string_lower用于返回输入字符串的小写字母。函数中的注释一共包含了3个测试实例。期望尽可能包括各种测试情况,然后在main函数中导入doctest,test_string_lower,然后在doctest中运行testmod函数进行测试。接下来,我们开始测试。首先在命令行输入pythontest_string_lower.py运行发现没有任何输出,这其实是件好事,说明程序中的所有测试都通过了!那么,如果我们想获得更多的输出怎么办?运行脚本时可以加上参数-v。这时命令变成了pythontest_string_lower.py-v,输出如下:Trying:string_lower('AbC')Expecting:'abc'okTrying:string_lower('ABC')Expecting:'abc'okTrying:string_lower('abc')预期:'abc'ok1itemshadnotests:test_string_lower1itemspassedalltests:3testsintest_string_lower.string_lower3testsin2items.3passedand0failed.Testpassed。可见程序测试的背后还是发生了很多事情。接下来我们尝试了程序出错的情况。比如我们不小心把函数的返回写成:returnstring.upper(),其实返回的是输入字符串的大写,但是我们测试的例子返回的是输入字符串的小写,然后运行脚本(带参数-v),输出如下:Failedexample:string_lower('abc')Expected:'abc'Got:'ABC'1itemshadnotests:test_string_lower*******************************************************************************1itemshadfailures:3of3intest_string_lower.string_lower3testsin2items.0passedand3failed.***测试失败***3失败。这时候程序测试失败了。不仅抓到了bug,还清楚的指出了错误发生的地方。我们修改这个程序并不困难。doctest模块更详细的使用说明,请参考网址:https://docs.python.org/2/library/doctest.html。unittestunittest类似于流行的Java测试框架JUnit,它比doctest更加灵活和强大,可以帮助您以结构化的方式编写大量详细的测试集。我们先从一个简单的例子开始,首先我们编写my_math.py脚本,代码如下:#-*-coding:utf-8-*-defproduct(x,y):''':paramx:int,float:paramy:int,float:return:x*y'''returnx*y该函数实现的功能是:输入两个数x,y,返回这两个数的乘积。然后是test_my_math.py脚本,完整代码如下:importunittest,my_mathclassProductTestcase(unittest.TestCase):defsetUp(self):print('begintest')deftest_integers(self):forxinrange(-10,10):foryinrange(-10,10):p=my_math.product(x,y)self.assertEqual(p,x*y,'integermultiplicationfailed')deftest_floats(self):forxinrange(-10,10):foryinrange(-10,10):xx=x/10yy=y/10p=my_math.product(x,y)self.assertEqual(p,x*y,'integermultiplicationfailed')if__name__=='__main__':unittest.main()函数unittest.main负责为你运行测试:在测试方法之前执行setUp方法,实例化所有TestCase子类,并运行名称以test开头的所有方法。assertEqual方法检查指定的条件(此处等于)以确定指定的测试是成功还是失败。接下来,我们运行前面的测试,输出如下:begintest.begintest.---------------------------------------------------------------------Ran2testsin0.001sOK可以看到程序运行了两次测试,每次测试前都会输出'开始测试',表示测试成功,如果测试失败则返回F。然后模拟测试出错的情况,将my_math函数中的product方法改成return:returnx+y然后运行测试脚本,输出结果如下:begintestFbegintestF======================================================================FAIL:test_floats(__main__.ProductTestcase)------------------------------------------------------------------追溯(mostrecentcallast):文件“test_my_math.py”,第20行,intest_floatsself.assertEqual(p,x*y,'integermultiplicationfailed')AssertionError:-2.0!=1.0:integermultiplicationfailed===========================================================================失败:test_integers(__main__.ProductTestcase)-------------------------------------------------------------------追溯(mostrecentcallast):文件“test_my_math.py”,第12行,intest_integerself.assertEqual(p,x*y,'integermultiplicationfailed')AssertionError:-20!=100:integermultiplicationfailed--------------------------------------------------------------------Ran2testsin0.001sFAILED(failures=2)两个测试都失败了,返回是F,帮你指出错误的地方,next,您应该能够快速修复此错误。关于unittest模块更详细的说明,可以参考网址:https://docs.python.org/3/library/unittest.html。总结本文介绍了Python中的两个测试工具:doctest和unittest,用简单的例子来说明这两个测试模块的使用,希望对读者有所帮助~