目录
3、软件测试/自动化测试【全家桶装】学习中的工具、安装包、插件....
4、有了安装包和学习资料,没有项目实战怎么办,我这里都已经准备好了往下看
unittest
是Python自带的一个单元测试框架,unittest
又被称为PyUnit
,是由Java的JUnit
衍生而来,基本结构是类似的。对于单元测试,需要设置预先条件,对比预期结果和实际结果。
由于unittest
是Python自带的标准模块,所以不需要单独再去安装。引入包import unittest
即可使用。
test fixture
:fixture
表示test case
运行前需要做的准备工作以及结束后的清理工作。比如,创建临时/代理数据库、目录或启动一个浏览器进程。test case
:test case
是单元测试中的最小个体,通常是使用assert方法(断言)检查动作和输入的响应。unittest
提供了一个基础类TestCase
,一般是基于TestCase类进行扩充,来创建test case
测试用例。test suite
:test suite
(套件)是test case
的合集,通常用test suite
将test case
按需求汇总后,统一执行。(批量执行用例)test runner
:test runner
是一个执行器,用来执行测试用例或者套件。并将测试结果保存到TextTestResult
实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。并提供图形界面、文本界面或者返回一个值展示测试结果。所有测试用例类都要继承TestCase
基本类。
# 1. 导入unittest import unittest # 2. 定义一个测试类 class Test_demo(unittest.TestCase):
test fixture
常用的四个方法(1)基于函数级别的方法
setup()
:每个测试方法运行前执行一次。测试类中有多少测试用例执行多少次。teardown()
:每个测试方法运行完后执行一次。测试类中有多少测试用例执行多少次。(2)基于类级别的方法
setUpClass()
:在测试类执行前执行一次,需要@classmethod
装饰器修饰。tearDownClass()
:在测试类执行完后执行一次,需要@classmethod
装饰器修饰。unittest
识别的。(规范,必须)unittest
中TestCase
类来编写用例。self
参数,用来单独运行或则组合运行用例。unittest.main()
:将一个单元测试模块变为可直接运行的测试脚本,main()
方法是使用TestLoader
类来搜索所有包含在该模块中以test命名开头的测试方法,并自动执行他们。
执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z
。
- """
- 1.学习目标
- 掌握unittest框架下测试用例编写方法
- 2.操作步骤
- 2.1 导入unittest
- 2.2 创建测试类
- 测试类名称需要Test开头
- 继承unittest中的TestCase基本类
- class Test_demo(unittest.TestCase):
- 2.3 编写test fixture
- setUp()--前置函数
- tearDown()--后置函数
- setUpClass()--+@classmethod
- tearDownClass()+@classmethod
- 2.4 编写test case
- 测试方法名称均以test开头
- 测试用例执行顺序:按照测试用例名称ASCII字符集编码排序。
- 所以我们在执行测试类中的测试方法的时候,要注意测试方法的执行顺序。
- 3.需求
- 编写简单的测试类
- """
- # 1 导入unittest
- import unittest
-
-
- # 2 创建测试类
- class Test_demo(unittest.TestCase):
- # 3 编写test fixture
- # setUp我们也称之为前置函数
- def setUp(self) -> None:
- print("setUp在每个测试用例执行前先执行。")
-
- # setUp我们也称之为后置函数
- def tearDown(self) -> None:
- print("tearDown在每个测试用例执行后执行。")
-
- @classmethod
- # cls等同于self,用于函数和类方便区分。
- def setUpClass(cls) -> None:
- print("setUpClass在测试类执行前先执行。")
-
- @classmethod
- def tearDownClass(cls) -> None:
- print("tearDownClass在测试类执行后执行。")
-
- # 4 编写test case
- # 每个测试方法均以test开头,否则是不被unittest识别的。
- def test_case_03(self):
- """测试用例3,这里是测试用例的备注"""
- # 测试方法中,将多行注释写在第一行,就是该方法的备注。
- print("执行测试用例3")
-
- def test_case_02(self):
- """测试用例2"""
- print("执行测试用例2")
-
- def test_case_01(self):
- """测试用例1"""
- print("执行测试用例1")
-
-
- if __name__ == '__main__':
- # 执行当前测试类中,以test开头的所有测试用例
- unittest.main()
-
- """
- 输出结果:
- setUpClass在测试类执行前先执行。
- setUp在每个测试用例执行前先执行。
- 执行测试用例1
- tearDown在每个测试用例执行后执行。
- setUp在每个测试用例执行前先执行。
- 执行测试用例2
- tearDown在每个测试用例执行后执行。
- setUp在每个测试用例执行前先执行。
- 执行测试用例3
- tearDown在每个测试用例执行后执行。
- tearDownClass在测试类执行后执行。
- """
提示:test fixture
的四个方法,用到哪个写哪个就好,不用全部都写。
测试执行完成后,会打印如下信息
- # 运行了3个测试用例,执行的时间
- Ran 3 tests in 0.008s
-
- # 执行结果
- OK
执行结果有如下三种
在执行测试用例的过程中,最终用例是否执行通过,是通过判断测试得到的实际结果和预期结果是否相等决定的,这时会用到断言方法。
本着没有消息就是最好的消息的原则,如果断言成功不采取任何措施(不输入任何日志),否则就会触发AssertionError
(断言错误)的异常。
断言方法名称 | 使用参数 | 验证 |
---|---|---|
assertEqual()(常用) | a,b,[msg='测试失败时打印的信息'] | 断言a和b是否相等,相等则测试用例通过 |
assertNotEqual() | a,b,[msg='测试失败时打印的信息'] | 断言a和b是否相等,不相等则测试用例通过。 |
assertTrue()(常用) | x,[msg='测试失败时打印的信息'] | 断言x是否True,是True则测试用例通过 |
assertFalse() | x,[msg='测试失败时打印的信息'] | 断言x是否false,是false则测试用例通过 |
assertIs() | a,b,[msg='测试失败时打印的信息'] | 断言a是否是b,是则测试用例通过 |
assertNotIs() | a,b,[msg='测试失败时打印的信息'] | 断言a是否是b,不是则测试用例通过 |
assertIsNone() | x,[msg='测试失败时打印的信息'] | 断言x是否None,是None则测试用例通过 |
assertIsNotNone() | x,[msg='测试失败时打印的信息'] | 断言x是否None,不是None则测试用例通过。 |
assertIn() | a,b,[msg='测试失败时打印的信息'] | 断言a是否在b中,在b中则测试用例通过 |
assertNotIn() | a,b,[msg='测试失败时打印的信息'] | 断言a是否在b中,不在b中则测试用例通过 |
assertIsInstance() | a,b,[msg='测试失败时打印的信息'] | 断言a是否是b的一个实例,是则测试用例通过。 |
assertNotIsInstance() | a,b,[msg='测试失败时打印的信息'] | 断言a是否是b的一个实例,不是则测试用例通过。 |
提示:如果a和b断言失败,则输出msg中定义的信息,如果没有定义msg,则输出系统异常。
- """
- 1.学习目标
- 必须掌握unittest中断言使用
- 2.语法
- 2.1 编写位置
- 在测试用例中去编写,先执行测试用例,最后一行断言。
- 2.2 使用的断言方法
- 注意:前边a是预期,后边b是测试实际的值
- (1)assertEqual(a,b,msg)
- 断言a和b是否相等,如果相等,断言成功,否则断言失败
- (2)assertTrue(x,msg)
- 断言条件x是否为True,如果是,断言成功,否则断言失败
- (3)其他断言用法类似。
- 2.3 判定断言结果
- 断言成功,控制台没有任何提示
- 断言失败,控制台AssertionError关键字会出现
- 3.需求
- 编写一个有断言的测试类
- """
- # 1 导入unittest
- import unittest
-
-
- # 2 创建测试类
- class Test_demo(unittest.TestCase):
-
- # 3 编写test case
- def test_case_03(self):
- """测试用例3"""
- print("执行测试用例3")
- # 用例步骤执行完成后做断言
- # assertEqual断言a和b是否相等
- self.assertEqual(2, 1 + 1, msg="断言成功")
-
- """
- 执行结果:
- 断言成功,控制台没有任何提示
-
- 下面是总测试结果的日志:
- 执行测试用例3
- # 在0.005秒内进行1次测试
- Ran 1 test in 0.005s
-
- # 测试用例全部通过
- OK
- """
-
- def test_case_02(self):
- """测试用例2"""
- print("执行测试用例2")
- # assertEqual断言a和b是否相等
- self.assertEqual(3, 1 + 1, msg="断言失败")
-
- """
- 执行结果:
-
- 执行测试用例2
- 断言失败
- 3 != 2
- Expected(预期) :2
- Actual(实际) :3
-
- 下面会有报错信息(主要内容):
- AssertionError: 2 != 3 : 断言失败
-
- # 在0.008秒内进行1次测试
- Ran 1 test in 0.008s
-
- # 失败一个测试用例
- FAILED (failures=1)
-
- # 断言失败
- Assertion failed
- """
-
- def test_case_01(self):
- """测试用例1"""
- print("执行测试用例1")
- # 断言条件x是否为True
- self.assertTrue(1 > 2, msg="条件不成立,断言失败")
-
- # 4 编写普通方法
- if __name__ == '__main__':
- # 执行当前测试类中,以test开头的测试用例
- unittest.main()
当测试用例写完后,有些模块有改动时候,会影响到部分用例的执行,这个时候我们希望暂时跳过这些用例。或者前面某个功能运行失败了,后面的几个用例是依赖于这个功能的用例,如果第一步就失败了,后面的用例也就没必要去执行了,为了节省用例执行时间,可选择直接跳过测试。
当执行有想要跳过的测试,我们可以通过skip
、skipIf
、skipUnless
装饰器跳过某个测试方法或者测试类。
@unittest.skip(reason)
:skip(reason)
装饰器,无条件跳过装饰的测试,并说明跳过测试的原因。@unittest.skipIf(reason)
:skipIf(condition,reason)
装饰器,条件为真时,跳过装饰的测试,并说明跳过测试的原因。@unittest.skipUnless(reason)
:skipUnless(condition,reason)
装饰器,条件为假时,跳过装饰的测试,并说明跳过测试的原因。@unittest.expectedFailure
:- """
- 1.学习目标
- 了解unittest中跳过测试方法使用
- 2.语法
- 2.1 放置在需要跳过的测试用例之前
- @跳过测试方法
- 测试用例
- 2.2 分类
- @unittest.skip(跳过原因):表示无条件跳过执行
- @unittest.skipIf(判断条件,跳过原因): 当判断条件为真时,跳过测试
- @unittest.skipUnless(判断条件,跳过原因):当判断条件为假时,跳过测试
- @unittest.expectedFailure: 直接将用例标记为失败
- 3.需求
- 编写测试类,使用跳过测试
- """
- # 1 导入unittest
- import unittest
-
-
- # 2 创建测试类
- class Test_demo(unittest.TestCase):
-
- # 3 编写test case
- # 第一条测试用例正常执行
- def test_case_01(self):
- """测试用例1"""
- print("执行测试用例1")
-
- # 添加skip,不执行测试
- @unittest.skip("无条件跳过")
- def test_case_02(self):
- """测试用例2"""
- print("执行测试用例2")
-
- # 添加skipif,条件为真跳过测试
- @unittest.skipIf(True, "条件为真,跳过测试")
- def test_case_03(self):
- """测试用例3"""
- print("执行测试用例3")
-
- # 添加skipIf,条件为假执行测试
- @unittest.skipIf(2 > 3, "条件为假,执行用例")
- def test_case_04(self):
- """测试用例4"""
- print("执行测试用例4")
-
- # 添加skipUnless,条件为假不执行测试
- @unittest.skipUnless(False, "条件为假,跳过测试")
- def test_case_05(self):
- """测试用例5"""
- print("执行测试用例5")
-
- # 添加skipUnless,条件为真执行测试
- @unittest.skipUnless(True, "条件为真,执行用例")
- def test_case_06(self):
- """测试用例6"""
- print("执行测试用例6")
-
- # 添加expectedFailure,直接将用例标记为失败
- @unittest.expectedFailure
- def test_case_07(self):
- """测试用例7"""
- print("执行测试用例7")
-
- def test_case_08(self):
- """测试用例8"""
- print("执行测试用例8")
-
- if __name__ == '__main__':
- # 执行当前测试类中,以test开头的测试用例
- unittest.main()
执行结果:
用TestCase.skipTest()
方法跳过某个测试方法(了解)。
示例:
- # 1 导入unittest
- import unittest
-
- # 2 创建测试类
- class TestDmeo(unittest.TestCase):
-
- # 3 编写test case
- def test_case_01(self):
- """测试用例1"""
- print("执行测试用例1")
-
- # TestCase.skipTest()方法
- def test_case_02(self):
- """测试用例2"""
- # 跳过测试方法
- self.skipTest('跳过用例test_case2')
- print("执行测试用例2")
-
- if __name__ == '__main__':
- # 执行当前测试类中,以test开头的测试用例
- unittest.main()
结果:
在我们实际工作,使用unittest
框架会有两个问题:
要解决上面两个问题,我们就要用到测试套件TestSuite
。
(1)入门用法
用法:
unittest.TestSuite()
:创建测试套件。addTest()
和addTests()
方法是将测试用例添加到测试套件中。unittest.TextTextRunner()
:通过该类下面的run()
方法来运行suite所组装的测试用例,suite测试套件为run()
方法参数。例如:将test_Demo1
模块下的TestDmeo
类下的test_case_01
测试用例添加到测试套件中。
- # 1.创建测试套件
- suite = unittest.TestSuite()
-
- # 2.向测试套件中添加测试用例
- # 模块名.测试类名('测试用例名')
- suite.addTest(test_Demo.TestDmeo('test_case_01'))
-
- # 3.执行测试套件中的用例
- runner = unittest.TextTestRunner()
- runner.run(suite)
示例:
- # 1 导入unittest
- import unittest
-
- # 2 创建测试类
- class TestDmeo(unittest.TestCase):
-
- # 3 编写test case
- def test_case_01(self):
- """测试用例1"""
- print("执行测试用例1")
-
- def test_case_02(self):
- """测试用例2"""
- print("执行测试用例2")
-
- def test_case_03(self):
- """测试用例3"""
- print("执行测试用例3")
-
-
- if __name__ == '__main__':
- # 执行当前测试类中,以test开头的测试用例
- # unittest.main()
-
- # 1. 创建测试套件
- suite = unittest.TestSuite()
- # 2. 向测试套件中添加测试用例
- # 当前模块中的测试用例,可省略模块名(文件名)
- suite.addTest(TestDmeo('test_case_02'))
- suite.addTest(TestDmeo('test_case_03'))
- suite.addTest(TestDmeo('test_case_01'))
- # 3. 执行测试套件中的用例
- runner = unittest.TextTestRunner()
- runner.run(suite)
提示:向测试套件中添加测试用例的顺序,就是测试用例执行的顺序。(此时解决了第一个问题)
注意:
使用PyCharm执行上边代码,会按顺序执行全部测试用例,这是PyCharm问题。
使用命令行直接执行该Python文件,没有问题。
(2)根据不同的条件加载测试用例(了解)
提示:这种方式很少用,了解一下即可。都用下面(3)的方式。unittest.TestLoader()
:根据不同的条件加载测试用例,其中有几个方法:
unittest.TestLoader().loadTestsFromName(测试用例名)
unittest.TestLoader().loadTestsFromNames(测试用例名的列表)
unittest.TestLoader().loadTestsFromTestCase(测试类名)
unittest.TestLoader().loadTestsFromModule(模块名)
unittest.TestLoader().discover()
例如:将``test_demo2模块下的
TestDmeo类下的
test_case_01`测试用例添加到测试套件中。
测试用例名格式:文件名+类名+方法名,一级一级的。
示例:
- # 1 导入unittest
- import unittest
-
- # 2 创建测试类
- class TestDmeo(unittest.TestCase):
-
- # 3 编写test case
- def test_case_0001(self):
- """测试用例0001"""
- print("执行测试用例0001")
-
- def test_case_0002(self):
- """测试用例0002"""
- print("执行测试用例0002")
-
- def test_case_0003(self):
- """测试用例0003"""
- print("执行测试用例0003")
-
-
- if __name__ == '__main__':
- # 1. 创建测试套件
- suite = unittest.TestSuite()
-
- # 2. 向测试套件中添加测试用例
- """
- # 2.1 loadTestsFromName
- # 提示:
- name参数是传入文件名,字符串格式
- 格式:模块名.测试类名.测试用例名
- """
- # suite_1 = unittest.TestLoader().loadTestsFromName('test_demo2.TestDmeo.test_case_01')
-
- """
- # 2.2 loadTestsFromNames
- 参数是一个列表,列表中的元素格式同上
- """
- # suite_1 = unittest.TestLoader().loadTestsFromNames(
- # ['test_demo2.TestDmeo.test_case_01','test_demo2.TestDmeo.test_case_02'])
-
- """
- # 2.3 loadTestsFromTestCase
- 参数一个测试类名
- 当前模块直接传如测试类名称即可
- """
- suite_1 = unittest.TestLoader().loadTestsFromTestCase(TestDmeo)
-
- # 加入套件
- suite.addTest(suite_1)
- # 3. 执行测试套件中的用例
- runner = unittest.TextTestRunner()
- runner.run(suite)
(3)常用方式(推荐)unittest.defaultTestLoader()
:通过该类下面的discover()
方法可自动根据测试目录test_dir
匹配查找测试用例文件,如test*.py
,并将查找到的测试用例组装到测试套件中。
简单示例:discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
测试套件示例:
test_case
包用来存放测试用例。test_demo1
和test_demo2
两个测试用例类文件放入test_case
包中。run_case.py
文件执行多个测试用例。说明:test_demo1
和test_demo2
两个文件,就是上面(1)(2)的示例。
下面是run_case.py
文件内容,需求是同时执行test_demo1
和test_demo2
两个文件中的测试用例。
- """
- 1.学习目标
- run_case.py必须会写
- 2.操作步骤
- 2.1 明确测试用例存放路径
- 2.2 将要执行的用例添加到测试套件中
- 2.3 执行测试套件中的用例
- 3.注意事项
- 1.run_case.py文件需要放置在项目根目录下
- 2.所有测试用例都写在test_caset文件夹中
- 3.编写用例的py文件需要以test开头
- """
- # 1.导入unittest
- import unittest
-
- # 2.获取测试用例存放路径---测试用例存放文件夹
- case_path = "./test_case"
-
- # 3.添加用例到测试套件中
- """
- # 如果只添加一个文件,pattern就直接填写文件名
- start_dir, 指定case目录
- pattern='test*.py', 匹配文件规则,# 选择文件夹中的写test_开头的py文件
- """
- discover = unittest.defaultTestLoader.discover(case_path, pattern="test*.py")
-
- # 4.执行测试套件中的用例
- runner = unittest.TextTestRunner()
- runner.run(discover)
最后我这里给你们分享一下我所积累和真理的文档和学习资料有需要是领取就可以了
这个大纲涵盖了目前市面上企业百分之99的技术,这个大纲很详细的写了你该学习什么内容,企业会用到什么内容。总共十个专题足够你学习
这里我准备了对应上面的每个知识点的学习资料、可以自学神器,已经项目练手。
最后送上一句话:
世界的模样取决于你凝视它的目光,自己的价值取决于你的追求和心态,一切美好的愿望,不在等待中拥有,而是在奋斗中争取。
如果我的博客对你有帮助、如果你喜欢我的文章内容,请 “点赞” “评论” “收藏” 一键三连哦