Python入门(四)——测试代码

11 测试代码

编写函数或类时还可以为其编写测试,通过测试,可确定代码面对各种输入都能够按照要求的那样工作

11.1 测试函数

name_function.py:一个简单的函数

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

names.py:使用这个函数的程序

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("Please give me a last name: ")
    if last == 'q':
        break

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

11.1.1 单元测试和测试用例

Python标准库中的模块 unittest 提供了代码测试工具,单元测试用于核实函数的某个方面没有问题
测试用例是一组单元测试,这些单元测试一起核实函数在各种情形的测试
全覆盖测试用例包含一整套单元测试,涵盖了何种可能的函数使用方式

11.1.2 可能同的测试

要为函数编写测试用例,可先导入模块 unittest 以及要测试的函数,再创建一个继承 unittext.TestCase 的类,并编写一系列方法对函数行为的不同方面进行测试
断言方法用来核实得到的结果食肉与期望的结果一致

import unittest
from first import get_formatted_name

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

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

unittest.main()

11.2 测试类

11.2.1 各种断言方法

asserEqual(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 中

11.2.2 一个要测试的类

AnonymousSurvey 类可用于进行简单的匿名调查

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)
from first 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 survey!")
my_survey.show_results()

测试类:

import unittest
from first 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)

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

11.2.4 方法 setUp()

unittest.TestCase 类包含方法 setUp(),Python将先运行他,再运行各个以 test_ 打头的方法,这样在编写的每个测试方法中都可以使用方法 setUp() 中创建对象了
方法 setUp() 做了两件事情:创建一个调查对象;创建了一个答案列表
可在 setUp() 方法中创建一些列实例并设置它们的属性,再在测试方法中直接使用这些实例

import unittest
from first import AnonymousSurvey

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

    def setUp(self) -> None:
        """创建一个调查对象和一组答案,供使用的测试方法使用"""
        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_responses(self):
        """测试三个答案会被妥善地存储"""
        for response in self.responses:
            self.my_survey.store_response(response)
        for response in self.responses:
            self.assertIn(response, self.my_survey.responses)

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

运行测试用例时,没完成一个测试,Python都打印一个字符,如果测试用例包含很多单元测试,需要运行很长时间,就可以通过观察这些结果来获悉有多少个测试通过了

上一篇:自监督(对比学习)资料


下一篇:Graph Learing: A Survey论文阅读笔记