文章目录

  • 前言
  • 一、测试的目的
  • 二、测试函数
    • 1.断言方法
    • 2.可通过的测试
    • 3.不可通过的测试
    • 4.添加多个测试
  • 三、测试类
    • 1.简单的测试类
    • 2.含多个答案的测试类
    • 3.setUp()方法
  • 总结

前言

本文的主要内容是Python中测试代码的介绍,包括测试的目的、测试函数以及测试类等内容,文中附有代码以及相应的运行结果辅助理解。


一、测试的目的

测试能够给我们信心,如果你的代码通过了测试,那么即便有再多的人使用你编写的程序,它也能正确地运行。通过测试,可确定代码面对各种输入时都能够按预想的那样工作。
测试是很多初学者都不熟悉的主题,作为初学者,并非必须为你尝试的所有项目编写测试,但参与工作量较大的项目时,应对自己编写的函数和类的重要行为进行测试,这样就能够更加确定自己所做的工作不会破坏项目的其他部分,如果不小心破坏了原来的功能,你马上就会知道,从而能够轻松地修复问题。相比于等到不满意的用户报告bug后再采取措施,在测试未通过时采取措施要容易得多。


二、测试函数

Python标准库中的模块unittest提供了代码测试工具,单元测试用于核实函数的某个方面没有问题,测试用例是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形的测试,全覆盖式测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。

1.断言方法

Python在unittest.TestCase类中提供了很多断言方法,断言方法的引入是为了检查你认为应该满足的条件是否确实满足,如果该条件确实满足,你对程序行为的假设就得到了确认,就可以确信在该测试中没有错误,如果你认为应该满足的条件实际上并不满足,Python将引发异常。
下面是常见的几个断言方法。

使用这些方法可核实返回的值等于或不等于预期的值、返回的值为True或False、返回的值在列表中或不在列表中,只能在继承unittest.TestCase的类中使用这些方法。

2.可通过的测试

写测试代码时,首先要导入模块unittest,如果你待测试的函数在另一个模块,也要将该函数导入;接着创建一个测试类,该类名可以自己起,但是这个类必须继承unittest.TestCase类,因为这样Python才知道如何运行你编写的测试;再接着在该类下写一个方法,用来测试你所写函数的正确性,这个方法需要以test_开头,因为在该模块运行后以test_开头的方法才会自动运行,在这个方法中,调用要测试的函数,并存储了要测试的返回值;然后使用unittest类的功能,即一个断言方法,来核实得到的结果是否与期望的结果一致;最后代码行unittest.main()让Python运行这个文件中的测试。
下面来写一个简单的测试函数例子。

import unittest  # 导入模块def get_full_name(first_name, last_name):  # 待测试的函数,也可以将其单独写在一个模块,然后导入"""输出全名"""full_name = first_name + ' ' + last_namereturn full_name.title()class NameTestCase(unittest.TestCase):   # 该类名可以自己起,这个类必须继承unittest.TestCase类,这样Python才知道如何运行你编写的测试"""测试函数"""def test_first_last_name(self): # 运行该模块时,所有以test_打头的方法将自动运行"""是否能够正确地处理只有名和姓的姓名"""full_name = get_full_name('kevin', 'durant')self.assertEqual(full_name, 'Kevin Durant')  # 使用断言方法判断函数的输出与我们预想的输出是否一致unittest.main()  # 让Python运行这个文件中的测试

运行结果如下图所示。

在上面的输出结果中,第1行的句点表明有一个测试通过了(有几个句点就通过了几个测试,本例中只有一个测试);接下来的一行指出Python运行了一个测试,消耗的时间不到0.001秒;最后的OK表明该测试用例中的所有单元测试都通过了。

3.不可通过的测试

简单修改一下上面的例子,使其为不可通过的测试。
下面是不可通过的测试的例子。

