这一章介绍的内容是测试代码,虽然说我觉得测试就直接打印出来不就好了,不过既然Python中设计了这个功能,那肯定有设计者自己的初衷
11-1 城市和国家
编写一个函数,它接受两个形参:一个城市名和一个国家名。这个函数返回一个格式为
City
,Country
的字符串,如Santiago
,Chile
。将 这个函数存储在一个名为city_functions.py
的模块中。创建一个名为test_cities.py
的程序,对刚编写的函数进行测试(别忘了,你需要导入模块unittest以及要测试的函数)。编写一个名为test_city_country()
的 方法,核实使用类似于'santiago'
和’chile’ 这样的值来调用前述函数时,得到的字符串是正确的。运行test_cities.py
,确认测试test_city_country()
通过了。
#city_functions.py
def city_functions(City, Country):
return City + ',' + Country
#test_cities.py
from city_functions import *
import unittest
class testCases(unittest.TestCase):
def testCityFunction(self):
formatString = city_functions("Guangzhou", "China")
self.assertEqual(formatString, "Guangzhou,China")
unittest.main()
#输出
#.
#----------------------------------------------------------------------
#Ran 1 test in 0.001s
#
#OK
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()
通过了。
#city_functions.py
def cityFunction(City, Country, Population):
return City + ',' + Country + '-population ' + str(Population)
测试模块不改,输出:
E
======================================================================
ERROR: testCityFunction (__main__.testCases)
----------------------------------------------------------------------
Traceback (most recent call last):
File "E:\2017-2018下学期\专选-高级编程技术-3学分\代码\180307E01\180307E01\_180307E01.py", line 6, in testCityFunction
formatString = cityFunction("Guangzhou", "China")
TypeError: cityFunction() missing 1 required positional argument: 'Population'
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
从上述结果可以看出测试不通过,若测试模块也按照改变的函数而改变
from city_functions import *
import unittest
class testCases(unittest.TestCase):
def test_city_country_population(self):
formatString = cityFunction("Guangzhou", "China", 10000000)
self.assertEqual(formatString, "Guangzhou,China-population 10000000")
unittest.main()
#输出
#.
#----------------------------------------------------------------------
#Ran 1 test in 0.001s
#
#OK
这一次通过了
11-3 雇员
编写一个名为
Employee
的类,其方法__init__()
接受名、姓和年薪,并将它们都存储在属性中。编写一个名为give_raise()
的方法,它默认将年薪增加5000
美元,但也能够接受其他的年薪增加量。 为Employee
编写一个测试用例,其中包含两个测试方法:test_give_default_raise()
和test_give_custom_raise()
。使用方法setUp()
,以免在每个测试方法中都创建新的雇员实例。运行这个测试用例,确认两个测试都通过了。
import unittest
class Employee:
def __init__(self, first_name, last_name, salary):
self.first_name = first_name
self.last_name = last_name
self.salary = salary
def give_raise(self, increment = 5000):
self.salary += increment
class testCases(unittest.TestCase):
def setUp(self):
self.employee = Employee("JP", "Wang", 5000)
def test_give_default_raise(self):
self.employee.give_raise()
self.assertEqual(self.employee.salary, 10000)
def test_give_custom_raise(self):
self.employee.give_raise(10000)
self.assertEqual(self.employee.salary, 15000)
unittest.main()
注意!我发现测试模块里对类对象的操作是临时的,第二个测试里如果把
15000
改成20000
就错了(第一次的5000
的薪水增加,出了测试样例就打水漂了)