作用:测试用例的管理、运行、编写、输出测试报告等功能。
selunium定位方法,页面元素方法.控制浏览器的方法. ----砖瓦
unittest ----框架
selenium和unittest结合 ,才能造出“高楼大厦”
用这个框架可以做ui自动化,接口自动化,app自动化。具体做什么取决于里面的测试用例。框架搭成了里面放什么样的用例就是什么测试。
环境搭建:不用搭环境,也不用安装,是python自带的,导包就行
unittest的几个核心要素:
TestCase: 测试用例类
Fixture: 测试固件,用于测试用例环境的搭建和销毁. setUP()前置条件 和 tearDown()后置条件
TestSuite: 测试套件,把需要执行的测试用例 集合在一起.
TextTestRunner: 测试执行器,执行测试用例。执行完用例之后会生成一个文字版的测试报告
report: 第三方的库 HTMLTestRunner(简陋),BeautifulReport(完善漂亮)。既然都是用第三方库,为什么不用个完善、漂亮的呢
unittest的语法规则:
1.用例类必须继承于unittest.TestCase
2.所有的测试用例,必须以test开头
3.运行的顺序与代码的位置无关,按照 ASCII 升序排列, 0-9,A-Z,a-z
语法规则举例
- 按照 ASCII 升序排列, 0-9,A-Z,a-z
import unittest
class TestShop(unittest.TestCase):
def test_A(self):
print("this is test_A")
def test_01(self):
print("this is test_01")
def test_a(self):
print("this is test_a")
if __name__ == '__main__':
unittest.main()
代码的顺序是A、01、a,但是执行的结果不是按照代码的顺序,而是01、A、a
- 所有的测试用例,必须以test开头
class TestShop(unittest.TestCase):
def ptest_A(self):
print("this is test_A")
def test_01(self):
print("this is test_01")
def test_a(self):
print("this is test_a")
if __name__ == '__main__':
unittest.main()
我的ptyst_A不是以test开头,而是以ptyst开头,所以执行结果就没有ptyst这个用例,只有以test开头的两个用例了
测试用例类举例
# 导入unittest
import unittest
# 用测试用例里的类方法表示测试用例
# 必须继承于unittest.TestCase
class TestShop(unittest.TestCase):
# 定义测试用例
# test_01,test_02,test_03代表三个测试用例,里面可以写具体的测试用例,比如登录、注册…
def test_01(self):
print("this is test1")
def test_02(self):
print("this is test2")
def test_03(self):
print("this is test3")
if __name__ == '__main__':
# 运行用例
unittest.main()
结果中可以看到,运行三个测试用例用了0.012秒,运行成功
Fixture:前置方法 和 后置方法
测试用例方法的前置条件和后置条件
每一条测试用例运行之前,都会运行setUp()方法,运行之后都会运行tearDown()方法
import unittest
class TestShop1(unittest.TestCase):
def setUp(self) -> None:
print("---setUp of TestShop1---")
def tearDown(self) -> None:
print("---tearDown of TestShop1---")
def test_A(self):
print("this is test_A")
def test_01(self):
print("this is test_01")
def test_a(self):
print("this is test_a")
class TestShop2(unittest.TestCase):
def setUp(self) -> None:
print("---setUp of TestShop2---")
def tearDown(self) -> None:
print("---tearDown of TestShop2---")
def test3(self):
print("this is test3")
def test2(self):
print("this is test2")
def test1(self):
print("this is test1")
if __name__ == '__main__':
unittest.main()
类的前置条件后置条件
import unittest
from selenium import webdriver
driver = webdriver.Chrome()
class TestShop2(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
print("打开浏览器")
driver.get("http://shop.pro.17lebo.com/")
@classmethod
def tearDownClass(cls) -> None:
print("关闭浏览器")
driver.quit()
def test3(self):
print("this is test3")
def test2(self):
print("this is test2")
def test1(self):
print("this is test1")
if __name__ == '__main__':
unittest.main()
测试套件 TestSuite
要创建一个包,存放测试用例
1.逐个添加测试用例
想加哪个加哪个。添加用例之前,要导入进来
先在case01里创建用例,创建好后导入进来
然后再实例化测试套件
在用例类中运行时用例必须以test开头,用套件运行时是强制把用例加进套件中的,所以如果不是以test开头的用例也能运行。
# testsuite 测试套件
import unittest
from cases.case01 import TestShop1
from cases.case01 import TestShop2
# 实例化测试套件
suite01 = unittest.TestSuite()
# 将测试用例加入测试套件 按照加入的顺序运行
suite01.addTest(TestShop1("test_a"))
suite01.addTest(TestShop1("test_01"))
# 实例化一个运行器
runner = unittest.TextTestRunner()
# 运行suite01这个测试套件
runner.run(suite01)
可以看到两个用例都运行了
两个红点代表两个用例都是运行成功的
2. 加载测试用例类
就是把整个类中的测试用例全都加载出来(名字必须以test开头才可以加载出来)
import unittest
from cases.case01 import TestShop1
from cases.case01 import TestShop2
# 实例化测试套件
suite01 = unittest.TestSuite()
# 实例化一个loader
loader = unittest.TestLoader()
# 把测试用例类加入测试套件
suite01.addTest(loader.loadTestsFromTestCase(TestShop1))
# 实例化一个运行器
runner = unittest.TextTestRunner()
runner.run(suite01)
我这个用例类中只有三条用例,三条用例都加载出来并执行成功
3. 加载模块中的测试用例
import unittest
import cases.case01
# 实例化测试套件
suite01 = unittest.TestSuite()
# 实例化一个loader
loader = unittest.TestLoader()
# 2.把测试用例类加入测试套件
# suite01.addTest(loader.loadTestsFromTestCase(TestShop1))
# 3.加载模块中的测试用例
suite01.addTest(loader.loadTestsFromModule(cases.case01))
# 实例化一个运行器
runner = unittest.TextTestRunner()
runner.run(suite01)
case01这个模块下所有的类,类中所有符合命名规范的用例(test开头)全都执行成功
4.加载目录下所有测试用例模块
import unittest
# 实例化测试套件
suite01 = unittest.TestSuite()
# 加载目录下所有用例模块
case_path = "./cases"
# start_dir是用例模块的路径,pattern是模块名
discover = unittest.defaultTestLoader.discover(start_dir=case_path,pattern="case*.py")
# 实例化一个运行器
runner = unittest.TextTestRunner()
runner.run(discover)
两个模块一共12条用例(test开头)全部执行成功
断言
其实断言就是看一下实际运行的结果是否和预期结果一致。
unittest中提供了一套内置的断言方法。如果断言失败,会抛错assertExpression,然后case变成失败状态。如果断言成功,case为成功状态。
我们做测试就是为了看结果是否符合预期,那么怎么判断就要有一些条件。
断言一般会写在测试用例中。
assertEqual:判断两个参数是否相等
举例1
比如在用例中添加断言,写了前后两个参数都是1,是相等的
那么结果中就不会有断言相关的内容,说明断言是正确符合预期的
举例2
比如在用例中添加断言,写了前面的参数是1,后面的参数是2,是不相等的
那么执行结果中就会抛出异常
一共执行了6条用例,第一条的用例断言失败,所以显示是F,后面会抛出异常AssertionError
捕获异常
断言如果失败,会抛错,看着有点丑。所以可以捕捉异常(当然,就算是不捕捉异常,断言失败也不会导致程序崩溃)
这时执行结果中可以看到,虽然断言失败了,但是不会抛错
assertIn:判断你前面的参数是否在后面的参数之内
执行结果是正常的
如果前面的参数不在后面列表的范围内
那么执行结果明显看到 断言失败,抛错
如果一个用例模块中有多个断言都失败,那么结果中会有提示共失败几个用例
常见断言方法
方法 | 检查 | 描述 |
---|---|---|
assertEqual(a, b) | a == b | 验证a是否等于b |
assertNotEqual(a, b) | a != b | 验证a是否不等于b |
assertTrue(x) | bool(x) is True | 验证x是否为ture |
assertFalse(x) | bool(x) is False | 验证x是否为flase |
assertIs(a, b) | a is b | 验证a,b是否为同一个对象 |
assertIsNot(a, b) | a is not b | 验证a,b不是同一个对象 |
assertIsNone(x) | x is None | 验证x是否是None |
assertIsNotNone(x) | x is not None | 验证x是否非None |
assertIn(a, b) | a in b | 验证a是否是b的子串 |
assertNotIn(a, b) | a not in b | 验证a是否非b的子串 |
assertIsInstance(a, b) | isinstance(a, b) | 验证a是否是b的实例 |
assertNotIsInstance(a, b) | not isinstance(a, b) | 验证a是否不是b的实例 |
方法 | 用于比较 |
---|---|
assertMultiLineEqual(a, b) | string |
assertSequenceEqual(a, b) | sequences |
assertListEqual(a, b) | list |
assertTupleEqual(a, b) | tuple |
assertSetEqual(a, b) | set |
assertDictEqual(a, b) | dict |
还有其他一些方法可用于执行更专门的检查,例如:
方法 | 检查 |
---|---|
assertAlmostEqual(a, b) | round(a-b, 7) == 0 |
assertNotAlmostEqual(a, b) | round(a-b, 7) != 0 |
assertGreater(a, b) | a > b |
assertGreaterEqual(a, b) | a >= b |
assertLess(a, b) | a < b |
assertLessEqual(a, b) | a <= b |
assertRegex(s, r) | r.search(s) |
assertNotRegex(s, r) | not r.search(s) # 正则是否匹配 |
assertCountEqual(a, b) | a和b具有相同编号的相同元素,而不管其顺序如何。 |
BeautifulReport
可生成HTML格式的测试报告。功能全、漂亮。
beautifulreport安装
pip3 install beautifulreport
BeautifulReport使用
# 导入unittest
import unittest
# 导入BeautifulReport
from BeautifulReport import BeautifulReport
# 实例化测试套件
suite01 = unittest.TestSuite()
# 设置用例模块的路径
case_path = "./cases"
# 加载目录下所有用例模块
discover = unittest.defaultTestLoader.discover(case_path, pattern="case*.py")
# 导入BeautifulReport后就不用TextTestRunner运行了
br = BeautifulReport(discover)
# 文件名filename,文件路径report_dir,文件描述description
br.report(filename='shop_test01.html', description="测试报告1.0", report_dir='report/')
执行完可查看报告