UnitTest
unittest是Python单元测试框架,类似于JUnit框架。
unittest中有4个重要的概念:test fixture, test case, test suite, test runner
Testcase:
一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码 (run),以及测试后环境的还原(tearDown)。元测试(unit test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
Test suite:
多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。
Test runner:
是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
TestLoader:
是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
Test fixture:
对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖 TestCase的setUp()和tearDown()方法来实现。这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUp() 中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,然后关闭连接。注意tearDown的过程很重要,要为以后的 TestCase留下一个干净的环境。关于fixture,还有一个专门的库函数叫做fixtures,功能更加强大。
使用unittest编写python的单元测试代码,包括如下几个步骤:
1、编写一个python类,继承 unittest模块中的TestCase类,这就是一个测试类
2、在上面编写的测试类中定义测试方法(这个就是指的测试用例),每个方法的方法名要求以 test 打头,没有额外的参数。 在该测试方法中 调用被测试代码,校验测试结果,TestCase类中提供了很多标准的校验方法,如 最常见的assertEqual。
3、执行 unittest.main() ,该函数会负责运行测试,它会实例化所有TestCase的子类,并运行其中所有以test打头的方法。
用法
1.用import unittest导入unittest模块
2.定义一个继承自unittest.TestCase的测试用例类,如class xxx(unittest.TestCase):
3.定义setUp和tearDown,这两个方法与junit相同,即如果定义了则会在每个测试case执行前先执行setUp方法,执行完毕后执行tearDown方法。
4.定义测试用例,名字以test开头,unittest会自动将test开头的方法放入测试用例集中。
5.一个测试用例应该只测试一个方面,测试目的和测试内容应很明确。主要是调用assertEqual、assertRaises等断言方法判断程序执行结果和预期值是否相符。
6.调用unittest.main()启动测试
7.如果测试未通过,则会显示e,并给出具体的错误(此处为程序问题导致)。如果测试失败则显示为f,测试通过为.,如有多个testcase,则结果依次显示。
代码
import unittest
# class FirstTest(unittest.TestCase):
#
# def test_1(self):
# print("test_1")
#
# def test_2(self):
# print("test_2")
#
#
# if __name__ == '_main':
# unittest.main()
#
# class NumbersTest(unittest.TestCase):
#
# def test_even(self):
# for i in range(0, 6):
# with self.subTest(i=i):
# self.assertEqual(i % 2, 0)
# def setUpModule():
# createConnection()
#
# def tearDownModule():
# closeConnection()
#
# class Test(unittest.TestCase):
# @classmethod
# def setUpClass(cls):
# cls._connection = createExpensiveConnectionObject()
#
# @classmethod
# def tearDownClass(cls):
# cls._connection.destroy()
from selenium import webdriver
import time
class TestUnit1(unittest.TestCase):
# 获取浏览器的驱动
def setUp(self):
# 1、self 就是类的引用/实例
# 2、全局变量的定义:self.变量名
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.url = "https://www.baidu.com"
self.driver.get(self.url)
time.sleep(3)
# 在百度中搜索信息
# 测试用例的命名: test_
def test_search1(self):
self.driver.find_element("id", "kw").send_keys("顾一野")
self.driver.find_element("id", "su").click()
time.sleep(6)
def test_search2(self):
self.driver.find_element("id", "kw").send_keys("account")
self.driver.find_element("id", "su").click()
time.sleep(6)
# 关闭浏览器
def tearDowm(self):
self.driver.quit()
# 一个入口
if __name__ == "__main__":
unittest.main()
import unittest
class TestCaseDemo(unittest.TestCase):
def testassertdemo(self):
self.assertIn(1, [1, 2, 3])
self.assertNotIn(1, [2, 3, 4])
self.assertEqual('1', '1')
self.assertNotEqual(1, 2)
self.assertTrue(2 == 2)
def testassertdemo_1(self):
self.assertDictEqual({"code": 1}, {"code": 1})
self.assertListEqual([1, 2], [1, 2])
self.assertMultiLineEqual("name", "name")
def testassertdemo_2(self):
self.assertGreater(2, 0)
self.assertGreaterEqual(2, 0)
self.assertNotRegex("1", "122") # 正则是否匹配
self.assertCountEqual("12", "12")
# 1、第一种方法,一条一条case加载用例
def suite():
# 创建一个测试套件
suite = unittest.TestSuite()
# 将测试用例加载到测试套件中
case1 = TestCaseDemo("testassertdemo")
suite.addTest(case1)
case2 = TestCaseDemo("testassertdemo_1")
suite.addTest(case2)
case3 = TestCaseDemo("testassertdemo_2")
suite.addTest(case3)
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
unittest模块常用方法
assertEqual(a, b) a == b
assertNotEqual(a, b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a, b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)
skip方法
有时候,测试用例很多,有些需要执行,有些不想执行,那就需要跳过一些测试用例,这时候就需要用到skip,skip用法:
无条件跳过,unittest.skip(“xxx”)
条件为True跳过,unittest.skipIf(1 < 2, ‘xxx’)
条件为False跳过,unittest.skipUnless(1 > 2, ‘xxx’)
执行失败不计入case总数中,unittest.expectedFailure
代码
import unittest
class Mytest1(unittest.TestCase):
def setUp(self) -> None:
print("===== setUp =====")
def tearDown(self) -> None:
print("===== tearDown =====")
@classmethod
def setUpClass(cls) -> None:
print("===== setUpClass =====")
@classmethod
def tearDownClass(cls) -> None:
print("===== tearDownClass =====")
@unittest.skip("直接跳过")
def test_1(self):
print("test_1")
@unittest.skipIf(1<2,"条件为True则跳过")
def test_2(self):
print("test_2")
@unittest.skipUnless(1<2,"条件为False则跳过")
def test_3(self):
print("test_3")
@unittest.expectedFailure
def test_4(self):
print("test_4")
self.assertEqual(4,5)
if __name__ == "__main__":
unittest.main()
生成HTML测试报告
from unittest import TestSuite
from HtmlTestRunner import HTMLTestRunner
class Mytest1(unittest.TestCase):
def test_1(self):
print("test_1")
def test_2(self):
print("test_2")
def test_3(self):
print("test_3")
def test_4(self):
print("test_4")
if __name__ == "__main__":
# 创建一个测试套件 suite
suite = TestSuite()
# 添加单个测试用例
suite.addTest(Mytest1("test_3"))
suite.addTest(Mytest1("test_1"))
suite.addTest(Mytest1("test_2"))
# 执行测试并输出html报告,output输出到xx目录下
runner = HTMLTestRunner(output="result")
runner.run(suite)
ddt模块
有时我们需要对大量的数据进行同一种逻辑函数测试,这时候可以用到ddt模块。
ddt,是一种 数据驱动测试 思想,数据和用例进行分离,通过外部数据去生成测试用例,可以快速的对大量数据和不同情况进行测试。
首先我们需要在python中安装ddt模块:pip install ddt。
数据引入的方式主要有以下几种:
@data装饰器的方式
json文件
yaml文件
其他
data装饰器
import unittest
from ddt import ddt, data, unpack
# 先定义@ddt,用于表示要使用ddt了
@ddt
class Mytest1(unittest.TestCase):
# data用于设定参数
@data("a", "b", "c")
def test_1(self, text):
self.assertEqual("a", text)
if __name__ == "__main__":
unittest.main()
json文件
先编写json文件
[
{
"name": "test",
"age": 18
},
{
"name": "test1",
"age": 20
}
]
import unittest
from ddt import ddt, file_data
@ddt
class Mytest1(unittest.TestCase):
@file_data("/test.json")
def test_1(self, **text):
print(text)
print(type(text))
if __name__ == "__main__":
unittest.main()
yaml文件
先编写yaml文件
# "-"表示一个列表
-
name: 'test1'
age: 18
-
name: 'test2'
age: 20
import unittest
from ddt import ddt, file_data
@ddt
class Mytest1(unittest.TestCase):
@file_data("/Users/tangliqi/Desktop/个人文档/json文件/test.yaml")
def test_1(self, **text):
print(text)
print(type(text))
if __name__ == "__main__":
unittest.main()
版权归原作者 你可以自己看 所有, 如有侵权,请联系我们删除。