目录

  • 介绍
  • 测试函数
    • 单元测试和测试用例
    • 可通过的测试
    • 不能通过的测试
    • 测试未通过时怎么办
    • 添加新测试
  • 测试类
    • 各种断言方法
    • 一个要测试的类
    • 测试AnonymousSurvey类
    • 方法setUp()

介绍

在本章中你会学习如何使用Python模块nuittest中的工具来测试代码。你将了解测试通过和未通过的样子;同时,你将学习如何测试函数和类;和知道该为项目编写多少个测试。

测试函数

要学习测试,先得有测试的代码。下面编写了一个简单的函数,它接受名和姓并返回整洁的姓名。

name_function.pydef get_formatted_name(first,last):full_name=first+' '+lastreturn full_name.title()

为核实get_formatted_name()像期望那样工作,我们来编写一个使用这个函数的程序。程序names.py让用户输入名和姓,并显示整洁的全名。

names.py
from name_function import get_formatted_name
print("Enter 'q' at any time to quit.")
while True:first = input("please input your first name:")if first == 'q':breaklast = input("please input your last name:")if last == 'q':breakformatted_name=get_formatted_name(first,last)print("\tNeatly formatted name:"+formatted_name+'.')

单元测试和测试用例

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

可通过的测试

要为函数编写测试用例,可先导入模块unittest以及要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。
下面是一个只包含一个方法的测试用例,它检查函数get_formatted_name()在给定名和姓时是否正确地工作。

test_name_function.pyimport unittest
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):def test_first_last_name(self):formatted_name = get_formatted_name('janis', 'joplin')self.assertEqual(formatted_name, 'janis joplin') #3unittest.main()

解释:类nameTestCase继承了unittest.TestCase类。
3处我们使用了unittest类最有用的功能之一:一个断言方法,断言方法用来核实得到的结果是否与预期的结果一致。比较fomatted_name的值和字符串’janis joplin’,如果他们相等,就万事大吉,如果他们不相等就跟我说一声。
结果出现句点和OK,表示测试通过了。

不能通过的测试

在name_function.py中添加一个名为new_get_formatted_name(first,middle,last)的函数,添加一个中间名。再放到test_name_function.py中测试:self.assertEqual(formatted_name, ‘janis joplin’),测试代码只改变为新的函数,其余不变。

E ❶
======================================================================
ERROR: test_first_last_name (__main__.NamesTestCase) ❷
----------------------------------------------------------------------
Traceback (most recent call last): ❸File "test_name_function.py", line 8, in test_first_last_nameformatted_name = get_formatted_name('janis', 'joplin')
TypeError: get_formatted_name() missing 1 required positional argument: 'last'
----------------------------------------------------------------------
Ran 1 test in 0.000s ❹
FAILED (errors=1) ❺

报错:

  1. 第一行只输出一个字母E,他指出测试用例中有一个单元测试导致了错误。
  2. ②处表示为:NamesTestCase中的test_first_last_name()导致了错误。测试用例中包含从多单元测试时,知道那个测试未通过至关重要。
  3. 在③处,它指出函数get_formatted_name(‘janis’,‘joplin’)有问题,因为它缺少一个必不可少的位置实参。
  4. 第④处,我们可以看到运行了一个单元测试。
  5. 第⑤处,我们可以知道测试该用例一共有几个错误。

测试未通过时怎么办

如果你检查的条件没有错,测试通过了意味着函数的行为是对的,而测试没有通过意味着你编写的新代码有错。因此,测试未通过时,不要修改测试,而应修复导致测试不能通过的代码。
在这个示例中,get_formatted_name()以前只需要两个实参–姓和名,但现在它要求提供中间名。新增的中间名参数是必不可少的,这导致get_formatted_name()的行为不符合预期。故最佳选择为让中间名变为可选的。

name_function.pydef new_get_formatted_name(first, last, middle=''):if middle:full_name = first + ' ' + middle + ' ' + lastreturn full_nameelse:full_name = first + ' ' + lastreturn full_name

再进行测试,测试通过。

添加新测试

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

import unittest
from name_function import new_get_formatted_nameclass NamesTestCase(unittest.TestCase):def test_first_last_name(self):formatted_name = new_get_formatted_name('janis', 'joplin')self.assertEqual(formatted_name, 'janis joplin')def test_first_last_middle_name(self):formatted_name = new_get_formatted_name('wolfgang','mozart','amadeus')self.assertEqual(formatted_name, 'wolfgang amadeus mozart')unittest.main()

