Python单元测试unittest测试框架
本文的主题是自动化测试框架的实现,在实现之前,先了解一下关于unittest模块的相关知识:
Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作。
在说unittest之前,先说几个概念:
TestCase 也就是测试用例
TestSuite 多个测试用例集合在一起,就是TestSuite
TestLoader是用来加载TestCase到TestSuite中的
TestRunner是来执行测试用例的,测试的结果会保存到TestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
1.yaml测试用例文件
unittest做自动化测试时,读取的测试用例文件是 ".yml"或者“.yaml”格式的用例文件,首先需要安装pyyaml,直接 pip install pyyaml等待安装完成即可;
编写yaml格式的测试用例文件,我们以一个登录接口为例,来写测试用例,文件名是:login.yaml 如下是3条测试用例:
-
url : /api/user/login #接口地址
method : post #请求方式
detail : 正常登录 #用例描述
data : #请求体
username : niuhanyang
passwd : aA123456
check : #预期结果
- userId
- sign -
url : /api/user/login
method : post
detail : 密码错误
data :
username : niuhanyang
passwd : aA12333
check :
- 密码错误 -
url : /api/user/login
method : post
detail : 不传密码
data :
username : niuhanyang
check :
- 必填参数未填
2.框架搭建
(1)首先需要将框架的路径建好,我这个框架在utp目录里面,utp目录下的具体目录层次如下:
bin目录存放执行的入口文件;
case_data存放的是yaml或者yml的用例文件;
case目录下存放自动生成的Python文件;
conf目录存放的是配置文件;
lib目录下存放的是主程序文件;
logs目录下存放的是日志文件;
report目录存放的是测试报告文件;
readme是说明;
(2)设置配置文件,在conf目录下创建setting.py文件,具体配置文件内容如下:
import os
BASE_PATH = os.path.dirname(
os.path.dirname(os.path.abspath(__file__))
)#基础路径,就是utp的路劲地址
MAIL_HOST='smtp.qq.com'
MAIL_USER='605130685@qq.com'
MAIL_PASSWRD = 'xxxxx'#邮箱的授权码
TO = [
'lyxiehong@@qq.com',
]
LEVEL = 'debug' #日志级别 LOG_PATH = os.path.join(BASE_PATH,'logs') #存放日志的路径
CASE_PATH = os.path.join(BASE_PATH,'cases') #存放用例的路径
YAML_PATH = os.path.join(BASE_PATH,'case_data') #存放yaml文件的路径
CASE_TEMPLATE = os.path.join(BASE_PATH,'conf','base.txt') #用例模板的路径
REPORT_PATH = os.path.join(BASE_PATH,'report') #存放测试报告的目录
BASE_URL = 'http://127.0.0.1' #接口的地址
LOG_NAME='utp.log' #日志的文件名
(3)写好请求接口的测试脚本,以登录接口为列,测试脚本写为base.txt格式的文件,具体脚本如下:
import unittest,requests
import ddt
from BeautifulReport import BeautifulReport as bf
from urllib import parse
from conf.setting import BASE_URL
@ddt.ddt
class %s(unittest.TestCase):
base_url = BASE_URL
@ddt.file_data(r'%s')#ddt帮你读文件,获取文件内容,循环调用函数
def test_request(self,**kwargs):
detail = kwargs.get('detail','没写用例描述')
self._testMethodDoc = detail #动态的用例描述
url = kwargs.get('url')#url
url = parse.urljoin(self.base_url,url)#拼接好url
method = kwargs.get('method','get')#请求方式
data = kwargs.get('data',{}) #请求参数
header = kwargs.get('header',{})#请求头
cookie = kwargs.get('cookie',{})#cookie
check = kwargs.get('check')
method = method.lower() #便于处理
try:
if method=='get':
res = requests.get(url,params=data,cookies=cookie,headers=header).text
#因为接口有异常的情况下, 可能返回的不是json串,会报错
else:
res = requests.post(url,data=data,cookies=cookie,headers=header).text
except Exception as e:
print('接口请求出错')
res = e
for c in check:
self.assertIn(c,res,msg='预计结果不符,预期结果:'+c + '实际结果:' +res)
将此base.txt的文件放在cases目录下,后面会用到此文件作为基础文件进行copy成Python文件的测试用例。
在测试时,如果有多个接口需要进行测试,那么就需要在case_data目录下将每个接口的测试用例写好,每个接口写一个yaml用例文件,每个yaml文件中会有好几条用例,
例如登录接口中,1.登录成功,2密码错误,3.必填参数未填,这就有3条用例;在跑测试的时候,所有yaml文件中的用例总数加起来的数量就是执行的用例数量;
我们的思路是,在case_data目录下有几个yaml测试用例文件,就把base.txt文件自动生成几份Python测试文件,Python测试文件的名字以yaml的文件名作为文件名,然后把所有的Python测试文件都执行一遍,
然后得出测试报告,最后测试结果邮件。为了看出效果,我在case_data目录又写了一个注册接口的yaml测试用例文件,名字叫reg.yaml,这个文件中只写 了一条用例,如下:
-
url : /api/user/user_reg
method : post
detail : 用户名字已经被注册的
data :
username : xiehong
passwd : aA123456
cpasswd : aA123456
check :
- 用户已存在
(4)根据case_data目录下的yaml文件的数量,在lib目录下新建tools.py文件,写自动生成Python测试文件的代码,一般主体代码都写在lib目录下,如下:
import datetime,os,yagmail,unittest
from conf import setting
from BeautifulReport import BeautifulReport as bf
def makeCase(): #这个函数自动生成Python文件
all_yaml = os.listdir(setting.YAML_PATH)#获取到YAML_PATH路径下的文件
base_case_str = open(setting.CASE_TEMPLATE,encoding='utf-8').read()#读取到文件里的东西
for yaml in all_yaml:
if yaml.endswith('.yaml') or yaml.endswith('.yml'):#判断是否是yml文件
class_name = yaml.replace('.yml','').replace('.yaml','').capitalize()#获取yaml文件的名字作为类名,并首字母大写
file_name = os.path.join(setting.YAML_PATH,yaml)#拼接用例yaml文件的绝对路径
content = base_case_str %(class_name,file_name)
#将读取到的文件中字符格式化赋值,就是即将生成Python文件的类名和文件名
py_file_name = os.path.join(setting.CASE_PATH,class_name)#拼好python文件的绝对路径
open('%s.py'%py_file_name,'w',encoding='utf-8').write(content)#写文件,content是写的内容
上面已经根据yaml文件的数量2,自动生成了2个Python测试文件,并且放在了cases目录下面,Login.py是测试登录接口的,Reg.py 是测试注册接口的。截图如下:
(6)接着在tools.py中写代码用来执行cases下的测试用例文件并生成测试报告,如下:
def run_all_case():#这个函数是运行所有的测试用例并生成测试报告
suite = unittest.TestSuite()#生成测试集合
all_py = unittest.defaultTestLoader.discover(setting.CASE_PATH,'*.py')
#找到CASE_PATH目录下的所有Python文件
[ suite.addTests(py) for py in all_py]
#列表生成式,添加文件里面的case到测试集合里面
run=bf(suite)#执行测试用例
today = datetime.datetime.today().strftime('%Y%m%d%H%M%S')#取当天的日期,精确到秒
title = '%s_接口测报告.html'%today#测试报告的文件名字
report_abs_path = os.path.join(setting.REPORT_PATH,title) #存放测试报告的路径
run.report(title,filename=title,log_path=setting.REPORT_PATH)
return run.success_count,run.failure_count,report_abs_path#返回成功和失败数量,以及测试报告的路径
(7)用例执行完了测试报告也生成了,接下来就是要把测试结果发邮件,还是继续在tools.py文件中写发送邮件的代码,如下:
def sendmail(title,content,attrs=None):#这个函数发送测试结果邮件
m = yagmail.SMTP(host=setting.MAIL_HOST,user=setting.MAIL_USER
,password=setting.MAIL_PASSWRD
,smtp_ssl=True )#调用配置文件的配置数据
m.send(to=setting.TO,subject=title,
contents=content,
attachments=attrs)#setting.TO调用配置文件的配置数据
(8)主体代码基本上都写完了,接下来就要写执行文件了,也就是这些代码从哪调用连贯起来执行,需要提供一个执行的入口,这个入口文件就放在bin目录下,
我们把这个执行入口的文件起名叫run.py,具体代码:
import os,sys
import datetime
BASE_PATH = os.path.dirname(
os.path.dirname(os.path.abspath(__file__))
)
sys.path.insert(0,BASE_PATH)#将utp目录加入环境变量
from lib import tools
def mail():
tools.makeCase()#调用函数自动产生python文件
pass_count,fail_count,abs_path = tools.run_all_case()
#调用函数运行用例,将返回结果赋值给pass_count,fail_count,abs_path
msg='''
各位好!
本次接口测试结果如下:
通过用例:%s条
失败用例:%s条
详细信息见附件【%s】。
'''%(pass_count,fail_count,os.path.basename(abs_path))
#获取abs_path的最后一级,就是报告的名称
today = datetime.datetime.today().strftime('%Y%m%d%H%M%S')
title = '接口测试报告_%s'%today #邮件标题
tools.sendmail(title,msg,abs_path) #发送邮件
mail()
至此,一个自动化测试框架基本完成,如有错误,欢迎指出!
Python单元测试unittest测试框架的更多相关文章
- python利用unittest测试框架组织测试用例的5种方法
利用unittest测试框架可以编写测试用例,执行方式分两大类:利用main方法和利用testsuite,其中利用测试套件来组织测试用例可以有4种写法. 在此之前,先了解几个概念 TestCase:所 ...
- 基于python的unittest测试框架集成到jenkins(Mac)
1.jenkins部分 1.1 安装jenkins jenkins下载地址:https://jenkins.io/download/ 安装步骤,疯狂点击下一步 1.2 打开jenkins服务 在浏览器 ...
- Python接口测试实战3(下)- unittest测试框架
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- 基于Python的接口自动化-unittest测试框架和ddt数据驱动
引言 在编写接口自动化用例时,我们一般针对一个接口建立一个.py文件,一条接口测试用例封装为一个函数(方法),但是在批量执行的过程中,如果其中一条出错,后面的用例就无法执行,还有在运行大量的接口测试用 ...
- Python 下的unittest测试框架
unittest测试框架,直接上图吧: data:数据:主要格式为CSV:读取方式:csv.reade: public:封装的模块:通用的模块单独封装,所需参数设置为变量: testcase:测试用例 ...
- <day002>Selenium基本操作+unittest测试框架
任务1:Selenium基本操作 from selenium import webdriver # 通用选择 from selenium.webdriver.common.by import By # ...
- python实例编写(6)--引入unittest测试框架,构造测试集批量测试(以微信统一管理平台为例)
---恢复内容开始--- 一.python单元测试实例介绍 unittest框架又叫PyUnit框架,是python的单元测试框架. 先介绍一个普通的单元测试(不用unittest框架)的实例: 首先 ...
- Python单元测试unittest - 单元测试框架
一.unittest简介 unitest单元测试框架最初是有JUnit的启发,它支持测试自动化,共享测试的设置和关闭代码,将测试聚合到集合中,以及测试与报告框架的独立性. 二.unittest相关概念 ...
- python单元测试unittest
单元测试作为任何语言的开发者都应该是必要的,因为时隔数月后再回来调试自己的复杂程序时,其实也是很崩溃的事情.虽然会很快熟悉内容,但是修改和 调试将是一件痛苦的事情,如果你在修改了代码后出现问题的话,而 ...
随机推荐
- koa2--06.koa-static中间件的使用
koa-static中间件,主要用于设置静态文件资源的文件路径 首先安装koa-static中间,以下是代码示例 const koa = require('koa'); var router = re ...
- Codeforces Round #524 (Div. 2) codeforces 1080A~1080F
目录 codeforces1080A codeforces 1080B codeforces 1080C codeforces 1080D codeforces 1080E codeforces 10 ...
- socket粘包问题及解决方案
一.粘包问题 问题1: 无法确认对方发送过来数据的大小. 'client.py' import socket client = socket.socket() client.connect( ('12 ...
- $CF1063B\ Labyrinth$ $01$最短路/$01BFS$
\(Des\) 有一个网格图,上面的格子分为空地和障碍,障碍是不可以走的.现在从给定的起点出发开始到处乱走,最多可以往左走\(l\)次,往右走\(r\)次.求可能到达的点数. \(Sol\) 如果只限 ...
- nodejs监听服务端口并且代理请求与静态资源
var express = require('express'); const proxy = require('http-proxy-middleware'); const app = expres ...
- ssh免密登陆和加密解密
一 丶实现无密码的远程管理 1.生成公钥 私钥 [root@room9pc14 桌面]# ssh-keygen [root@room9pc14 桌面]# ls /root/.ssh/ 2.上传公钥到虚 ...
- @Configuration结合@Bean实现对象的配置
@Configuration结合@Bean实现对象的配置 前提:最近项目中需要做支付接口,支付宝以及微信支付,本文并不介绍如何写支付接口,而是通过这个示例讲解配置应该怎么写,项目中使用的是Kotlin ...
- oracle-按年、月、周、日、时、分 分组查询统计数据,无数据补零(connect by)
目的:统计一段时间内每年.每月.每周.每日.每时.每分数据,无数据时自动补零 思路:1. 生成给定时间段对应日期 2. 将原表中该时间段内的不为0的数据量统计出来 3. 用left join连接起来, ...
- 侠说java8--Stream流操作学习笔记,都在这里了
前言 首次接触到Stream的时候以为它是和InputStream.OutputStream这样的输入输出流的统称. 流和集合的前世今生 概念的差异 在开发中,我们使用最多的类库之一就是集合.集合是一 ...
- 使用WebUploader上传HTML文件并读取文件
需求: 前端需要上传HTML文件并识别里面有多少个特殊标签并录入到数据库. 思路: 使用WebUploader上传文件,然后使用FileReader接口和DOMParser识别HTML中的特殊标签 资 ...