Python学习笔记(十)——测试代码

编写函数或类时,还可为其编写测试。通过测试,可确定代码面对各种输入都能够按要求的那样工作。测试让你信心满满,深信即便有更多的人使用你的程序,它也能正确地工作。在程序中添加新代码时,你也可以对其进行测试,确认它们不会破坏程序既有的行为。程序员都会犯错,因此每个程序员都必须经常测试其代码,在用户发现问题前找出它们。

一 测试函数

1.单元测试和测试用例

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

2.可通过的测试

import unittest
from fun1 import get_formatted_name

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

        def test_first_last_name(self):
            """ 能够正确地处理像 Janis Joplin 这样的姓名吗? """
            formatted_name = get_formatted_name('janis', 'joplin')
            self.assertEqual(formatted_name, 'Janis Joplin')

unittest.main()

首先,我们导入了模块unittest和要测试的函数get_formatted_name()。然后,我们创建了一个名为 NamesTestCase 的类,用于包含一系列针,对get_formatted_name()的单元测试。这个类必须继承 unittest.TestCase 类,这样 Python 才知道如何运行我们编写的测试。
NamesTestCase 只包含一个方法,用于测试 get_formatted_name() 的一个方面。
在方法内此时我们使用了 unittest 类最有用的功能之一:一个 断言 方法。断言方法用来核实得到的结果是否与期望的结果一致。在这里,我们知道 get_formatted_name() 应返回这样的姓名。
代码行 unittest.main() 让 Python 运行这个文件中的测试。

3.不能通过的测试

例如我们修改了名字命名程序,只能处理含有中间名的名字:

def get_formatted_name(first, middle, last):
    """ 生成整洁的姓名 """
    full_name = first + ' ' + middle + ' ' + last
    return full_name.title()

此时不能通过测试,输出包含了很多有用的信息。
它会指出测试用例中有一个单元测试导致了错

4.测试未通过时怎么办

测试未通过时怎么办呢?如果你检查的条件没错,测试通过了意味着函数的行为是对的,而测试未通过意味着你编写的新代码有错。因此,测试未通过时,不要修改测试,而应
修复导致测试不能通过的代码:检查刚对函数所做的修改,找出导致函数行为不符合预期的修改。

5.添加新测试

我们还可以添加新的方法进行多项测试。

二 测试类

下面来编写针对类的测试。很多程序中都会用到类,因此能够证明你的类能够正确地工作会大有裨益。如果针对类的测试通过了,你就能确信对类所做的改进没有意外地破坏其原有的行为。

1.各种断言方法

方法 用途
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 中

2.一个要测试的类

类的测试与函数的测试相似 —— 你所做的大部分工作都是测试类中方法的行为.

#一个有关调查的类
class AnonymousSurvey():
    """ 收集匿名调查问卷的答案 """
    
    def __init__(self, question):
        """ 存储一个问题,并为存储答案做准备 """
        self.question = question
        self.responses = []
        
    def show_question(self):
        """ 显示调查问卷 """
        print(question)
        
    def store_response(self, new_response):
        """ 存储单份调查答卷 """
        self.responses.append(new_response)
        
    def show_results(self):
        """ 显示收集到的所有答卷 """
        print("Survey results:")
        for response in responses:
            print('- ' + response)

这个类首先存储了一个你指定的调查问题,并创建了一个空列表,用于存储答案。
然后,我们编写一个使用它的程序

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

3.测试 AnonymousSurvey 类

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('English')

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

unittest.main()

4.方法set.up()

unittest.TestCase 类包含方法 setUp() ,让我
们只需创建这些对象一次,并在每个测试方法中使用它们。如果你在 TestCase 类中包含了方法 setUp() , Python 将先运行它,再运行各个以 test_ 打头的方法。

猜你喜欢

转载自blog.csdn.net/weixin_51871724/article/details/121150427