Python 基础入门前六篇:php
这是第七篇,也是这个基础入门系列的最后一篇内容,简单介绍如何采用 unittest
模型编写测试用例。java
首先是给出用于测试的代码,以下所示,这是一个接收姓和名而后返回整洁的姓名的函数:python
def get_formatted_name(first, last):
full_name = first + ' ' + last
return full_name.title()
复制代码
简单的测试代码:c++
first = 'kobe'
last = 'bryant'
print(get_formatted_name(first, last)) # 输出 Kobe Bryant
复制代码
在 Python 标准库中的模块 unittest
提供了代码测试工具。这里介绍几个名词的含义:git
一般,最初只须要对函数的重要行为编写测试便可,等项目被普遍使用时才考虑全覆盖。github
接下来就开始介绍如何采用 unittest
对代码进行测试。正则表达式
首先是须要导入 unittest
模块,而后建立一个继承 unittest.TestCase
的类,并编写一系列类方法对函数的不一样行为进行测试,以下代码所示:算法
import unittest
class NamesTestCase(unittest.TestCase):
''' 测试生成名字函数的类 '''
def test_first_last_name(self):
formatted_name = get_formatted_name('kobe', 'bryant')
self.assertEqual(formatted_name, 'Kobe Bryant')
unittest.main()
复制代码
输出结果以下,显示运行的测试样例是 1 个,耗时是 0.001s。编程
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
复制代码
上述是给了一个能够经过的例子,而若是测试不经过,输出是怎样的呢,以下所示:bash
# 添加中间名
def get_formatted_name(first, middel, last):
full_name = first + ' ' + middle + ' ' + last
return full_name.title()
class NamesTestCase(unittest.TestCase):
''' 测试生成名字函数的类 '''
# 不能经过的例子
def test_first_name(self):
formatted_name = get_formatted_name('kobe', 'bryant')
self.assertEqual(formatted_name, 'Kobe Bryant')
unittest.main()
复制代码
输出结果以下,这里会打印错误发生的地方和错误缘由:
E
======================================================================
ERROR: test_first_last_middle_name (__main__.NamesTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "E:/Python_Notes/Practise/unittest_practise.py", line 39, in test_first_last_middle_name
formatted_name = get_formatted_name('kobe', 'bryant')
TypeError: get_formatted_name() missing 1 required positional argument: 'middle'
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
复制代码
很明显是由于缺乏 middle
参数,若是但愿经过测试,能够将原函数进行以下修改:
def get_formatted_name(first, last, middle=''):
''' 接收姓和名而后返回完整的姓名 :param first: :param last: :return: '''
if middle:
full_name = first + ' ' + middle + ' ' + last
else:
full_name = first + ' ' + last
return full_name.title()
复制代码
而后添加新的测试方法,继续运行,就能够测试经过。
def test_first_last_middle_name(self):
formatted_name = get_formatted_name('kobe', 'bryant', 'snake')
self.assertEqual(formatted_name, 'Kobe Snake Bryant')
复制代码
上一小节介绍了给函数写测试的代码,接下来介绍如何编写针对类的测试。
在 unitest.TestCase
类中提供了不少断言方法,上一小节就采用了 assertEqual
这一个判断给定两个参数是否相等的断言方法,下面给出经常使用的 6 个断言方法:
方法 | 用途 |
---|---|
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 中 |
这些方法都只能在继承了 unittest.TestCase
的类中使用这些方法。
首先,编写用于进行测试的类,代码以下所示,这是一个用于管理匿名调查问卷答案的类:
class AnonymousSurvey():
''' 收集匿名调查问卷的答案 '''
def __init__(self, question):
''' :param question: '''
self.question = question
self.responses = []
def show_question(self):
''' 显示问卷 :return: '''
print(self.question)
def store_response(self, new_response):
''' 存储单份调查问卷 :param new_response: :return: '''
self.responses.append(new_response)
def show_results(self):
''' 显示全部答卷 :return: '''
print('Survey results:')
for response in self.responses:
print('- ' + response)
复制代码
这个类包含三个方法,分别是显示问题、存储单份问卷以及展现全部调查问卷,下面是一个使用例子:
def use_anonymous_survey():
question = "世上最好的语言是?"
language_survey = AnonymousSurvey(question)
# 显示问题
language_survey.show_question()
# 添加问卷
language_survey.store_response('php')
language_survey.store_response('python')
language_survey.store_response('c++')
language_survey.store_response('java')
language_survey.store_response('go')
# 展现全部问卷
language_survey.show_results()
if __name__ == '__main__':
use_anonymous_survey()
复制代码
输出结果以下:
世上最好的语言是?
Survey results:
- php
- python
- c++
- java
- go
复制代码
而后就开始编写对该类的测试代码,一样建立一个类,继承 unittest.TestCase
,而后类方法进行测试,代码以下所示:
import unittest
class TestAnonmyousSurvey(unittest.TestCase):
def test_store_single_response(self):
''' 测试保存单份问卷的方法 :return: '''
question = "世上最好的语言是?"
language_survey = AnonymousSurvey(question)
language_survey.store_response('php')
self.assertIn('php', language_survey.responses)
unittest.main()
复制代码
上述代码采用了 assertIn
断言方法来测试函数 store_response()
。
这里还能够继续测试可否存储更多的问卷,以下所示,测试存储三份问卷:
def test_store_three_response(self):
question = "世上最好的语言是?"
language_survey = AnonymousSurvey(question)
responses = ['c++', 'php', 'python']
for response in responses:
language_survey.store_response(response)
for response in responses:
self.assertIn(response, language_survey.responses)
复制代码
最后,在 unittest.TestCase
中其实包含一个方法 setUp()
,它的做用相似类的初始化方法 __init()__
,它会在各类以 test_
开头的方法运行前先运行,因此能够在这个方法里建立对象,避免在每一个测试方法都须要建立一遍,因此上述代码能够修改成:
class TestAnonmyousSurvey(unittest.TestCase):
def setUp(self):
''' 建立一个调查对象和一组答案 :return: '''
question = "世上最好的语言是?"
self.language_survey = AnonymousSurvey(question)
self.responses = ['c++', 'php', 'python']
def test_store_single_response(self):
''' 测试保存单份问卷的方法 :return: '''
self.language_survey.store_response(self.responses[1])
self.assertIn('php', self.language_survey.responses)
def test_store_three_response(self):
for response in self.responses:
self.language_survey.store_response(response)
for response in self.responses:
self.assertIn(response, self.language_survey.responses)
复制代码
运行后,输出结果以下:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
复制代码
注意,这里运行成功,打印一个句号,由于是运行两个测试方法成功,因此打印了两个句号;若是运行出错,打印一个 E
;测试致使断言失败,打印一个 F
。
参考
Python 的基础入门系列就介绍到这里,最初第一篇初步制定的计划是以下所示:
恰好基本都介绍上述 10 个方面的知识,后续还会有进阶的知识点,包括函数和类的高级知识点,正则表达式,网络编程方面的如进程和线程知识,固然还会总结或者翻译一些不错的介绍 Python 技巧的文章,以及一些经常使用库的使用方法,好比 numpy、pandas、matplotlib 等等。
固然,还有就是努力作一些有趣的项目。
本文的代码例子也都上传到个人 Github 上:
欢迎关注个人微信公众号--算法猿的成长,或者扫描下方的二维码,你们一块儿交流,学习和进步!