一、unittest框架

unittest属于python内置的单元测试框架。

二、unittest框架的核心概念

test case:指测试用例。unittest中提供了一个基本类TestCase,可以用来创建新的测试用例;

​test fixure:测试夹具,用于测试用例环境的搭建和销毁。即用例测试前准备环境的搭建(SetUp前置条件),测试后环境的还原(TearDown后置条件),比如测试前需要登录获取token等就是测试用例需要的环境,运行完后执行下一个用例前需要还原环境,以免影响下一条用例的测试结果。(以及数据库的连接和断开等)

test suite:测试套件,用来把需要一起执行的测试用例集中放到一块执行,相当于一个篮子。我们可以使用TestLoader来加载测试用例到测试套件中。

test runner:用来执行测试用例的,并返回测试用例的执行结果。它还可以用图形或者文本接口,把返回的测试结果更形象的展现出来,如:HTMLTestRunner。

三、unittest断言

python中的assert断言,使用方法比较简单,即assert(表达式, 提示信息)

而unittest框架中也提供了一个自带的断言方式,主要有以下几种:

方法 检查
assertEqual(a, b,msg) 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)

四、unittest核心概念详解

1、TestCase测试用例:

使用unittest编写用例,必须遵守以下规则:

(1)测试文件必须先import unittest

(2)测试类必须继承unittest.TestCase

(3)测试方法必须以“test”开头,且执行顺序会按照方法名的ASCII值排序,所以,写多个有关联的测试用例的时候请一定注意方法名称。

2、TestFixture测试固件:

unittest的测试固件有两种:

(1)setUp()tearDown():在每个测试方法执行前后,均会执行该方法。

(2)setUpClass()tearDownClass():整个测试类中的用例执行前后,会执行此方法。

3、TestSuite测试套件

(1)unittest.TestSuite()

  • addTest():添加单个测试用例方法。
  • addTest([..]):添加多个测试用例方法,方法名存在一个列表,用逗号隔开。
(2)unittest.TestLoader()

  • loadTestsFromTestCase(测试类名):添加一个测试类。
  • loadTestsFromModule(模块名):添加一个模块。
  • discover(测试用例的所在目录):指定目录去加载,会自动寻找这个目录下所有符合命名规则的测试用例。

if __name__ == "__main__":
# verbosity参数可以控制输出结果的详细程度,默认为1.若为0,则简化输出;若为2,则详细输出。
# unittest.main():搜索该模块下所有以test开头的测试用例方法,并自动执行
# unittest.main(verbosity=1)
suite = unittest.TestSuite() # 方式1:添加单个或多个测试用例
# case1 = MyTest('test_register_success')
# case2 = MyTest('test_pwd_not_cpwd')
# case3 = MyTest('test_username_lt6')
# suite.addTest(case3)
# suite.addTests([case1, case2]) # 方式2:添加一个测试类
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromTestCase(test_register.TestRegister)) # 方式3:添加一个模块(不过试了不可以,按照提示也不行。。。)
# loader = unittest.TestLoader()
# suite.addTests(loader.loadTestsFromModule(test_register)) # 方式4:指定测试用例所在的路径,进行加载(默认是寻找目录下test*.py文件)
# pattern正则表达式匹配测试用例的文件名
loader = unittest.TestLoader()
suite.addTest(loader.discover(r"E:", pattern="test_*.py"))
 
4、TestRunner执行测试
test runner是用来执行测试用例的,并且可以生成相应的测试报告。测试报告有两种展示形式,一种是text文本,一种是html格式(前提:安装HTMLTestRunner模块)。

runner = HTMLTestRunner.HTMLTestRunner(
stream=open("report.html", 'wb'),
description="注册接口测试详情",
title="注册接口测试报告"
)
# 使用启动器去执行测试套件里的用例
runner.run(suite)

相关参数说明:

  • stream:指定输出的方式
  • tester:报告中要显示的测试人员的名字
  • description:报告中要显示的面熟信息
  • title:测试报告的标题
  • verbosity :表示测试报告信息的详细程度,一共三个值,默认是2
    • 0 (静默模式):你只能获得总的测试用例数和总的结果,如:总共100个 失败10 成功90
    • 1 (默认模式):类似静默模式,只是在每个成功的用例前面有个. 每个失败的用例前面有个F
    • 2 (详细模式):测试结果会显示每个测试用例的所有相关的信息
 
五、@unittest.skip():装饰器,用来暂时屏蔽特定的测试用例。

@unittest.skip(reason):无条件跳过装饰的测试,并说明跳过测试的原因。

@unittest.skipIf(reason):条件为真时,跳过装饰的测试,并说明跳过测试的原因。

