测试代码 unittest
1.概述。
相信接触过Java语言的朋友一定对Junit单元测试框架不陌生,对于Python语言,同样有类似的单元测试框架Unittest。
Unittest是Python内部自带的一个单元测试的模块,它设计的灵感来源于Junit,具有和Junit类似的结构,有过Junit经验的朋友可以很快上手。Unittest具备完整的测试结构,支持自动化测试的执行,对测试用例集进行组织,并且提供了丰富的断言方法,最后生成测试报告。Unittest框架的初衷是用于单元测试,但也不限于此,在实际工作中,由于它强大的功能,提供的完整的测试流程,我们往往将其用于自动化测试的各个方面,例如在本书中大量的接口测试实例都会用到Unittest。
所谓知己知彼百战不殆,首先我们来一起看下Unittest大家庭里的成员。首先导入unittest模块,使用dir()函数获取Unittest的所有成员,并输出到界面上。
import unittest
print(dir(unittest))
执行结果如下:
['BaseTestSuite', 'FunctionTestCase', 'SkipTest', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'TestSuite', 'TextTestResult', 'TextTestRunner', '_TextTestResult', 'all', 'builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'path', 'spec', '__unittest', 'case', 'defaultTestLoader', 'expectedFailure', 'findTestCases', 'getTestCaseNames', 'installHandler', 'load_tests', 'loader', 'main', 'makeSuite', 'registerResult', 'removeHandler', 'removeResult', 'result', 'runner', 'signals', 'skip', 'skipIf', 'skipUnless', 'suite', 'util']
三、unittest模块的常用断言方法
python在unittest.TestCase类中提供了很多断言方法。
使用这些方法可核实返回的值等于或不等于预期的值,返回的值True和False、返回的值在列表中或者不在列表中。只能在unittest.testcase的类中使用这些方法。
方法 | 含义 |
---|---|
assertEqual(a, b) | a == b |
assertNotEqual(a, b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a, b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsInstance(a, b) | not isinstance(a, b) |
导入模块
import unittest
class Test(unittest.TestCase):
def testA(self):
'''判断a == b'''
a = 1
b = 1
self.assertEqual(a,b)
def testB(self):
'''判断a in b'''
a = "hi!"
b = "hi! leihao"
self.assertIn(a,b)
def testC(self):
'''判断a is True'''
a = True
self.assertTrue(a)
def testD(self):
'''失败案例'''
a = "aaa"
b = "bbb"
self.assertEqual(a, b)
if __name__ == '__main__':
unittest.main()
结果:
C:\python\python.exe C:\ProgramFiles\JetBrains\PyCharm2018.3\helpers\pycharm\_jb_unittest_runner.py --path D:/python资料/30s/代码/测试代码/test_name.py
Launching unittests with arguments python -m unittest D:/python资料/30s/代码/测试代码/test_name.py in D:\python资料\30s\代码
bbb != aaa
Expected :aaa
Actual :bbb
<Click to see difference>
Traceback (most recent call last):
File "C:\ProgramFiles\JetBrains\PyCharm2018.3\helpers\pycharm\teamcity\diff_tools.py", line 32, in _patched_equals
old(self, first, second, msg)
File "C:\python\lib\unittest\case.py", line 829, in assertEqual
assertion_func(first, second, msg=msg)
File "C:\python\lib\unittest\case.py", line 1203, in assertMultiLineEqual
self.fail(self._formatMessage(msg, standardMsg))
File "C:\python\lib\unittest\case.py", line 670, in fail
raise self.failureException(msg)
AssertionError: 'aaa' != 'bbb'
- aaa
+ bbb
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\python\lib\unittest\case.py", line 59, in testPartExecutor
yield
File "C:\python\lib\unittest\case.py", line 605, in run
testMethod()
File "D:\python资料\30s\代码\测试代码\test_name.py", line 38, in testD
self.assertEqual(a, b)
Ran 4 tests in 0.007s
FAILED (failures=1)
Process finished with exit code 1
示例
1.接收名字和姓氏,并返回整洁的姓名
first:姓氏
last:名字
middle:中间字
定义服务类
def get_formatted_name(first,last,middle=''):
"""将名和行合并成姓名,性和名之间加上一个空格,并将它们返回的首字母大写"""
if middle: #判断有无中间字
full_name = first + ' '+middle+' '+ last
else:
full_name = first + ' ' + last
return full_name.title() #首字母大写
if __name__ == '__main__':
li = get_formatted_name
print(li("li","guoshuai"))
定义调用类
"""编写一个程序调用名字合并工具"""
from .name_function import get_formatted_name
print("退出:q")
while True:
first = input("\n请输入姓:")
if first == "q":
break
last = input("\n请输入名:")
if last == "q":
break
fromat = get_formatted_name(first,last)
print("\n欢迎" + fromat + '.')
定义测试类
import unittest #调用测试模块
from .name_function import get_formatted_name
class NameTest(unittest.TestCase): #继承测试主类
"""测试name_function函数"""
#无中间字测试
def test_first(self):
"""能够正确的处理像janis joplin这样的名字吗?"""
formatted_name = get_formatted_name("janis","joplin") #输入调用函数参数
self.assertEqual(formatted_name,"Janis Joplin") #比较结果是否一致
#有中间字测试
def test_fist_last_middle(self):
formatted_name = get_formatted_name("janis","jopline","love") #输入调用函数参数
self.assertEqual(formatted_name,"Janis Love Jopline") #比较结果是否一致
if __name__ == "__main__":
unittest.main()
2.国家-城市-人口数量
以 国家-省会-人口数量形式输出
人口数量不是必填项
```
**功能类**
```
def City_func(city,country,population = ''):
if population:
func_name = city + "-" + country +'-'+ "人口数量:" + str(population)
else:
func_name = city + "-" + country
return func_name
if __name__ == '__main__':
li = City_func
li2 = City_func
print(li("中国","河北",2200))
print(li2("中国","河北"))
结果:
中国-河北-人口数量:2200
中国-河北
```
**调用**
```
from name_function import City_func
while True:
print("\n退出请输入q")
city = input("\n请输出国家名称: ")
if city == "q":
break
country = input("\n请输入省会名称:")
if country == "q":
break
popu = input("\n请输入人口数量:")
if popu == "q":
break
name_func = City_func(city,country,popu)
print(f"输入的为:{name_func}")
结果:
退出请输入q
请输出国家名称: 中国
请输入省会名称:石家庄
请输入人口数量:20000
输入的为:中国-石家庄-人口数量:20000
退出请输入q
请输出国家名称: 中国
请输入省会名称:石家庄
请输入人口数量:
输入的为:中国-石家庄
```
****
**测试类**
```
import unittest
from .name_function import City_func
class Test_func(unittest.TestCase):
def test_city(self):
name_func = City_func("中国","石家庄")
self.assertEqual(name_func,"中国-石家庄")
def test_city_popu(self):
name_func_popu = City_func("中国","石家庄",50000)
self.assertEqual(name_func_popu,"中国-石家庄-人口数量:50000")
结果:
Ran 2 tests in 0.001s
OK
```
# 测试类
>很多程序中都会用到测试类,因此能够证明你的类能够正确的工作会大有裨益。如果针对类的测试通过了,就能确信对类所做的改进没有意义地破坏其原有的行为。
## 一个要测试的类
**server.py**
```
class Anonymous():
"""收集匿名调查问卷的答案"""
def __init__(self,question):
self.question = question
self.list = []
def show_question(self):
"""显示调查问卷问题"""
print(self.question)
def store_response(self,new_response):
"""存储单份调查问卷"""
self.list.append(new_response)
def show_results(self):
"""显示收集到的所有答案"""
print("收集的问卷:")
for i in self.list:
print('- ' + i)
```
**测试.py**
//方法一
```
import unittest
from .survey import Anonymous
class Testanony(unittest.TestCase):
def setUp(self):
"""创建一个调查对象和一组答案,供使用的测试方法使用"""
ques = "你喜欢哪一门课程"
self.my_survey = Anonymous(ques) #调查对象
self.responses = ['数学','语文','英语'] #答案
def test_store(self):
"""单个答案测试答案会被妥善保存"""
self.my_survey.store_response(self.responses[0]) #取列表第一份值
self.assertIn(self.responses[0],self.my_survey.list) #第一个值是否在list列表中
def test_store_three(self):
"""三个答案都会被妥善保存"""
for i in self.responses:
self.my_survey.store_response(i)
for i in self.responses:
self.assertIn(i,self.my_survey.list)
if __name__ == '__main__':
unittest.main()
```
//方法二
```
import unittest
from .survey import Anonymous
class Test(unittest.TestCase):
"""针对选课的测试类"""
def test_store(self):
"""测试单个答案并妥善保存"""
question = "你喜欢哪一门课程?"
my_survey = Anonymous(question)
my_survey.store_response('语文')
print(my_survey.list)
self.assertIn('语文',my_survey.list)
def test_three(self):
"""测试三个答案都会被妥善存储"""
question = "你喜欢哪一门课程"
my_survey = Anonymous(question)
responses = ['English','Spanish','语文']
#添加多个问卷答案
for i in responses:
my_survey.store_response(i)
print(my_survey.list)
#查看单个答案在list列表中没有
for rep in responses:
self.assertIn(rep,my_survey.list)
if __name__ == '__main__':
unittest.main()
```
//运行结果
```
C:\python\python.exe C:\ProgramFiles\JetBrains\PyCharm2018.3\helpers\pycharm\_jb_unittest_runner.py --path D:/python资料/30s/代码/测试类/test_surver.py
Launching unittests with arguments python -m unittest D:/python资料/30s/代码/测试类/test_surver.py in D:\python资料\30s\代码
Ran 2 tests in 0.001s
OK
```
**调用.py**
```
from survey import Anonymous
#定义一个问题,并创建一个表示调查的对象
question = "你喜欢那一门课程?"
my_survey = Anonymous(question)
#显示问题并存储答案
my_survey.show_question()
print("按Q退出")
while True:
response = input("输入:")
if response == 'q':
break
my_survey.store_response(response)
print(f'\n{question}')
my_survey.show_results()
```
//结果
```
C:\python\python.exe D:/python资料/30s/代码/测试类/language.py
你喜欢那一门课程?
按Q退出
输入:yuwen
输入:shuxue
输入:q
你喜欢那一门课程?
收集的问卷:
- yuwen
- shuxue
Process finished with exit code 0
```
## 雇员
>将输入人员的默认年薪都增加5万元,也接收其他方式的增加年薪
**server.py**
```
class Employee():
def __init__(self,na,me,mag):
"""接收名,姓和年龄"""
self.na = na
self.me = me
self.mag = mag
def give_raise(self,qq=0):
"""将年薪增加5万元,但也能够接收其他的年薪增加量"""
#姓名拼接
list = []
list.append(self.me)
list.append(self.na)
name = "".join(list)
mag = int(self.mag) + 50000 + int(qq) #增加5万元年薪
#输出姓名和年薪
print(f"姓名:{name},年薪:{mag}元")
if __name__ == '__main__':
li = Employee('悟空','孙',100000)
li.give_raise(10000)
```
**ceshi.py**
```
import unittest
from .survey import Employee
class Test(unittest.TestCase):
def setUp(self):
self.na = 'li'
self.me = 'guoshuai'
self.mag = 800000
def test_give_default(self):
"""年薪增加5万元"""
my = Employee(self.na,self.me,self.mag)
my.give_raise()
def test_give_custom(self):
"""其他增加年薪方法,并年薪增加5万元"""
my = Employee(self.na,self.me,self.mag)
my.give_raise(87654)
if __name__ == '__main__':
unittest.main()
```
```
结果:
姓名:guoshuaili,年薪:937654元
姓名:guoshuaili,年薪:850000元
Ran 2 tests in 0.001s
OK
```
# 1.setUP()方法
**用途**
>unittest.TestCase类包含方法setUp(),让我们只需要创建这些对象一次,并在每个测试方法中使用他们。
>如果你在测试类中包含了方法setUP()方法,python将会先运行它,在运行各个test_打头的方法,这样,在编写的每个测试方法中都可以使用setUP()方法中创建的对象了。
**示例**
```
class 类名(unittest.TestCase):
def setUp():
"""
用例
"""
```
标签:__,name,python,unittest,测试代码,self,def
From: https://www.cnblogs.com/megshuai/p/18518334