一、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. Linux学习日志——基本指令②

    文章目录 Linux学习日志--基本指令② 前言 touch cp (copy) mv (move) rm vim 输出重定向(> 或 >>) cat df(disk free) f ...

  2. 下面POM插件的作用是转换包名,修改tomcat跳转端口

    <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat6-mave ...

  3. 旧 WCF 项目成功迁移到 asp.net core web api

    背景 接上一篇,放弃了 asp.net core + gRPC 的方案后,我灵光一闪,为什么不用 web api 呢?不也是 asp.net core 的吗?虽然 RESTful 不是强约束,客户端写 ...

  4. 41.4 Method Security方法安全性

    41.4.1 <global-method-security> 这个元素是为Spring Security beans上的安全方法添加支持的主要手段.可以通过使用注释(在接口或类级别定义) ...

  5. (转)软件产品化,国内IT人之痛

    原文链接:http://blog.csdn.net/harrymeng/article/details/5254415 记得在网上看过一则印度软件的有趣故事,意思是先从印度6个不同城市的软件公司中选出 ...

  6. python基础 Day3

    python Day3 1.作业回顾 设定一个理想的数字比如88,让用户输入数字,如果比88大,则显示猜测的结果大:如果比66小,则显示猜测的结果小了,给用户三次猜测机会,如果显示猜测正确退出循环,如 ...

  7. Eclipse中构建maven项目的两种方式

    Eclipse中构建maven项目的两种方式 方式一: 1.构建maven项目 1.1 新建meven项目,可在Other中找到maven文件夹 1.2 进入maven项目后,点击next 1.3 在 ...

  8. 团队作业1——团队展示&选题 (追忆少年)

    目录 一,团队展示 1.1队名 1.2队员学号 1.3项目描述 1.4队员风采 1.5团队分工 1.6团队合照 1.7团队特色 (一)目标导向 (二)协作基础 (三)共同的规范和方法 (四)技术或技能 ...

  9. zookeeper基本配置以及一些坑

    配置 1. 解压安装包:tar zxvf zookeeper-3.4.14.tar.gz 2. 修改zookeeper配置: #Master cd zookeeper-3.4.14 #创建日志文件夹及 ...

  10. 作为一个Java程序员连简单的分页功能都会写,你好意思嘛!

    今天想说的就是能够在我们操作数据库的时候更简单的更高效的实现,现成的CRUD接口直接调用,方便快捷,不用再写复杂的sql,带吗简单易懂,话不多说上方法 1.Utils.java工具类中的方法 1 /* ...