以下内容B站千峰软件测试训练营内容
引入例子使用简单的例子进行测试脚本的开发:
#开发实现功能myMath.py
class mymath():
def jia(self,a,b):
return a+b
def jian(self,a,b):
return a-b
def chengfa(self,a,b):
return a*b
def chufa (self,a,b):
if b==0:
return 'ee'
else:
return a/b
if __name__=="__main__":
mm=mymath()
#测试用例一:验证数字的加法
actualValue=mm.jia(2,3)
exceptValue=5
if actualValue==exceptValue:
print("该加法功能实现正确",exceptValue)
# 测试用例2:异常用例
try :
actualValue=mm.jia("a",3)
exceptValue = "a3"
if actualValue == exceptValue:
print("该加法功能实现正确",exceptValue)
except Exception as e:
print("该方法实现不正确",e)
#验证字符串的加法
try :
actualValue=mm.jia("a","b")
exceptValue ="ab"
if actualValue == exceptValue:
print("该加法功能实现正确",exceptValue)
except Exception as e:
print("该方法实现正确",e)
输出:
该加法功能实现正确 5
该方法实现不正确 can only concatenate str (not "int") to str
该加法功能实现正确 ab
这种方法的特点:
1.断言方式太low,需要使用if-else进行判断;
2.测试结果在控制台输出,看不到测试报告的效果。
于是引入Unittest框架,其优势在于:
1.提供了用例的组织与形式;
2.提供了丰富的日志和报告;
3.提供了丰富的断言方法,如表1所示.
表1 unittest框架TestCase类提供的断言方法
方法 描述 方法 描述 assertEqual(a,b) a==b assertIn(a,b) a in b assertTrue(x) bool(x) isTrue assertNone(x) x is None assertIs(a,b) a is b assertIsInstance(a,b) isInstance(a,b)
以下将通过unnittest 框架来实现mytest
引入unittest框架来设计mymath单元测试用例
TestCase步骤:
1.导包 unittest是自导的框架,不需要安装;
2.创建一个单元测试类(其实就是类,只不过他继承了单元测试框架单元测试用例的类);
3.单元测试类中的5个方法的使用,包括使用场景及执行顺序;
setUp():测试用例的资源初始化,一般写入测试用例的前提条件;
test_add_1():测试用例,把测试用例步骤写在这个方法中;
tearDown()用于测试用例的资源释放。
@classmethod注解的是类方法,不用创建对象也能用,在对象创建之前就已经存在
的方法随着类进入内存。
setUpClass给当前所有的测试类进行初始化
tearDownClass给所有的单元测试用例进行资源释放
4.创建测试用例:test开头的方法,与代码顺序无关
5.测试用例的执行:
main():所有的测试用例执行一遍,测试用例的执行顺序按照测试用例方法名的字母序执行的。
import unittest
from myMath import mymath
#创建一个单元测试类(继承自unittest.testcase)
class myMathTest(unittest.TestCase):
#测试用例资源初始化方法
def setUp(self):
self.mm=mymath()
#测试用例方法
def test_add_1(self):
actualValue=self.mm.jia(2,1)
exceptValue=3
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
#测试用例方法
def test_add_2(self):
actualValue=self.mm.jia("ab","cd")
exceptValue="abcd"
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_jian_1(self):
actualValue=self.mm.jian(2,1)
exceptValue=1
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_cheng_1(self):
actualValue=self.mm.chengfa(2,5)
exceptValue=10
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_cheng_2(self):
actualValue=self.mm.chengfa("a",2)
exceptValue="aa"
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_chu_1(self):
actualValue=self.mm.chufa(4,2)
exceptValue=2
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_chu_2(self):
actualValue=self.mm.chufa(4,0)
exceptValue=2
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
#测试用例的资源
def tearDown(self) -> None:
pass
if __name__ == '__main__':
unittest.main()#运行所有的测试用例
控制台输出:
C:\Users\beauty\AppData\Local\Programs\Python\Python38\python.exe C:/Users/beauty/Desktop/test_project/venv/run_test_unittest_2py.py
F.
======================================================================
FAIL: test_add_1 (__main__.unitMymath)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:/Users/beauty/Desktop/test_project/venv/run_test_unittest_2py.py", line 26, in test_add_1
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
AssertionError: 22 != 24 : 预期结果与实际结果不一致
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
我是setUpClass方法
我是setup方法
我是第一条测试用例
我是teardown方法
我是setup方法
我是第二条测试用例
我是teardown方法
我是tearDownClass方法
Process finished with exit code 1
使用测试集合概念(testsuit)的方法解决存在的问题:1.运行所有测试用例,2.执行顺序;
testsuite:
1.调用testsuite的对象
2.调用testsuite中的方法addtest()、addtests()将测试用例加入集合中
3.testsuite的run()方法运行测试集合
注意run方法的参数是testresult的对象:re = unittest.TestResult()
4.使用print(re.__dict__)可显示测试运行的结果
if __name__=="__main__":
#1.创建testsuite的方法
suitt=unittest.TestSuite()
#测试集合对象有一个方法"test_add_1"。
# addtest单次追加测试用例到测试集合;addtsets追加多个测试用例,且对象为可迭代的
#格式:类名(用例名)
suitt.addTest(unitMymath("test_add_2"))#测试集合对象有一个方法"test_add_2先执行"。
suitt.addTest(unitMymath("test_add_1"))
re = unittest.TestResult()
suitt.run(re)
if __name__=="__main__":
#1.创建testsuite的方法
suitt=unittest.TestSuite()
suitt.addTests(map(unitMymath,["test_add_2","test_add_1"]))#创建一个组合
re = unittest.TestResult()
suitt.run(re)
两种方法运行结果相同:
C:\Users\beauty\AppData\Local\Programs\Python\Python38\python.exe C:/Users/beauty/Desktop/test_project/venv/run_test_unittest_2py.py
我是setUpClass方法
我是setup方法
我是第二条测试用例
我是teardown方法
我是setup方法
我是第一条测试用例
我是teardown方法
我是tearDownClass方法
Process finished with exit code 0
实际的测试中会有大量的测试用例,使用testsuite自带的方法加载到集合很麻烦,可使用unittest模块提供的testloader模块,可以将测试用例加载到测试集合中
TestLoader:
1.创建TestLoader对象:loader=unittest.TestLoader()
2.loadtestsfromName通过添加的模块名、类名、测试用例名,将其中的的用例直接加载到测试集合,返回给测试对象
# suitt=loader.loadTestsFromName("run_test_unittest_2py")模块名
# suitt=loader.loadTestsFromName("run_test_unittest_2py.unitMymath")#类名
suitt=loader.loadTestsFromName("run_test_unittest_2py.unitMymath.test_add_2")#测试用例名
3.使用loader的discover方法,将指定文件(模块)中的测试用例一次性加载。使用的方法suitt=unittest.defaultTestLoader.discover(filename,pattern="run_test_unittest_1.py"):
path:指定存放测试用例的目录即可(单元测试用例,使用unitest框架写的)
pattern:只当匹配规则,run_test*.py
#testsuite:
# 创建testsuite的对象
# 调用testsuite的方法addtess、addtests()将测试用例加入测试集合
# 3.testsuite的run方法运行测试集合
import unittest
import myMath
class unitMymath(unittest.TestCase):
#使用@给方法指定了特殊的含义
@classmethod
def setUpClass(cls) -> None:
print("我是setUpClass方法")
@classmethod
def tearDownClass(cls) -> None:
print("我是tearDownClass方法")#释放资源
#方法名不能该
def setUp(self) -> None:
self.mm = myMath.mymath()#共同测试用例的方法
print("我是setup方法")
#必须test开头的方法,即测试用例
def test_add_1(self):
print("我是第一条测试用例")
#mm=myMath.mymath()
actualValue=self.mm.jia(10,12)
exceptValue=22
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_add_2(self):
print("我是第二条测试用例")
#mm=myMath.mymath()
actualValue=self.mm.jia('a','b')
exceptValue='ab'
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
# 方法名不能该
def tearDown(self) -> None:
print("我是teardown方法")
if __name__=="__main__":
#1.创建testsuite的方法创建测试集合对象
suitt=unittest.TestSuite()
# 1.创建testloader的对象
loader=unittest.TestLoader()
suitt=loader.loadTestsFromName("run_test_unittest_2py.unitMymath.test_add_2")#测试用例名
# #测试结果
re=unittest.TestResult()
# #测试集合中有run方法,直接运行即可
suitt.run(re)
print(re.__dict__)#测试运行的结果
控制台输出:
C:\Users\beauty\AppData\Local\Programs\Python\Python38\python.exe C:/Users/beauty/Desktop/test_project/venv/run_test_unittest_2py.py
我是setUpClass方法
我是setup方法
我是第二条测试用例
我是teardown方法
我是tearDownClass方法
{'failfast': False, 'failures': [], 'errors': [], 'testsRun': 1, 'skipped': [], 'expectedFailures': [], 'unexpectedSuccesses': [], 'shouldStop': False, 'buffer': False, 'tb_locals': False, '_stdout_buffer': None, '_stderr_buffer': None, '_original_stdout': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, '_original_stderr': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, '_mirrorOutput': False, '_testRunEntered': False, '_moduleSetUpFailed': False, '_previousTestClass': <class 'run_test_unittest_2py.unitMymath'>}
Process finished with exit code 0
以下需要导入import os
测试用例为run_test_unittest_1
if __name__=="__main__":
#1.创建testsuite的方法创建测试集合对象
suitt=unittest.TestSuite()
loader=unittest.TestLoader()
filename = os.path.dirname(__file__)
# # #使用testloader对象的discover方法加载测试用例,第一个参数是一个目录,这个目录下可以由单元测试用例的文件unittest_1文件
suitt=unittest.defaultTestLoader.discover(filename,pattern="run_test_unittest_1.py")
#
# #测试结果
re=unittest.TestResult()
# #测试集合中有run方法,直接运行即可
suitt.run(re)
print(re.__dict__)#测试运行的结果
TestRunner:
前面测试结果都是使用testsuite()的run方法,suitt.run(re),运行的结果是在控制台输出。
TextTestRunner()将结果以text的形式展示。
'''
run_test_unittest_4.py
使用unittest框架测试mymath类中的加减乘除
使用步骤:
1.导模块(unittest模块、mymath模块)
2.创建一个单元测试类(继承自unittest.testcase)
3.定义三个测试用例的方法
def setUp()
def test_xx()
def tearDown()
'''
#
import os
import unittest
from myMath import mymath
#创建一个单元测试类(继承自unittest.testcase)
class myMathTest(unittest.TestCase):
#测试用例资源初始化方法
def setUp(self):
self.mm=mymath()
#测试用例方法
def test_add_1(self):
actualValue=self.mm.jia(2,1)
exceptValue=3
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
#测试用例方法
def test_add_2(self):
actualValue=self.mm.jia("ab","cd")
exceptValue="abcd"
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_jian_1(self):
actualValue=self.mm.jian(2,1)
exceptValue=1
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_cheng_1(self):
actualValue=self.mm.chengfa(2,5)
exceptValue=10
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_cheng_2(self):
actualValue=self.mm.chengfa("a",2)
exceptValue="aa"
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_chu_1(self):
actualValue=self.mm.chufa(4,2)
exceptValue=2
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
def test_chu_2(self):
actualValue=self.mm.chufa(4,0)
exceptValue=2
#断言
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
#测试用例的资源
def tearDown(self) -> None:
pass
if __name__ == '__main__':
#创建一个测试集合
suitt=unittest.TestSuite()
#直接使用TestLoader的discover方法返回测试集
discover=unittest.defaultTestLoader.discover(r"./",pattern="run_test_unittest_4.py")
#使用TextTestRunner()运行器提供的run()行测试集,a为写模式
#创建一个文件流对象,打开文件进行写数据
with open (r"./re.txt","w",encoding="utf-8") as f:
runner=unittest.TextTestRunner(f,descriptions="用于测试math类的用例测试",verbosity=2)
runner.run(discover)#测试集合
运行结果
re.txt文件的内容:
test_add_1 (run_test_unittest_4.myMathTest) ... ok
test_add_2 (run_test_unittest_4.myMathTest) ... ok
test_cheng_1 (run_test_unittest_4.myMathTest) ... ok
test_cheng_2 (run_test_unittest_4.myMathTest) ... ok
test_chu_1 (run_test_unittest_4.myMathTest) ... ok
test_chu_2 (run_test_unittest_4.myMathTest) ... FAIL
test_jian_1 (run_test_unittest_4.myMathTest) ... ok
======================================================================
FAIL: test_chu_2 (run_test_unittest_4.myMathTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\beauty\Desktop\test_project\venv\run_test_unittest_4.py", line 57, in test_chu_2
self.assertEqual(actualValue,exceptValue,"预期结果与实际结果不一致")
AssertionError: 'ee' != 2 : 预期结果与实际结果不一致
----------------------------------------------------------------------
Ran 7 tests in 0.003s
FAILED (failures=1)s