import unittest  # 导入模块def get_full_name(first_name, middle_name, last_name):  # 待测试的函数,也可以将其单独写在一个模块,然后导入"""输出全名"""full_name = first_name + ' ' + middle_name + ' ' + last_namereturn full_name.title()class NameTestCase(unittest.TestCase):  # 该类名可以自己起,这个类必须继承unittest.TestCase类,这样Python才知道如何运行你编写的测试"""测试函数"""def test_first_last_name(self):  # 运行该模块时,所有以test_打头的方法将自动运行"""是否能够正确地处理只有名和姓的姓名"""full_name = get_full_name('kevin', 'durant')self.assertEqual(full_name, 'Kevin Durant')  # 使用断言方法判断函数的输出与我们预想的输出是否一致unittest.main()  # 让Python运行这个文件中的测试

运行结果如下图所示。

在上面的输出结果中,第1行的 E 表明有一个单元测试导致了错误;接下来的一行指出了出错误发生的方法;Traceback这里指明了缺少一个必不可少的位置实参;最后显示了运行测试的时间,还看到了一条消息,它指出整个测试用例都未通过,因为运行该测试用例时发生了一个错误。

4.添加多个测试

在测试不可通过的时候,就要查看自己的函数写得是否正确,有必要的话还要多加一个或几个测试。
再来修改一下这个例子,让其既能通过只有名和姓的测试,也能通过除了名和姓还包含中间名的测试。
下面是包含多个测试的例子。

import unittest  # 导入模块def get_full_name(first_name, last_name, middle_name=''):  # 待测试的函数,也可以将其单独写在一个模块,然后导入"""输出全名"""if middle_name:full_name = first_name + ' ' + middle_name + ' ' + last_nameelse:full_name = first_name + ' ' + last_namereturn full_name.title()class NameTestCase(unittest.TestCase):  # 该类名可以自己起,这个类必须继承unittest.TestCase类,这样Python才知道如何运行你编写的测试"""测试函数"""def test_first_last_name(self):  # 运行该模块时,所有以test_打头的方法将自动运行"""是否能够正确地处理只有名和姓的姓名"""full_name = get_full_name('kevin', 'durant')self.assertEqual(full_name, 'Kevin Durant')  # 使用断言方法判断函数的输出与我们预想的输出是否一致def test_first_middle_last_name(self):  # 运行该模块时,所有以test_打头的方法将自动运行"""是否能够正确地处理有名、姓和中间名的姓名"""full_name = get_full_name('larry', 'jr', 'nance')self.assertEqual(full_name, 'Larry Nance Jr')unittest.main()  # 让Python运行这个文件中的测试

运行结果如下图所示。

在上面的输出结果中,第1行的两个句点表明有两个测试通过了;接下来的一行指出Python运行了两个测试,消耗的时间不到0.001秒;最后的OK表明该测试用例中的所有单元测试都通过了。


三、测试类

前面是关于函数的测试,下面来进行类的测试,很多程序中都会用到类,因此能够证明类正确地工作相当有用,如果对类的测试通过了,就能确信对类所做的改进没有意外地破坏其原有的行为。

1.简单的测试类

下面是一个简单测试类的例子。

import unittestclass FavoriteProgramLanguage():  # 该类可以单独写一个模块然后导入"""最喜欢的编程语言"""def __init__(self, question):"""存储一个问题,并创建一个列表用来存放答案"""self.question = questionself.answers = []  # 创建一个列表来存放答案def show_question(self):"""显示问题"""print(self.question)def save_answer(self, answer):"""将回答存放进列表"""self.answers.append(answer)  # 追加到列表中class TestFavoriteProgramLanguage(unittest.TestCase):"""测试类FavoriteProgramLanguage"""def test_one_answer(self):"""测试单个回答是否会被正确地存储"""question = "What program language did you like best?"my_answer = FavoriteProgramLanguage(question)my_answer.save_answer('Python')self.assertEqual(question, my_answer.question)   # 查看问题是否相同self.assertIn('Python', my_answer.answers)  # 查看'English'是否在列表中unittest.main()  # 让Python运行这个文件中的测试

运行结果如下图所示。

在上面这个例子中,类的功能是存储问题和该问题的回答,这个简单的测试类是检验单个答案是否成功的存储在了列表中,由测试结果可知,单个答案存储成功。

2.含多个答案的测试类

上面的例子只测试了一个答案的正确性,下面在该例子的基础上修改,使其可以测试多个答案。
下面是含多个答案测试类的例子。

