unittest框架
unittest(在Python中通常写作unittest,注意大小写)是Python自带的一个强大的单元测试框架。
Unittest框架四大组件:
1、TestCase 测试用例
2、TestFixture
3、TestSuite
4、TestRunner
二、unittest的四大组件
unittest中TestCase部分的规则:
1、用例类必须继承Unittest.TestCase,并且以test开头
2、每条用例,都必须以test开头
3、用例执行的顺序按照ASCII: 0-9 a-z A-Z 顺序来执行用例unittest也可以通过命令运行
命令执行TestShopnc类下的所有用例: python -m unittest 用例文件名.用例类
执行某一条用例: python -m unittest 用例文件名.用例类.用例名称
python -m unittest test_case.TestShop.test_loginimport unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03") if __name__ == '__main__': unittest.main()
def setUp(self) -> None: """ 前置操作, setUp执行每条用例前都会执行函数代码,有n条用例,则会执行n次 :return: """ # 加载项目,打开浏览器之类的操作 self.driver = webdriver.Chrome() self.driver.get("http://www.baidu.com") ele = self.driver.find_element(By.ID, "kw") self.driver.maximize_window() ele.send_keys("王勇") time.sleep(3) @classmethod def setUpClass(cls) -> None: """ 前置操作 setUpClass执行用例前会执行 ,总共只执行一次 :return: """ # 链接数据库,连接数据, 打开浏览器 pass def tearDown(self) -> None: """ 后置操作, tearDown执行完每条用例前都会执行代码,有n条用例,则会执行n次 :return: """ # self.driver.close() @classmethod def tearDownClass(cls) -> None: """ 后置操作 tearDownClass执行完所有用例之后会执行代码 ,总共只执行一次 :return: """ cls.driver.quit()
2.3 TestSuite 测试套件(测试用例集)
# 测试套件 用例集(把需要执行的用例汇总到一起) import unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03") if __name__ == '__main__': suite = unittest.TestSuite() suite.addTest(TestShop("test_login")) suite.addTest(TestShop("test_payment")) unittest.main(defaultTest="suite")
import unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03") if __name__ == '__main__': suite = unittest.TestSuite() case_list = [TestShop("test_login"), TestShop("test_payment")] suite.addTests(case_list) unittest.main(defaultTest="suite")
# 和 unittest.main() 基本上就是一样的 import unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03") if __name__ == '__main__': suite = unittest.TestSuite() # 用例加载器 # 用例 TestLoader() suite # loadTestsFromTestCase 加载某个用例类(继承 TestCase)下的所有用例 test_cases = unittest.TestLoader().loadTestsFromTestCase(TestShop) suite.addTests(test_cases) unittest.main(defaultTest="suite")
import unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03") if __name__ == '__main__': suite = unittest.TestSuite() # discover(文件夹, 以..开头的文件(默认是test*.py)) test_dir = "../unittest_study" unittest.defaultTestLoader.discover(test_dir) unittest.main(defaultTest="suite")
测试运行器 执行用例,把执行的结果输出给到用户
用例执行结果状态:
. 用例执行成功
E 用例有异常
F 用例执行失败(断言失败)企业测试报告的优化及定制 优化测试报告模板 通过js+html/html5
pytest+allure 生成更加美观的测试报告+优化定制(装饰器)
# test_case.py import time import unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03")import unittest from Code.unittest_study.test_case import TestShop # 加载用例 testcases = unittest.TestLoader().loadTestsFromTestCase(TestShop) # 执行用例,生成测试报告 with open("report/report.text", "w") as f: unittest.TextTestRunner(stream=f, verbosity=2).run(testcases) # 1 简介 2 详细一点; 生成的结果 report.text test_login (Code.unittest_study.test_case.TestShop) ... ok test_payment (Code.unittest_study.test_case.TestShop) ... ok test_shopping (Code.unittest_study.test_case.TestShop) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
HtmlTestRunner: https://www.cnblogs.com/wangyong123/articles/18431254
1. 官网下载HtmlTestRunner.py只能支持python2版本,支持Python3,需要做修改
2. python安装路径/Lib# test_case.py import time import unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03")import unittest import HTMLTestRunner from Code.unittest_study.test_case import TestShop # 加载用例 testcases = unittest.TestLoader().loadTestsFromTestCase(TestShop) # 执行用例,生成测试报告 with open("report/report.html", "wb+") as f: runner = HTMLTestRunner.HTMLTestRunner(stream=f, title="report.html", description="测试结果描述") runner.run(testcases)
# test_case.py import time import unittest class TestShop(unittest.TestCase): def test_login(self): print("测试 01") def test_shopping(self): print("测试 02") def test_payment(self): print("测试 03")import unittest from BeautifulReport import BeautifulReport from Code.unittest_study.test_case import TestShop # 加载用例 testcases = unittest.TestLoader().loadTestsFromTestCase(TestShop) # 执行用例,生成测试报告 with open("report/report_bf.html", "wb+") as f: BeautifulReport(testcases).report(description="测试结果描述", filename="report_bf", report_dir="./report")
@unittest.skip 强制跳过执行
@unittest.skipIf 符合条件,则跳过执行
@unittest.skipUnless 条件不成立,则跳过执行在类中加,那么可以直接跳过整个类
import time import unittest # @unittest.skip("整个用例类都不执行") # @unittest.skipIf(True, "整个用例类都不执行") @unittest.skipUnless(False, "整个用例类都不执行") class TestShopSkip(unittest.TestCase): def test_login(self): print("skip 测试 01") def test_shopping(self): print("skip 测试 02") def test_payment(self): print("skip 测试 03") class TestShop(unittest.TestCase): def test_login(self): print("测试 01") @unittest.skip("此用例暂时不启用") def test_shopping(self): print("测试 02") # @unittest.skipIf("条件1", "条件为真,则跳过") @unittest.skipIf(3 > 2, "条件为真,则跳过") def test_payment(self): print("测试 03") @unittest.skipUnless(2 > 3, "2>3不成立,则跳过执行") def test_select_goods(self): print("测试 04") if __name__ == '__main__': unittest.main()
assertIn(字符1,字符2) # 字符1是否包含在字符2 self.assertNotIn(字符1,字符2) # 字符1不包含包含在字符2 self.assertEqual(参数1,参数2,"断言失败的描述") # 参数1等于参数2 self.assertNotEqual(参数1,参数2,"断言失败的描述") # 参数不等于参数2 self.assertTrue(True) self.assertFalse(False)import time import unittest from selenium import webdriver from selenium.webdriver.common.by import By class TestShop(unittest.TestCase): @classmethod def setUpClass(cls) -> None: """ 前置操作 :return: """ # 打开浏览器 cls.driver = webdriver.Chrome() @unittest.skip("跳过登录") def test_login(self): """ 登录 :return: """ print("登录") def test_select_goods(self): """ 搜索商品 :return: """ self.driver.get("http://101.34.221.219:8010/") ele_select = self.driver.find_element(By.ID, "search-input") select_good = "手机" ele_select.send_keys(select_good) ele_button = self.driver.find_element(By.ID, "ai-topsearch") ele_button.click() time.sleep(3) # 断言:验证测试结果与预期结果是否一致 # 获取商品列表的标题 ele_content = self.driver.find_element(By.XPATH, "//ul/li[1]/div/a[1]/div[@class='am-padding-xs']/p") text = ele_content.text # 断言是否含有手机 self.assertIn(select_good, text, "商品未包含检索内容") def tearDown(self) -> None: self.driver.close() @classmethod def tearDownClass(cls) -> None: cls.driver.quit() if __name__ == '__main__': unittest.main()