• python《从入门到实践》第11章测试代码 笔记


    测试是用来确定代码在面对各种输入时能按照要求进行工作,提前测试有利于防止新代码不会破坏程序既有的行为,本章使用unittest中的工具,编写测试用例,核实输入将得到的输出

    formatted 格式化 Generate生成 neatly 整洁的 full完全的

     1 from name_function import get_formatted_name #从name_function.py中导入get_formatted_name() 

    11-1城市和国家:编写一个函数,它接受两个形参:一个城市名和一个国家名。这个函数返回一个格式为City, Country的字符串,如Santiago, Chile。将这个函数存储在一个名为city _functions.py的模块中。创建一个名为test_cities.py的程序,对刚编写的函数进行测试(别忘了,你需要导入模块unittest以及要测试的函数)。编写一个名为test_city_country()的方法,核实使用类似于'santiago'和'chile'这样的值来调用前述函数时,得到的字符串是正确的。运行test_cities.py,确认测试test_city_country()通过了。

     1 #city_functions.py
     2 def city_country(city_name, country_name, middle=','):  #
     3     """输出城市名和国家名,例如Santiago, chile"""
     4     full_city_country = city_name + middle + country_name
     5     return full_city_country.title()
     6 
     7 #city_name_country_name.py
     8 from city_functions import city_country
     9 print("Enter 'q' at any time to quit.")
    10 while True:
    11     city_name = input("亲输入城市名: ")
    12     if city_name == 'q':
    13         break
    14     country_name = input("亲输入国家名: ")
    15     if country_name == 'q':
    16         break
    17 
    18     formatted_name = city_country(city_name, country_name)
    19     print("\n城市和国家名的输出结果: " + formatted_name)
    20 
    21 
    22 #test_cityname_and_country_name.py
    23 import unittest                     #导入inttest模块中的工具
    24 from city_functions import city_country    
    25 
    26 class NamesTestCase(unittest.TestCase):    #这个命名可以随意,但通常都与测试的函数相关而且要包含Test字样
    27     """测试city_functions.py"""            #继承TestCase类这样Python才知道如何运行你编写的测试,可以认为是一个接口将你的函数
    28                                    #在另一个地方运行
    29     def test_city_country_name(self):     #这个测试文件的方法要用test_为开头,_test为开头的方法在文件运行时会自动运行
    30         """能够正确地处理像Santigo, Chile这类的名字吗?"""
    31         formatted_name = city_country('Santigo', 'Chile') #调用了要测试的函数,并将返回值储存到formatted_name中
    32         self.assertEqual(formatted_name, 'Santigo,Chile')#使用断言方法assertEqual用来核实得到的结果是否与期望的结果一致
    33                         
    34   '''在这里,我们知道get_formatted_name()应返回这样的城市国家名,即
    35 首字母为大写,且它们之间有一个‘,’,因此我们期望formatted_name的值为Santigo,Chile。为检查是否确实如此,我们调用unittest的方法assertEqual(),并向它传递formatted_
    36 name和'Santigo Chile'。代码行self.assertEqual(formatted_name, 'Janis Joplin')的意思是说:“将formatted_name的值同字符串'Santigo,Chile'进行比较,如果它们相等,就万事大吉,如果它
    37 们不相等,跟我说一声!'''
    38 unittest.main()

    11-2人口数量:修改前面的函数,使其包含第三个必不可少的形参population,并返回一个格式为City, Country – population xxx的字符串,如Santiago, Chile –population 5000000。运行test_cities.py,确认测试test_city_country()未通过。修改上述函数,将形参population设置为可选的。再次运行test_cities.py,确认测试test_city_country()又通过了。再编写一个名为test_city_country_population()的测试,核实可以使用类似于'santiago'、'chile'和'population=5000000'这 样 的 值 来 调 用 这 个 函 数 。 再 次 运 行test_cities.py,确认测试test_city_country_population()通过了。

     1 #写到一般才看到是测试两个。。一个可选,一个不可选
     2 #不可选
     3 def city_country_population(city_name, country_name, population='population-50000'):
     4     """输出城市名和国家名,例如Santiago, chile"""
     5     full_city_country = (city_name + ', ' +
     6                          country_name + str(population))
     7     return full_city_country.title()
     8 #city_country_population_name.py
     9 from city_country_population import city_country_population
    10 population = 'population-500000'
    11 print("Enter 'q' at any time to quit.")
    12 while True:
    13     city_name = input("亲输入城市名: ")
    14     if city_name == 'q':
    15         break
    16     country_name = input("亲输入国家名: ")
    17     if country_name == 'q':
    18         break
    19     #population = input("请输入人口数: ")
    20     #if population == 'q':
    21         #break
    22 
    23     formatted_name = city_country_population(city_name, country_name, population)
    24     print("\n城市和国家名和人口的输出结果: " + formatted_name)
    25 #可选
    26 #city_country_population.py
    27 def city_country_population(city_name, country_name, population):
    28     """输出城市名和国家名,例如Santiago, chile"""
    29     full_city_country = (city_name + ', ' +
    30                          country_name + ' -population ' + population)
    31     return full_city_country.title()
    32 
    33 #city_country_population_name.py
    34 from city_country_population import city_country_population
    35 print("Enter 'q' at any time to quit.")
    36 while True:
    37     city_name = input("亲输入城市名: ")
    38     if city_name == 'q':
    39         break
    40     country_name = input("亲输入国家名: ")
    41     if country_name == 'q':
    42         break
    43     population = input("请输入人口数: ")
    44     if population == 'q':
    45         break
    46 
    47     formatted_name = city_country_population(city_name, country_name, population)
    48     print("\n城市和国家名和人口的输出结果: " + formatted_name)
    49 
    50 #test_city_and_country_populations.py
    51 import unittest
    52 from city_country_population import city_country_population
    53 
    54 class NamesTestCase(unittest.TestCase):
    55     """测试city_functions.py"""
    56 
    57     def test_city_country_population_name(self):
    58         """能够正确地处理像Santigo, Chile这类的名字吗?"""
    59         formatted_name = city_country_population('Asd', 'Asd', '456')
    60         self.assertEqual(formatted_name, 'Asd, Asd -Population 456')
    61 
    62 unittest.main()
    63 #测试不通过的没写,因为太多不通过的方法了,没有明确定义用啥

    断言方法

    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中

    11-3雇员:编写一个名为Employee的类,其方法__init__()接受名、姓和年薪,并将它们都存储在属性中。编写一个名为give_raise()的方法,它默认将年薪增加5000美元,但也能够接受其他的年薪增加量。为Employee编写一个测试用例,其中包含两个测试方法:test_give_default_raise()和test_give_custom_raise()。使用方法setUp(),以免在每个测试方法中都创建新的雇员实例。运行这个测试用例,确认两个测试都通过了。

     1 #Employee.py
     2 class Employee:
     3       """收集打工人的信息"""
     4       def __init__(self, firstname, lastname, money):
     5           """打工人初始化"""
     6           self.firstname = firstname
     7           self.lastname = lastname
     8           self.money = money
     9      def give_raise(self, addmoney=5000):
    10           """应该加的钱(可能吗)"""
    11           self.money += addmoney
    12 
    13 #测试用例
    14 import inttest
    15 from Employee import Employee     #文件Employee内的Employee类         
    16 class EmployeeTestCase(unittest.TestCase):              #如果你在TestCase类中包含了方法setUp(),Python将先运行
    17                                                    # 它,再运行各个以test_打头的方法
    18       """测试不同打工人的信息"""
    19       def setUp(self):
    20            """初始化打工人信息"""                        #方法setUp(),让我们只需创建这些对象一
    21                                                         # 次,并在每个测试方法中使用它们。
    22            self.default = Employee('xiao', 'ma', 1000) #变量名包含前缀self(即存储在属性中)
    23           """默认加的薪水"""
    24           self.default.give_raise()
    25           self.assertEqual(self.default.money,6000)
    26       def test_igive_coustom_raise(self):
    27           """特殊加薪"""
    28           self.default.give_raise(8000)
    29           self.assertEqual(self.default.money,9000)
    30 unittest.main()

    小结:测试代码

    参与工作量较大的项目时,你应对自己编写的函数和类的重要行为进行测试,在项目早期,不要试图去编写全覆盖的测试用例,除非有充分的理由这样做。

    使用模块unittest中的工具来为函数和类编写测试;如何编写继承unittest.TestCase的类,以及如何编写测试方法,以核实函数和类的行为符合预期;如何使用方法setUp()来根据类高效地创建实例并设置其属性,以便在类的所有测试方法中都可使用它们。

     

  • 相关阅读:
    【洛谷P2922】秘密消息【Trie】
    数据结构实验之链表三:链表的逆置
    数据结构实验之链表三:链表的逆置
    数据结构实验之链表一:顺序建立链表
    数据结构实验之链表一:顺序建立链表
    数据结构实验之链表二:逆序建立链表
    数据结构实验之链表二:逆序建立链表
    顺序表应用6:有序顺序表查询
    顺序表应用6:有序顺序表查询
    顺序表应用5:有序顺序表归并
  • 原文地址:https://www.cnblogs.com/Learningpython/p/15802578.html
Copyright © 2020-2023  润新知