当测试代码中含有两个测试类的时候,我们需要重新编写测试代码
被测代码,加了一个需要被测试的减法的功能:
#计算器类
from selenium import webdriver
class Count:
def __init__(self,a,b):
self.a = int(a)
self.b = int(b)
def add(self):
return self.a+self.b
def sub(self):
return self.a-self.b
测试代码为:
#两个类的测试执行方法
import unittest
from count import Count
class TestCountAdd(unittest.TestCase):
def setUp(self):
print("star add test")
def test_add(self):
t = Count(2,4)
add = t.add()
self.assertEqual(add,6)
print("add test case1")
def tearDown(self):
print("test add end")
class TestCountSub(unittest.TestCase):
def setUp(self):
print("star sub test")
def test_sub(self):
t = Count(10,2)
sub = t.sub()
self.assertEqual(sub,8)
print("sub test case1")
def tearDown(self):
print("test sub end")
#执行测试类的测试方法
if __name__ == '__main__':
# 构造测试集
suite = unittest.TestSuite()
suite.addTest(TestCountAdd("test_add"))
suite.addTest(TestCountSub("test_sub"))
#执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
其实一个被测的功能点,可以有多个测试用例,如果这样写的话,相当于所有功能点和所有的测试用例会在一个文件里面产生,如果功能点越多,测试用例也会越多,维护起来很麻烦,所以我们可以将一个测试功能的测试用例放入一个文件中,将add和sub各存入一个文件中,testadd.py 和testsub.py
#测试加法功能测试用例
import unittest
from .count import Count
class TestCountAdd(unittest.TestCase):
def setUp(self):
print("star add test")
def test_add1(self):
t = Count(2,4)
add = t.add()
self.assertEqual(add,6)
print("add test case1")
def test_add2(self):
t = Count(7,3)
add = t.add()
self.assertEqual(add,10)
print("add test case2")
def tearDown(self):
print("test add end")
if __name__ == '__main__':
# 构造测试集
suite = unittest.TestSuite()
suite.addTest(TestCountAdd("test_add1"))
suite.addTest(TestCountAdd("test_add2"))
#执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
--------------------------------------------------------------我是分割线-----------------------------------------------------------
#测试减法测试用例
import unittest
from .count import Count
class TestCountSub(unittest.TestCase):
def setUp(self):
print("star sub test")
def test_sub1(self):
t = Count(10,2)
sub = t.sub()
self.assertEqual(sub,8)
print("sub test case1")
def test_sub2(self):
t = Count(20,2)
sub = t.sub()
self.assertEqual(sub,18)
print("sub test case2")
def tearDown(self):
print("test sub end")
#执行测试类的测试方法
if __name__ == '__main__':
# 构造测试集
suite = unittest.TestSuite()
suite.addTest(TestCountSub("test_sub1"))
suite.addTest(TestCountSub("test_sub2"))
#执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
想要同时运行testadd.py和testsub.py测试用例,可以新建一个testall.py来运行:
import unittest
from testcase import testadd
from testcase import testsub
suite = unittest.TestSuite()
suite.addTest(testadd.TestCountAdd("test_add1"))
suite.addTest(testadd.TestCountAdd("test_add2"))
suite.addTest(testsub.TestCountSub("test_sub1"))
suite.addTest(testsub.TestCountSub("test_sub2"))
# 执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
运行结果如下:
以上这种如果测试用例达到上百条的话,对于想要注释某几条用例不运行的话,还算比较方便,而且能够调整测试用例的优先级运行。但是如果全部都要运行的话,那就太麻烦,unittest提供了另一外一种方法也可以运行全部测试用例:
import unittest
'''
使用discover = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None)
test_dir :要测试的模块名或测试用例目录
pattern='test*.py':表示用例文件名的匹配原则,此处匹配文件名以test开头的“.py”类型的文件
星号表示任意多个字符
top_level_dir=None:测试模块的顶层目录,如果没有顶层目录,默认为None
'''
test_dir="./testcase" #需要测试文件的目录
aaa = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')#需要测试的文件
# 执行测试
runner = unittest.TextTestRunner()
runner.run(aaa)
这里一定要注意测试用例的命名,一定要以test开头,要不然unittest是识别不了的,就不会运行非test开头的测试用例,首先测试类要继承过来,然后再是测试方法必须以test开头,unittest就能执行了
__init__.py文件表示当前目录是一个标准的Python包文件目录
unittest的执行顺序
用例的执行顺序会涉及到多个层级,它是按照ASC码的顺序运行的:
1~9
a~z
A~Z
不按用例先写或者后写的顺序,在字符和数字面前,首先先运行数字名称的用例,在大小写面前,先运行大写后运行小写字符。
数字>大写字符>小写字符
目录、文件名、测试类、测试方法都是按以上规则运行
Python跳过测试用例的方法(装饰器):
Python跳过测试用例的方法(装饰器)和用法:
-unittest.skip(reason):无条件跳过装饰的测试,说明原因
@unittest.skip("就是不想执行")
-unittest.skipIf(condition,reason):跳过装饰的测试,如果条件为真时
@unittest.skipIf(1>2,"当条件为true时跳过本条测试用例")
-unittest.skipUnless(condition,reason):跳过装饰的测试,如果条件为真
@unittest.skipIf(3>2,"当条件为true时跳过本条测试用例")
-unittest.expectedFailure():测试标记为失败
@unittest.expectedFailure
例子:
@unittest.skip("就是不想执行")
def test_sub1(self):
t = Count(10,2)
sub = t.sub()
self.assertEqual(sub,8)
print("sub test case1")
执行结果会打印一条OK(skipped=1)表示有一条没有执行,会有S的标志,输出成功会有.的标志
装饰器一般测试用例经常用,比如前置条件成功,下一条就执行,不成功,就不执行。比如:
@unittest.skipIf(1>2,"当条件为true时跳过本条测试用例")
def test_sub1(self):
t = Count(10,2)
sub = t.sub()
self.assertEqual(sub,8)
print("sub test case1")
以上程序为false就会将本条测试用例执行
----------------------------------------------------------我是分割线---------------------------------------------------------------
setUpModule/tearDownModule:在整个模块的开始与结束时被执行
setUpClass/tearDownClass:在测试类的开始与结束时被执行
setUp/tearDown:在测试用例的开始与结束时被执行
需要注意的是setUpClass/tearDownClass的写法稍微不同,必须通过@classmethod进行装饰,其次方法的参数为cls,其实cls和self没有什么特别之处,都只表示类方法的一个参数,也可以用abc来代替。