@unittest.skipUnless(reason):条件为假时,跳过装饰的测试,并说明跳过测试的原因。

@unittest.expectedFailure():标记该测试预期为失败 ,如果该测试方法运行失败,则该测试不算做失败。

 
实践:
# get_unittest.py
import unittest
from Test1 import Register
import HTMLTestRunner
import test_register # 继承unittest.TestCase
class MyTest(unittest.TestCase):

  a = 10
def setUp(self):
self.Reg = Register()
# print("测试开始") def tearDown(self):
pass
# print("测试完成") @classmethod
def setUpClass(cls):
print("注册接口模块 -- 测试开始") @classmethod
def tearDownClass(cls):
print("注册接口模块 -- 测试完成") # 测试方法必须以"test"开头
  @unittest.skip("跳过该用例")
def test_register_success(self):
'''注册成功'''
data = ("hahaha15", "Bc123456", "Bc123456")
expected = {"error_code": 0, "msg": "注册成功!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result)

  @unittest.skipIf(3>2, "跳过该用例")
def test_pwd_not_cpwd(self):
'''
注册失败,两次输入密码不一样
data: 测试数据
expected: 预期结果
result: 实际结果
''' data = ("hahaha14", "Bc123456", "Bc12345")
expected = {"error_code": 3004, "msg": "两次输入密码不一致!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) @unittest.skipUnless(3<2, "跳过该用例")
def test_username_lt6(self):
'''注册失败,用户名长度小于6位'''
data = ("haha", "Bc123456", "Bc123456")
expected = {"error_code": 3002, "msg": "用户名长度为6-10位!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) if __name__ == "__main__":
# unittest.main():搜索该模块下所有以test开头的测试用例方法,并自动执行
# unittest.main(verbosity=1)
suite = unittest.TestSuite() # 方式1:添加单个或多个测试用例
# case1 = MyTest('test_register_success')
# case2 = MyTest('test_pwd_not_cpwd')
# case3 = MyTest('test_username_lt6')
# suite.addTest(case3)
# suite.addTests([case1, case2]) # 方式2:添加一个测试类
# loader = unittest.TestLoader()
# suite.addTest(loader.loadTestsFromTestCase(test_register.TestRegister)) # 方式3:添加一个模块(不过试了不可以,按照提示也不行。。。)
# loader = unittest.TestLoader()
# suite.addTests(loader.loadTestsFromModule(test_register)) # 方式4:指定测试用例所在的路径,进行加载
# pattern匹配了加载的测试用例文件
loader = unittest.TestLoader()
suite.addTest(loader.discover(r"E:", pattern="test_*.py"))
runner = HTMLTestRunner.HTMLTestRunner(
stream=open("report.html", 'wb'),
description="注册接口测试详情",
title="注册接口测试报告"
)
# 使用启动器去执行测试套件里的用例
runner.run(suite)
# test_register.py

import unittest
from Test1 import Register class TestRegister(unittest.TestCase): def setUp(self):
self.Reg = Register()
# print("测试开始") def tearDown(self):
pass
# print("测试完成") @classmethod
def setUpClass(cls):
print("注册接口模块 -- 测试开始") @classmethod
def tearDownClass(cls):
print("注册接口模块 -- 测试完成") # 测试方法必须以"test"开头
def test_register_success(self):
'''注册成功'''
data = ("hahaha15", "Bc123456", "Bc123456")
expected = {"error_code": 0, "msg": "注册成功!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) def test_pwd_not_cpwd(self):
'''
注册失败,两次输入密码不一样
data: 测试数据
expected: 预期结果
result: 实际结果
''' data = ("hahaha14", "Bc123456", "Bc12345")
expected = {"error_code": 3004, "msg": "两次输入密码不一致!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result) def test_username_lt6(self):
'''注册失败,用户名长度小于6位'''
data = ("haha", "Bc123456", "Bc123456")
expected = {"error_code": 3002, "msg": "用户名长度为6-10位!"}
result = self.Reg.register(*data)
self.assertEqual(expected, result)
# Test1.py

import requests
import json class Register(): def register(self, username, pwd, cpwd):
url = "http://api.nnzhp.cn/api/user/user_reg"
method = "post"
form_body = {
"username": username,
"pwd": pwd,
"cpwd": cpwd
}
response = requests.request(url=url, method=method, data=form_body).text
return json.loads(response) if __name__ == "__main__":
reg = Register()
data = ("hahaha1", "Bc123456", "Bc123456")
expected = {"error_code": 0, "msg": "注册成功!"}
result = reg.register(*data)
print(result)
print(type(result))

参考:https://www.cnblogs.com/miki-peng/p/12501341.html

python之unittest框架使用的更多相关文章

  1. selenium + python自动化测试unittest框架学习(二)

    1.unittest单元测试框架文件结构 unittest是python单元测试框架之一,unittest测试框架的主要文件结构: File >report >all_case.py &g ...

  2. selenium + python自动化测试unittest框架学习(一)selenium原理及应用

    unittest框架的学习得益于虫师的<selenium+python自动化实践>这一书,该书讲得很详细,大家可以去看下,我也只学到一点点用于工作中,闲暇时记录下自己所学才能更加印象深刻. ...

  3. python之unittest框架实现接口测试实例

    python之unittest框架实现接口测试实例 接口测试的方法有很多种,具体到工具有postman,jmeter,fiddler等,但是工具的局限性是测试数据的组织较差,接口的返回工具的判断有限, ...

  4. python selenium --unittest 框架

    转自:http://www.cnblogs.com/fnng/p/3300788.html 学习unittest 很好的一个切入点就是从selenium IDE 录制导出脚本.相信不少新手学习sele ...

  5. selenium自动化测试、Python单元测试unittest框架以及测试报告和日志输出

    部分内容来自:https://www.cnblogs.com/klb561/p/8858122.html 一.基础介绍 核心概念:test case, testsuite, TestLoder,Tex ...

  6. python的unittest框架中的assert断言

    unittest框架自带断言,如果想用assert断言,一定要引入unittest.TestCase框架才行,不然不会自动识别assert断言

  7. python单元测试unittest框架

    环境:PyCharm 2016.2 + python 3.5 待测试的类:(Widget.py) 测试类:(Auto.py) 测试结果: 总结:1.第一步:先写好测试类2.第二步:导入unittest ...

  8. Selenium with Python 010 - unittest 框架(又称PyUnit 框架)

    unittest进行python代码单元测试 calculator.py--被测试类 #!/usr/bin/env python # -*- coding: utf-8 -*- # 将要被测试的类 c ...

  9. Python+Selenium+Unittest框架使用——Selenium——定位元素(二)

    1.定位元素(id.name.class.link.partial link) (1)find_element_by_id() 用百度定位测试,用firebug查看定位元素 ,输入框的id为“kw”, ...

随机推荐

  1. C#LeetCode刷题之#118-杨辉三角(Pascal‘s Triangle)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3688 访问. 给定一个非负整数 numRows,生成杨辉三角的前 ...

  2. 从0写一个Golang日志处理包

    WHY 日志概述 日志几乎是每个实际的软件项目从开发到最后实际运行过程中都必不可少的东西.它对于查看代码运行流程,记录发生的事情等方面都是很重要的. 一个好的日志系统应当能准确地记录需要记录的信息,同 ...

  3. 使用 .NET Core 3.x 构建 RESTFUL Api (续)

    关于Entity Model vs 面向外部的Model Entity Framework Core 使用 Entity Model 用来表示数据库里面的记录. 面向外部的Model 则表示要传输的东 ...

  4. next()与nextLine()的区别

    abc def ghij kl mno pqr st uvw xyz 你用next(),第一次取的是abc,第二次取的是def,第三次取的是ghij 你用nextLine(),第一次取的是abc de ...

  5. Windows10 + Ubuntu 20.04 LTS 双系统安装 (UEFI + GPT)(图文,多图预警)

    版权声明:本文为CSDN博主「ZChen1996」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/ZChen1 ...

  6. Centos7重置root密码(详细版)

    修改了root密码,步骤如下: 步骤一:在开机出现如下界面的时候就按“e”键     步骤二:在步骤一按下”e”键之后,出现如下界面,按 ↓键一直到底部找到“LANG=zh_CN.UTF-8”这句,在 ...

  7. Gulp的安装及用法

    1.安装淘宝镜像 npm install cnpm -g --registry=https://registry.npm.taobao.org cnpm -v 2.生成项目描述文件 package.j ...

  8. Java之reflection(反射机制)——通过反射操作泛型,注解

    一.反射操作泛型(Generic) Java采用泛型擦除机制来引入泛型.Java中的泛型仅仅是给编译器Javac使用的,确保数据的安全性和免去强制类型转换的麻烦.但是编译一旦完成,所有和泛型有关的类型 ...

  9. 初入Shell

    shell 第1章 Shell概述 大数据程序员为什么要学习Shell呢? 1)需要看懂运维人员编写的Shell程序. 2)偶尔会编写一些简单Shell程序来管理集群.提高开发效率. 第2章 Shel ...

  10. 第4章 DDL数据定义

    第4章 DDL数据定义 4.1 创建数据库 1)创建一个数据库,数据库在HDFS上的默认存储路径是/user/hive/warehouse/*.db. hive (default)> creat ...