import unittestclass FavoriteProgramLanguage():"""最喜欢的编程语言"""def __init__(self, question):"""存储一个问题,并创建一个列表用来存放答案"""self.question = questionself.answers = []def show_question(self):"""显示问题"""print(self.question)def save_answer(self, answer):"""将回答存放进列表"""self.answers.append(answer)  # 追加到列表中class TestFavoriteProgramLanguage(unittest.TestCase):"""测试类FavoriteProgramLanguage"""def test_one_answer(self):"""测试单个回答是否会被正确地存储"""question = "What program language did you like best?"my_answer = FavoriteProgramLanguage(question)my_answer.save_answer('Python')self.assertEqual(question, my_answer.question)  # 查看问题是否相同self.assertIn('Python', my_answer.answers)  # 查看'English'是否在列表中def test_three_answer(self):"""测试多个回答是否会被正确地存储"""question = "What program language did you like best?"my_answer = FavoriteProgramLanguage(question)languages = ['Python', 'Java', 'C']  # 待测试的列表for language in languages:my_answer.save_answer(language)  # 将列表中的元素依次追加到列表self.assertEqual(question, my_answer.question)   # 查看问题是否相同for language in languages:self.assertIn(language, my_answer.answers)  # 查看多个回答是否都在列表中unittest.main()  # 让Python运行这个文件中的测试

运行结果如下图所示。

由运行结果可知,两个测试都通过了。

3.setUp()方法

在上面的例子中,我们在两个测试方法中都创建了一个类的实例,并在每个方法中都创建了答案,这样就显得很繁琐,好在unittest.TestCase类中包含方法setUp(),这让我们只需创建这些对象一次,并在每个测试方法中使用它们。
如果在TestCase类中包含了方法setUp(),Python将先运行它,再运行各个以test_打头的方法。
在上面例子的基础上加入setUp()方法,改进后的代码如下。

import unittestclass FavoriteProgramLanguage():"""最喜欢的编程语言"""def __init__(self, question):"""存储一个问题,并创建一个列表用来存放答案"""self.question = questionself.answers = []def show_question(self):"""显示问题"""print(self.question)def save_answer(self, answer):"""将回答存放进列表"""self.answers.append(answer)  # 追加到列表中class TestFavoriteProgramLanguage(unittest.TestCase):"""测试类FavoriteProgramLanguage"""def setUp(self):"""创建一个调查对象和一组答案,供使用的测试方法使用"""question = "What program language did you like best?"self.my_answer = FavoriteProgramLanguage(question)self.languages = ['Python', 'Java', 'C']self.assertEqual(question, self.my_answer.question)  # 查看问题是否相同def test_one_answer(self):"""测试单个回答是否会被正确地存储"""self.my_answer.save_answer(self.languages[0])  # 将第一个元素追加到列表self.assertIn(self.languages[0], self.my_answer.answers)  # 查看第一个元素是否在列表中def test_three_answer(self):"""测试多个回答是否会被正确地存储"""for language in self.languages:self.my_answer.save_answer(language)  # 将列表中的元素依次追加到列表for language in self.languages:self.assertIn(language, self.my_answer.answers)  # 查看多个回答是否在列表中unittest.main()  # 让Python运行这个文件中的测试

运行结果如下图所示。

试想一下,如果在测试类中包含多个方法,那么setUp()方法的作用将会愈加明显。


总结

以上就是Python中测试代码介绍的所有内容了,这部分的内容相对比较简单,在创建的类中继承unittest.TestCase类,并能够熟练正确的运用几个常用的断言方法即可写出测试代码,测试类就是在测试函数基础上的引申。
本文参考书目:Python 编程 :从入门到实践 / (美) 埃里克•马瑟斯(Eric Matthes)著;袁国忠译

