python基础10

测试代码

在很多时候,但我们在完成程序后,常常会因各种需求,对该程序进行修改,或者拓展其功能。

测试代码,就是在拓展程序功能的时候,测试函数是否仍保留其之前的功能,并正确运行。

一般而言,我们将函数文件、主程序与测试代码分别保存在不同文件中。

测试函数

测试函数的编写过程就是随着函数编写而编写测试代码的过程。

具体而言,先完成一段函数,然后编写对应测试代码,再拓展函数功能,再编写对与拓展之后的函数的测试代码的过程。

首先在名为name_function的文件中编写一个待测试的函数:

1
2
3
4
def get_formatted_name(first_name, last_name):
"""获取完整姓名的函数"""
full_name = first_name + " " + last_name
return full_name.title()

– 为了证明该代码可以运行,我们还需要编写一个使用该代码的程序。该程序在名为names的文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from name_function import get_formatted_name


print("Enter 'q' at any time to quit.")
while True:
first = input("\nPlease give me a first name:")
if first == 'q':
break
last = input("\nPlease give me a last name:")
if last == 'q':
break

formatted_name = get_formatted_name(first, last)
print("\tNeatly formatted name: " + formatted_name + ".")

上面的程序的运行证明待测试文件可以运行,进一步编写待测试函数的测试代码。代码如下,并存储在名为get_name_test.py的模块中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import unittest
from name_function import get_formatted_name


class NamesTestCase(unittest.TestCase):
"""测试get_name.py"""

def test_first_last_name(self):
"""能够正确处理像John leon的名字吗"""
formatted_name = get_formatted_name('John', 'leon')
self.assertEqual(formatted_name, 'John Leon')


unittest.main()

"""---------------输出结果-------------------------"""
Ran 1 test in 0.000s

OK
  • 引用unittest模块检测代码;
  • 在测试模块中创建unittest.TestCase类的子类,其中子类中的函数必须以test_开头;
  • 测试程序输出结果与自己预期输出结果是否相同时,需要使用断言asserEqual
  • 当函数代码改进时,首先运行该测试文件,运行结果正常后,继续编写新的代码的测试文件。
断言方法 用途
assertEqual(1,b) 核实a==b
assertNotEqual(a,b) 核实a!=b
assertTrue(x) 核实x为True
assertFalse 核实x为False
assertIn(item, list) 核实item在list中
assertNotIn(item, list) 核实item不在list中

测试类

类的测试与函数的测试相似————你所做的大部分工作都是测试类中方法的行为。特殊之处在于,在测试类的代码中,可以定义一个setUp()方法,来存储测试过程之中需要的变量以便重复使用来测试类中的多个方法。

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

首先编写一个待测试的类,文件名为survey.py。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class AnonymousSurvey():
"""收集匿名调查问卷的答案"""

def __init__(self, question):
"""存储一个问题,并为存储答案做准备"""
self.question = question
self.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)

其次基于该类编写程序,证明该类可正常运行,文件名为language_survey.py。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from survey import AnonymousSurvey

# 定义一个问题,并创建一个表示调查的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':
break
my_survey.store_response(response)

# 显示调查结果
print("\nThank you to everyone who participated in the survey!")
my_survey.show_results()

然后编写测试代码,文件名为test_survey.py。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import unittest
from survey import AnonymousSurvey


class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""

def test_store_single_response(self):
"""测试单个答案会被妥善地存储"""
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
my_survey.store_response('python')

self.assertIn('python', my_survey.responses)


unittest.main()

下面使用setUp()对复杂代码进行测试。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import unittest
from survey import AnonymousSurvey


class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""

def setUp(self):
"""
定义一个调查对象和一组答案,以供使用的测试方法使用
"""
question = "What language did you first learn to speak?"
self.my_survey = AnonymousSurvey(question)
self.responses = ['python', 'C', 'C++']

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_single_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()

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!