补充:我们把这个方法命名为test_first_last_middle_name()。方法名必须以test_打头,这样它才会在我们运行test_name_function.py时自动运行。
在TestCase类中,使用很长的方法名是可以的,这些方法名称必须是描述性的,这样才能让你明白测试未通过时的输出。
这些方法由python调用,不用你编写他们的代码。

测试类

各种断言方法

python在unittest.TestCase类中提供了很多断言的方法。前面说过,断言方法检查你认为应该满足的条件是否可以满足。如果该条件满足,你对程序的假设就得了确认,你就可以确信其中没有错误。如果你认为应该满足的条件实际并不满足,python将引发异常。
常见的断言方法有六个:

方法 用途
assertEqual(a,b) 核实a == b
assertNotEqual(a,b) 核实a != b
assertTrue(x) 核实x 为 True
assertFalse(x) 核实x 为 False
assertIn(item,list) 核实 item 在 list 中
assertNotIn(item,list) 核实 item 不在 list 中

一个要测试的类

下面来编写一个类进行测试,创建一个帮助管理匿名调查的类。

survey.pyclass AnonymousSurvey():def __init__(self,question):self.question = questionself.responses = []def show_question(self):print(self.question)def store_response(self,new_response):self.responses.append(new_response)def show_results(self):print("survey results:")for response in self.responses:print('-'+response)

编写一个使用该类的程序

from survey import AnonymousSurvey
question = "what language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
my_survey.show_question()
print("Enter 'q' at any time to quit.\n")
while True:response = input("language:")if response == 'q':breakelse:my_survey.store_response(response)
print("\nThank you to everyone who participated in the survey!")
my_survey.show_results()

测试AnonymousSurvey类

编写一个测试,对AnonymousSurvey类的行为的一个方面进行验证:如果用户面对调查问题时只提供了一个答案,这个答案也能被妥善地存储。为此,我们将在这个答案被存储后,使用方法assertln()来核实它包含在答案列表中:

test_survey.pyimport unittest
from survey import AnonymousSurveyclass TestAnonymousSurvey(unittest.TestCase):def test_store_single_response(self):question = "what language did you first learn to speak?"my_survey = AnonymousSurvey(question)my_survey.store_response('english')self.assertIn('english',my_survey.responses)unittest.main()

测试成功,但它只能收集一个答案的调查用途不大。下面来核实用户提供三个答案时,他们也将被妥善地存储。故,我们在TestAnonymousSurvey中添加一个方法。

import unittest
from survey import AnonymousSurveyclass TestAnonymousSurvey(unittest.TestCase):def test_store_single_response(self):question = "what language did you first learn to speak?"my_survey = AnonymousSurvey(question)my_survey.store_response('english')self.assertIn('english',my_survey.responses)def test_store_three_responses(self):question = "what language did you first learn to speak?"my_survey = AnonymousSurvey(question)  # 补充:类中传参responses = ['english', 'spanish', 'mandarin']for response in responses:my_survey.store_response(response)for response in responses:self.assertIn(response, my_survey.responses)unittest.main()

方法setUp()

前面的测试效果很好,但有些测试有重复的地方,接下来使用unittest的另一项功能来提高它们的效率。
unittest.TestCase类包含方法setUp(),让我们只需创建这些对象一次,并在每个测试方法中使用他们。
如果你在TestCase类中包含了方法setUp(),python将先运行它,再运行各个以test_打头的方法。这样,在你编写的每个测试方法中都可使用在方法setUp()中创建对象了。

示例:使用setUp()来创建一个调查对象和一组答案,提供方法test_store_single_response()和test_store_three_responses()使用:

import unittest
from survey import AnonymousSurveyclass TestAnonymousSurvey(unittest.TestCase):def setUp(self):question = "what language did you first learn to speak?"self.my_survey = AnonymousSurvey(question)self.responses = ['english', 'spanish', 'mandarin']def test_store_single_response(self):self.my_survey.store_response(self.responses[0])self.assertIn(self.responses[0], self.my_survey.responses)def test_store_three_response(self):for response in self.responses:self.my_survey.store_response(response)for response in self.responses:self.assertIn(response, self.my_survey.responses)unittest.main()

解释:方法setUp()做了两件事:创建一个调查对象;创建一个答案列表。存储这两样东西的变量名包含前缀self(即存储在属性中),因此可在这个类的任何地方使用。这让两个测试方法都更简单,因为它们都不用创建调查对象和答案。
方法setUp()让测试方法编写起来更容易:可在setUp()方法中创建一系列实例并设置它们的属性,再在测试方法中直接使用这些实例。