Python中测试代码的介绍相关推荐

  1. ML之XGBoost:XGBoost参数调优的优秀外文翻译—《XGBoost中的参数调优完整指南(带python中的代码)》(一)

    ML之XGBoost:XGBoost参数调优的优秀外文翻译-<XGBoost中的参数调优完整指南(带python中的代码)>(一) 目录 概述/Overview 介绍/Introducti ...

  2. python nose测试框架全面介绍十---用例的跳过

    又来写nose了,这次主要介绍nose中的用例跳过应用,之前也有介绍,见python nose测试框架全面介绍四,但介绍的不详细.下面详细解析下 nose自带的SkipTest 先看看nose自带的S ...

  3. python代码块-Python中的代码块和非代码块是什么

    Python中的代码块和非代码块是什么 发布时间:2020-06-26 13:53:30 来源:亿速云 阅读:150 今天就跟大家聊聊有关Python中的代码块和非代码块是什么,可能很多人都不太了解, ...

  4. ML之XGBoost:XGBoost参数调优的优秀外文翻译—《XGBoost中的参数调优完整指南(带python中的代码)》(四)

    ML之XGBoost:XGBoost参数调优的优秀外文翻译-<XGBoost中的参数调优完整指南(带python中的代码)>(四) 目录 Step 3: Tune gamma步骤3:伽马微 ...

  5. ML之XGBoost:XGBoost参数调优的优秀外文翻译—《XGBoost中的参数调优完整指南(带python中的代码)》(三)

    ML之XGBoost:XGBoost参数调优的优秀外文翻译-<XGBoost中的参数调优完整指南(带python中的代码)>(三) 目录 3. 参数微调案例/Parameter Tunin ...

  6. python方法测试怀孕_在Python中测试私有方法(例外)

    在阅读了关于在Python中测试私有方法的内容之后,特别是在How do I unit test the methods in a method object?处引用了接受的答案,看来最好只测试公共接 ...

  7. Python基础-测试代码-test2.py

    Python基础-测试代码-test2.py 对类进行测试 # ~ coding=GBKimport unittest# ~ 下面代码演示对一个类进行测试 # ~ 待测试的类AnonymousSurv ...

  8. python以什么表示代码层次_在Python中,采用代码缩进和( )区分代码之间的层次。_学小易找答案...

    [填空题]29 号元素 Cu 基态时的电子排布式为 ___ __ ,该元素在周期表中位于 __ _ 周期. __ __ 族. [单选题]"我要努力实现梦想,以弥补小时候吹过的牛"小 ...

  9. python代码块使用缩进表示-python中的代码块使用缩进来表示。

    [填空题]Python 运算符中用来计算整商的是( ). (2.0分) [判断题]python中的多行语句可以使用反斜杠来实现. (2.0分) [填空题]在python中,int表示的数据类型是( ) ...

最新文章

  1. android 动态添加删除控件,求教Android,动态添加到控件能动态删除吗?
  2. C语言从青铜到王者——基础知识总结
  3. kaggle房价预测特征意思_Kaggle实战-波士顿房价预测
  4. ios FMDB数据库添删改查应用
  5. 7个顶级资源网站,不知道就很可惜
  6. 桶分类 算法_桶分类算法
  7. Pure Pursuit纯跟踪算法Python/Matlab算法实现
  8. 框架设计之菜鸟漫漫江湖路系列 开篇
  9. 【BZOJ1082】【codevs2456】栅栏,让人抓狂的优化剪枝
  10. 关于单点登录的简单原理和实现步骤
  11. Linux下清除DNS缓存
  12. 每天一个linux命令(56)--crontab命令
  13. 特征检测和特征匹配方法汇总
  14. 201671010129 2016—2017—2 《Java程序设计》Java总结
  15. 模2运算_模二除法和CRC循环冗余校验
  16. maven安装及配置(详细版)
  17. vue + el-menu 实现菜单栏无限多层级分类
  18. 《编程珠玑》课后答案
  19. 浩若烟海事半功倍|利用Docker容器技术构建自动化分布式web测试集群Selenium Grid
  20. C++操作Excel表格

热门文章

  1. 赫伯特·西蒙和艾伦·纽厄尔
  2. 架构的本质是管理复杂性,微服务本身也是架构演化的结果
  3. 【C#】WixToolset快速入门教程
  4. Node.js Git Server搭建及Git常用操作笔记
  5. 安装和卸载CentOS7图形界面
  6. 美图 android sdk,美图AI开放平台
  7. 服务器分vps销售系统,实体服务器配置vps销售
  8. api调用 python 验证码_Python短信验证码接口调用demo
  9. 陌陌联手JusTalk Cloud 对讲社交app新风尚
  10. 组合模式--设计模式解析与实战(关爱名 何红辉)笔记