在软件开发过程中,编写测试是确保代码质量和可靠性的关键步骤。测试函数的作用在于验证代码的各个部分是否按照预期工作,以及在不同情况下是否能够正确处理输入。
文件一name_function_test1
# name_function_test_1.py
def get_formatted_name(first, last, middle=''):
"""生成整洁的姓名"""
if middle:
full_name = f"{first} {middle} {last}"
else:
full_name = f"{first} {last}"
return full_name.title()
文件二 name_function_test
【名字test结尾】
import unittest
from name_function_test_1 import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""测试name_function.py """
def test_first_last_name(self):
"""能够正确地处理像Janis Joplin这样的姓名吗?"""
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
def test_first_last_middle_name(self):
"""能够正确地处理像Wolfgang Amadeus Mozart这样的姓名吗?"""
formatted_name = get_formatted_name(
'wolfgang', 'mozart', 'amadeus')
self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
# unittest.main()
【断言】 self.assert
测试目的:这段代码是一个简单的单元测试,用于测试名字格式化函数 `get_formatted_name` 是否能够正确地处理不同情况下的姓名。
测试类和方法: 通过 `unittest.TestCase` 创建了一个测试类 `NamesTestCase`,其中包含了两个测试方法。每个测试方法都以 `test_` 开头,是为了让 unittest 能够自动识别和执行这些方法。
第一个测试方法 (`test_first_last_name`):测试函数调用 `get_formatted_name` 函数,将 'janis' 和 'joplin' 作为参数传递给它。然后,使用 `self.assertEqual` 断言来验证函数的返回值是否等于期望的结果 'Janis Joplin'。
第二个测试方法 (`test_first_last_middle_name`): 同样地,这个方法测试 `get_formatted_name` 函数,但这次使用了包含中间名 'amadeus' 的完整名字 'wolfgang mozart amadeus'。通过断言验证函数的返回值是否等于'Wolfgang Amadeus Mozart'。
注释和文档字符串: 注释和文档字符串用于解释代码的目的和各个部分的功能。注释解释了整个测试类的目的,而文档字符串则解释了每个测试方法的具体测试目标。
注释掉的 `unittest.main()`:在最后,`unittest.main()` 这一行是注释掉的。这是因为在讲解代码时,你可能只想解释测试的内容而不直接执行测试。如果需要执行测试,可以取消注释这一行。
【练习】
11-1 城市和国家:编写一个函数,它接受两个形参:一个城市名和一个国家名。这个函数返回一个格式为City,Country的字符串,如Santiago,Chile。将这个函数存储在一个名为city_functions.py的模块中。
# city_functions.py
def format_city_country(city, country):
"""格式化城市和国家的字符串"""
formatted_string = f"{city.title()}, {country.title()}"
return formatted_string
创建一个名为test_cities.py的程序,对刚编写的函数进行测试(别忘了,你需要导入模块unittest以及要测试的函数)。编写一个名为test_city_country()的方法,核实使用类似于'santiago'和'chile'这样的值来调用前述函数时,得到的字符串是正确的。运行test_cities.py,确认测试test_city_country()通过了。
import unittest
from city_functions import format_city_country
class TestCities(unittest.TestCase):
'''test city_functions.py模块'''
def test_city_country(self):
formatted_result=format_city_country('santiago','chile')
self.assertEqual(formatted_result,'Santiago, Chile')
if __name__ == '__main__': #这是主程序入口
unittest.main()
11-2 人口数量:修改前面的函数,使其包含第三个必不可少的形参population,并返回一个格式为City, Country-populationxxx的字符串,如Santiago,Chile-population 5000000。运行test_cities.py,确认测试test_city_country()未通过。修改上述函数,将形参population设置为可选的。再次运行test_cities.py,确认测试test_city_country()又通过了。
# city_functions.py
def format_city_country(city, country,population=None):
"""格式化城市和国家的字符串"""
if population:
formatted_string = f"{city.title()}, {country.title()},{population}"
else:
formatted_string = f"{city.title()}, {country.title()}"
return formatted_string
再编写一个名为test_city_country_population()的测试,核实可以使用类似于'santiago'、'chile'和'population=5000000'这样的值来调用这个函数。再次运行test_cities.py,确认测试test_city_country_population()通过了
import unittest
from city_functions import format_city_country
class TestCities(unittest.TestCase):
'''test city_functions.py模块'''
def test_city_country(self):
formatted_result=format_city_country('santiago','chile')
self.assertEqual(formatted_result,'Santiago, Chile')
def test_city_population(self):
formatted_result= format_city_country('santiago','chile', 500000)
if __name__ == '__main__': #这是主程序入口
unittest.main()