参与拿奖:本文已参与「新人创作礼」活动,一起开启掘金创作之路
1.关于测试
①主要测试技术:白盒测试和黑盒测试;
②白盒测试:主要通过阅读程序源代码来判断是否符合功能需求(对于复杂程序的业务逻辑白盒测试难度非常大);
③黑盒测试:不关心模块的内部实现,只关心其功能是否正确,通过精心设计一些测试用例检验模块和输出是否正确来判断是否符合预定的功能需求,一般使用黑盒测试为主,白盒测试为辅的方式测试;
④测试技术对于保证软件质量非常重要。
2.单元测试
①单元测试:使用单元测试来管理设计好的测试用例,可以避免人工输入可能引入的错误,还可以重复利用设计好的测试用例;
②测试案例讲解
a)引入Python测试模块和需要被测试的·模块Stack
import unittest
import Stack
from unittest import TestCase
b)查看测试模块的方法和帮助
#查看模块中的方法
print(dir(unittest),end='\n')
print(dir(unittest.TestCase),end='\n')
#查看方法的使用帮助
help(TestCase.assertEqual)
c)开始编写测试模块(继承公共测试模块)
class myTest(TestCase):
def setUp(self): #每一项测试开始之前自动调用该函数
self.fp=open('test_result.txt','a+') #将测试结果写入此文件
def tearDown(self): #每一项测试结束之后会自动调用该函数
self.fp.close() #关闭打开的文件
d)测试Stack是否为空
def test_isEmpty(self):
try:
s=Stack.Stack()
#确保函数返回为True
self.assertTrue(s.isEmpty()) #判断bool值是否为True
self.fp.write('isEmpty passed\n')
except Exception as e:
self.fp.write('isEmpty failed\n')
e)测试Stack清空操作是否合法
def test_empty(self):
try:
s=Stack.Stack(5)
for i in ['a','b','c']:
s.push(i)
#测试清空栈操作是否正常工作
s.empty()
self.assertTrue(s.isEmpty())
self.fp.write('empty passed\n')
except Exception as f:
self.fp.write('empty failed\n')
f)测试栈满的时候
def test_isFull(self):
try:
s=Stack.Stack(3)
s.push(1)
s.push(2)
s.push(3)
self.assertTrue(s.isFull())
self.fp.write('full passed\n')
except Exception as f:
self.fp.write('full failed\n')
g)测试栈的进出是否合法
def test_pushpop(self):
try:
s=Stack.Stack()
s.push(3)
#确保入栈后立刻出栈为原来的元素
self.assertEqual(s.pop(),3) #判断相等
s.push('a')
self.assertEqual(s.pop(),'a')
self.fp.write('push and pop passed\n')
except Exception as f:
self.fp.write('push or pop failed\n')
h)测试栈设置大小
def test_setSize(self):
try:
s=Stack.Stack(8)
for i in range(8):
s.push(i)
self.assertTrue(s.isFull())
#测试增大空间是否正常工作
s.setSize(9)
s.push(8)
self.assertTrue(s.isFull())
self.assertEqual(s.pop(),8)
#测试缩小栈空间是否异常
s.setSize(4)
self.assertTrue(s.isFull())
self.assertEqual(s.pop(),3)
self.fp.write('setSize passed\n')
except Exception as f:
self.fp.write('aetSize failed\n')
i)测试模块的多个方法的使用
def test_Case(self):
s=Stack.Stack()
s.push(1)
s.push(5)
self.assertIs(s.pop(),1)#is关键字
self.assertIn(s.pop(),[1,2,3]) #in关键字
self.assertIsInstance(s.pop(),int) #isinstance()
self.assertGreater(4,3) #4>3
self.assertLess(3,4) #3<4
self.assertRegex(5,s) #s.search(5)
self.assertAlmostEqual(3,1) #round(3-1,7)==0
j)使用父类的min方法运行测试模块
if __name__=='__main__':
unittest.main()
运行结果如下 文档内容:
empty passed
isEmpty passed
full passed
push and pop passed
setSize passed
命令行运行结果
F.....
======================================================================
FAIL: test_Case (__main__.myTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:/Users/QinHsiu/PythonProjects/String/BaseException/signal-test.py", line 91, in test_Case
self.assertIs(s.pop(),1)#is关键字
AssertionError: 5 is not 1
----------------------------------------------------------------------
Ran 6 tests in 0.024s
FAILED (failures=1)
Process finished with exit code 1
学习笔记:
1.测试用例的设计应该是完备的,应该保证尽可能多的情况,尤其需要覆盖代码的边界条件,对目标模块功能进行充分的测试,以免遗漏;
2.测试用例以及测试代码的设计与编写也可能存在bug,通过测试并不能代表目标代码没有错误,但是一般而言,不能通过测试的模块代码是存在问题的;
3.再好的测试方法和测试用例也无法保证能够发现所有错误,只能通过改进和综合多种测试方法并且精心设计测试用例来发现尽可能多的潜在问题;
4.除了功能测试,还应该对程序进行性能测试和安全性测试,甚至还需要进行规范性测试以保证代码可读性和可维护性。