python-测试代码相关推荐

  1. Python:测试代码

    Python : 测试代码 文章目录 Python : 测试代码 1 测试函数 1.1 单元测试和测试用例 1.2 可通过的测试 1.3 不能通过的测试 1.4 测试未通过时怎么办 1.5 添加新测试 ...

  2. python测试代码怎么写_Python 单元测试

    Test your software, or your users will. "Test ruthlessly. Don't make your users find bugs for y ...

  3. python测试代码怎么写_如何使用python做单元测试?

    很多编程小白不太理解单元测试,为什么要进行单元测试呢?很简单,主要是提高代码的正确,同时确保重构不出错.接下来我们一起学习怎么用python做单元测试吧. python内置了一个unittest,但是 ...

  4. python测试代码报错:Ran 0 test in 0.00s

    最近在学习selenium时,使用unittest框架进行代码测试时,发现报以下错误: Ran 0 test in 0.00sOK 原因: unittest提供了全局的main()方法,使得一个单元测 ...

  5. python测试代码怎么写_python unittest编写测试代码

    做开发的朋友在写代码的同时一般都会写测试代码,这对于做运维的同学却很少用. 今天我们就来写写测试代码,用unittest模块. cat test.py import unittest def IsOd ...

  6. python测试代码运行时间_10种检测Python程序运行时间、CPU和内存占用的方法

    在运行复杂的Python程序时,执行时间会很长,这时也许想提高程序的执行效率.但该怎么做呢? 首先,要有个工具能够检测代码中的瓶颈,例如,找到哪一部分执行时间比较长.接着,就针对这一部分进行优化. 同 ...

  7. python测试代码运行时间_python测量代码运行时间方法

    Python 社区有句俗语: "python自己带着电池" ,别自己写计时框架. Python3.2具备一个叫做 timeit 的完美计时工具可以测量python代码的运行时间. ...

  8. python测试代码性能_使用python timeit 模块检测代码性能

    使用Python 通常在乎的是它的开发效率,而不是运行性能. 但如果通过很简单的方法可以测试出n种不同的写法之间的性能差异,这个过程本身也是一种乐趣. python 自带了timeit 模块,可以在代 ...

  9. python测试代码与模块_测量Python代码运行时间

    Python 社区有句俗语: "python自己带着电池" ,别自己写计时框架. Python 2.3 具备一个叫做 timeit 的完美计时工具可以测量python代码的运行时间 ...

  10. python测试代码_python英语单词测试小程序代码实例

    这篇文章主要介绍了python英语单词测试小程序代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 爬取了扇贝英语网,并制作了一个英语单词测试的 ...

最新文章

  1. Jupyter Notebook实现直接调用R
  2. Handler造成Activity泄漏,用弱引用真的有用么?
  3. java基础-容器-Set
  4. TensorFlow 2.0.0-RC0版发布,专注于简单性与易用性
  5. 一个通用Makefile详解
  6. cocos2d-x游戏实例(13)-简易摇杆控制主角
  7. NCF框架揭秘直播来了!红包、抽奖、还有神秘嘉宾…(内含彩蛋)
  8. 利用html 5 websocket做个山寨版web聊天室(手写C#服务器)
  9. mysql 亿级高并发_亿级流量系统架构之如何设计每秒十万查询的高并发架构.md
  10. 【每日算法Day 61】LeetCode 672. 灯泡开关 Ⅱ
  11. WPS表格(Excel)常用函数与技巧总结
  12. 【oracle19c静默安装RAC】
  13. 智能车阳光算法(含大津法)
  14. 【asp.net core 系列】5 布局页和静态资源
  15. Adobe2023全家桶win及Mac系统安装包下载及安装教程ps、pr、ai、ae安装包下载
  16. 虚拟号的运营商一般是哪家的?你知道吗?
  17. 2023 zibll 子比主题 美化插件 全开源
  18. ECDSA (Elliptic Curve Digital Signature Algorithm)
  19. 哈尔滨理工大学第七届程序设计竞赛初赛 题集
  20. ip地址,MAC地址,子网掩码,网关,VPC,交换机,

热门文章

  1. day2:算法之美|打开算法之门与算法复杂性
  2. 服务器信号满格但上不了网,新版tplink路由器wifi信号满格上不了网怎么办?
  3. CSS核心内容:标准流、盒子模型、浮动、定位
  4. JSONObject简介 - 月月鸟0820 - 博客园
  5. 新中新二代身份证读卡器C#开发问题及解决方法
  6. STM32系列 (一)开发环境的搭建
  7. 【软件质量】软件可扩展性
  8. 服务器主板支持专用条,昂达推出存储服务器专用B250 D32-D3主板
  9. OSChina 周六乱弹 ——通常他们这么修复的bug,我都接受不了
  10. 艾美捷ALC-0159基本参数文献参考