Python入门: (8)测试

253 阅读3分钟

1. 测试函数

单元测试和测试用例

  • Python标准库中的模块unittest提供了代码测试工具
  • 单元测试 用于核实函数的某个方面没有问题
  • 测试用例 是一组单元测试,它们一道核实函数在各种情形下的行为都符合要求。良好的测试用例考虑到了函数可能收到的各种输入,包含针对所有这些情形的测试
  • 全覆盖 的测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。对于大型项目,要进行全覆盖测试可能很难。通常,最初只要针对代码的重要行为编写测试即可,等项目被广泛使用时再考虑全覆盖

可通过的测试

import unittest  # 导入模块unittest


def get_formatted_name(first, last):  # 要测试的函数
    """生成整洁的姓名"""
    full_name = f"{first} {last}"
    return full_name.title()

class NamesTestCase(unittest.TestCase):  # 创建NamesTestCase类,用于包含一系列针对get_formatted_name()的单元测试。
                                        # 这个类可以随意命名,但最好让它看起来与要测试的函数相关并包含Test字样。
                                        # 这个类必须继承unittest.TestCase类,这样Python才知道如何运行你编写的测试
    """测试name_function"""

    def test_first_last_name(self):
        """能够正确地处理像Janis Joplin这样的姓名吗?"""
        formatted_name = get_formatted_name('janis', 'joplin')
        self.assertEqual(formatted_name, 'Janis Joplin')  # unittest最有用的功能之一:断言方法
                                                        # 断言方法核实得到的结果是否与期望的结果一致
                                                        # 我们调用unittest的方法assertEqual(),并向它传递两个需要比较的值

if __name__ == '__main__':   # if代码块检查特殊变量__name__,这个变量是在程序执行时设置的
    unittest.main()

未通过的测试

def get_formatted_name(first, last, middle=''):  # 要测试的函数
    """生成整洁的姓名"""
    full_name = f"{first} {middle} {last}"
    return full_name.title()

2. 测试类

各种断言方法

方法用途
assertEqual(a, b)核实 a == b
assertNotEqual(a, b)核实 a != b
assertTrue(x)核实 x is True
assertFalse(x)核实 x is False
assertIn(item, list)核实 item in list
assertNotIn(item, list)核实 item not in list

一个要测试的类

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(f"- {response}")


# 定义一个问题,并创建一个调查
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()

测试AnonymousSurvey类

import unittest

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)

    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)

if __name__ == '__main__':
    unittest.main()

方法setUp()

  • unittest.TestCase类包含的方法setUp()让我们只需创建对象一次,就能在每个测试方法中使用
  • 可在setUp()方法中创建一系列实例并设置其属性,再在测试方法中直接使用这些实例。这让测试方法编写起来更容易
class TestAnonymousSurvey(unittest.TestCase):
    """针对AnonymousSurvey类的测试"""

    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):
        """测试单个答案会被妥善地存储"""
        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)

if __name__ == '__main__':
    unittest.main()


文章中的所有代码经测试均可成功编译运行,可直接复制。具有显然结果或简单结论的代码不展示运行结果。如有问题欢迎随时交流~