python_UnitTest测试框架

本文详细介绍UnitTest测试框架的应用,包括requests模块的使用方法、调试接口、断言方法汇总等内容,并提供了丰富的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、requests模块

Ⅰ、 模块导入

requests模块非原生模块,所以要使用需要先进行安装,cmd中输入命令:pip install requests
如果是已经安装过的则展示安装所在的文件位置

如果安装完成后PyCharm中导入模块import requests标红报错

解决办法1:(可解决当前项目 import requests 问题,但新建一个项目可能又不行)

  • 打开pycharm->File->Settings->Project Interprete ,点击“+”号按钮
    在这里插入图片描述
  • 然后点击添加 ,搜requests,选中后点左下角的install ,等待安装完成即可,就不会报ModuleNotFoundError: No module named 'requests’这个错了
    在这里插入图片描述
    解决办法2:(新建一个项目也没问题)
  • https://blog.youkuaiyun.com/qq_21041889/article/details/94392538

Ⅱ 、发送请求 / 获取响应结果

发送请求:

reques t[ rɪ'kwest ]
r = requests.方法(url, headers,data, ···)

其中url必填,其他参数根据实际情况选择性使用,发送请求后悔获取响应结果,然后把结果赋值给变量,最后通过变量的属性值取出需要的结果
获取结果:

response [ rɪ'spɒns ]
response.headers			获取返回的头信息
response.text				获取返回的主体
response.cookies			获取返回的cookie
response.status_code		获取返回的状态码
···

实操:

import requests
# 访问网易首页,并获取返回状态码
test_url = "http://www.163.com"
r = requests.get(test_url)
print(r.status_code)

# 输出
200

Ⅲ、常用参数

url:
唯一必填参数,上方有说明

headers:
模拟手机端访问网易首页,这时候就需要带上headers参数,通过抓包可发现headers有个字段"User-Agent",而服务器就是通过这个字段来判断访问的来源,代码如下:

import requests
# 访问网易首页,并获取返回状态码
test_url = "http://www.163.com"
h = {"User-Agent":"Android/BKL-AL00/9.0.0/"}
r = requests.get(test_url, header = h)
print(r.status_code)

cookies:
cookies参数以字典形式发送,只需要对应的将namevalue传入即可,代码如下:

import requests

test_url = "http://mail.163.com/js6/main.jsp?sid=xkjskjsnlsoakskoa&df=163nav_icon"
c = "JSESSIONID=6272e7c3762fa26619780af615a75a0b"
h = {"User-Agent":"Android/BKL-AL00/9.0.0/"}
r = requests.get(test_url, header = h, cookies = c)
print(r.status_code)

params: 可以存放请求的表单,并会以key1=value1&key2=value2的形式跟在url之后发送,为了区分url和参数,最好不要把表单放在url中,可以通过params参数来分离

import requests

# 分离 (test_url = "http://mail.163.com/js6/main.jsp?sid=xkjskj&df=163nav_icon")

test_url = "http://mail.163.com/js6/main.jsp"
p = ("sid":"xkjskj", "df":"163nav_icon") # 将需要发送的表单以字典的形式赋值到变量p中
h = {"User-Agent":"Android/BKL-AL00/9.0.0/"}
r = requests.get(test_url, params = p)
print(r.status_code)

data: 此参数也是用于存放请求的表单,是request模块最重要的参数之一

补充:
params和data的区别:
params > params是添加到url的请求字符串中的,用于get请求,只能提交一种类型的数据"字符串"
data > 添加到请求体(body)中的, 用于post请求

post请求: 可以提交4种类型的数据,取决与服务器接收的数据类型,post的数据类型需要和服务器接收的一致,不然服务器就无法正确识别post的数据,导致测试结果报错。

  • post四种数据类型:
    • application/json: Content-Type:application/json作为响应头大家肯定不陌生,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/xml

Ⅳ、porttest

  • 请求简介:
  • 不带params的get请求,一般是请求静态页面,大多数只用来测试页面是否存在,返回数据是否正常
  • 带params的get请求,一般是查询请求
  • 带form的post请求,一般是修改/提交/查询…数据

二、有效可用调试接口


`https接口`

淘宝查询电话号码归属地(可用)

https://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=手机号

百付宝接口(可用)

https://www.baifubao.com/callback?cmd=1059&callback=phone&phone=手机号

`http接口`

快递接口:
http://www.kuaidi100.com/query?type=快递公司代号&postid=快递单号

ps:快递公司编码:申通=”shentong” EMS=”ems” 顺丰=”shunfeng” 圆通=”yuantong” 中通=”zhongtong” 
韵达=”yunda” 天天=”tiantian” 汇通=”huitongkuaidi” 全峰=”quanfengkuaidi” 德邦=”debangwuliu” 宅急送=”zhaijisong”

谷歌接口(不确定是否可用)
FeedXml转json接口:

http://ajax.googleapis.com/ajax/services/feed/load?q=Feed地址&v=1.0

备选参数:callback:&callback=foo就会在json外面嵌套foo({})方便做jsonp使用。

备选参数:n:返回多少条记录。

音乐接口
QQ空间音乐接口(可用)

http://qzone-music.qq.com/fcg-bin/cgi_playlist_xml.fcg?uin=QQ号码&json=1&g_tk=1916754934

QQ空间收藏音乐接口(可用)

http://qzone-music.qq.com/fcg-bin/fcg_music_fav_getinfo.fcg?dirinfo=0&dirid=1&uin=QQ&p=0.519638272547262&g_tk=1284234856

多米音乐接口(可用)

http://v5.pc.duomi.com/search-ajaxsearch-searchall?kw=关键字&pi=页码&pz=每页音乐数

soso接口(可用)

http://cgi.music.soso.com/fcgi-bin/fcg_search_xmldata.q?source=10&w=关键字&perpage=1&ie=utf-8

地图接口
阿里云根据地区名获取经纬度接口(可用)

http://gc.ditu.aliyun.com/geocoding?a=苏州市

参数解释: 纬度,经度type 001 (100代表道路,010代表POI001代表门址,111可以同时显示前三项)

阿里云根据经纬度获取地区名接口(可用)

http://gc.ditu.aliyun.com/regeocoding?l=39.938133,116.395739&type=001

IP接口
新浪接口(ip值为空的时候 获取本地的)(可用)

http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=218.4.255.255

手机信息查询接口
淘宝网接口(可用)

http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=手机号

获取QQ昵称和用户头像(可用,不过会提示登录)

http://r.qzone.qq.com/cgi-bin/user/cgi_personal_card?uin=QQ

三、断言方法汇总

assertEqual:A为预期值,B为实际值

方法解释
assertEqual(a, b)判断ab是否相等
assertNotEqual(a, b)判断ab不相等
assertIs(a, b)判断a是b
assertIsNot(a, b)判断a不是b
assertIsNone(a)判断a是不是None
assertIsNotNone(a)判断a不是None
assertIn(a,b)判断a在b中,此时a与b可以相等
assertNotIn(a, b)判断a不在b中
assertIsInstance(a, b)判断a是否属于b的实例
assertNotIsInstance(a, b)判断a不属于b的实例
assertGreater(a, b)判断a > b
assertGreaterEqual(a, b)判断a >= b
assertLess(a, b)判断a < b
assertLessEqual(a, b)判断a <= b

四、UnitTest测试框架

  • UnitTest Unit :单元 [ 'juːnɪt ]
    • testcase(测试用例)
    • testsuite(测试套件):多个测试用例组成一个测试套件
    • testfixtrue(测试固件):整合了代码中相同的公共部分,减少代码冗余,比如通过setup()进行初始化,同样的还可以使用teardown()来结束测试工作
    • testrunner(测试运行器):给测试用例提供运行环境,通过它的run()方法,来执行测试用例,并在执行完成后把结果输出在testresult
      · HTMLTestRunner(测试报告)

Ⅰ、testcase(测试用例)

需要通过继承TestCase类来构建测试用例,既可以一个测试用例生产一个类,也可以多个测试用例生产一个类,后者执行效率更高效,构建代码格式如下:

	calss 测试类名(unittest.TestCase):   # 这个类继承了unittest的TestCase的基类
		testcase1
		testcase2
		...

实际代码:

import unittest
import requests

class VersionTest(unittest.TestCase):
    def test1(self):
        url = "https://jdsq.jdsq360.com/wx/version/check"
        form = ({"version": "1.1.6", "type": "vp"})
        r = requests.post(url, data=form)
        self.assertEqual(r.text, "验证成功!")    # r.text返回主体
        
    def test2(self):
        url = "https://jdsq.jdsq360.com/wx/version/check"
        form = ({"version": "1.1.7", "type": "vp"})
        r = requests.post(url, data=form)
        self.assertEqual(r.text, "验证失败!")

Ⅱ、testsuite(测试套件)

完成了 testcase准备工作,进行组合时就需要用到testsuite suite:套 [ swiːt ]

import unittest
import requests

class VersionTest(unittest.TestCase):
    def test1(self):
        # 省略之前代码
    def test2(self):
        # 省略之前代码
        
# 1
def suite():
    vt = unittest.TestSuite()       # TestSuite重点,勿写错!!!!!
    vt.addTest(VersionTest("test1"))  # 把"test1"的用例都导入套件
    vt.addTest(VersionTest("test2"))  # 把"test2"的用例都导入套件
    return vt

# 2
def suite():
    vt = unittest.makeSuite(VersionTest, "test")  # 把所有"test"开头的用例都导入套件
    return vt

Ⅲ、test runner(测试运行器)

import unittest
import requests

class VersionTest(unittest.TestCase):
    def test1(self):
        # 省略之前代码
    def test2(self):
        # 省略之前代码
        
# 1
def suite():
    # 省略之前代码

if __name__ == '__main__':
	# 方法1
	# 运行套件suite()中的testcase
    unittest.TextTestRunner().run(suite())    
    
    # verbosity 参数可以控制输出的错误报告的详细程度,不填写默认为1,详情见补充内容
    unittest.TextTestRunner(verbosity=2).run(suite())    
    
    # 方法2
    unittest.main()   # 所有操作封装在main方法中,完成所有testcase的加载和运行

补充verbosity 参数内容:
0 (静默模式): 你只能获得总的测试用例数和总的结果 比如 总共100个 失败20 成功80
1 (默认模式): 非常类似静默模式 只是在每个成功的用例前面有个“.” 每个失败的用例前面有个 “F”
2 (详细模式):测试结果会显示每个测试用例的所有相关的信息

Ⅳ、HTMLTestRunner(测试报告)

下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html
在这里插入图片描述
此模板基于python 2.x写的,如果使用python 3.x的话需要做以下修改:

94行: 引入的名称,从import StringIO改成import io
539行: self.outputBuffer=StringIO.StringIO()改成self.outputBuffer=io.StringIO()

631行: print>>sys.stderr,'\nTime Elapsed:%s' % (self.stopTime-self-startTime)改成:
              print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))

642行: if not rmap.has_key(cls):改成if not cls in rmap:
766行: uoo.decode('latin-1')改成uo = e
772行: ue = e.decode('latin-1')改成ue = e
778行: output = saxutils.escape(uo+ue),改成output = saxutils.escape(str(uo)+str(ue)),

存储路径:
将修改的文件存放在Pythonx.x安装路径Lib文件夹下

尝试运行:

import unittest
import requests
import HTMLTestRunner

class VersionTest(unittest.TestCase):
    def test1(self):
        # 省略之前代码
    def test2(self):
        # 省略之前代码
        
# 1
def suite():
    # 省略之前代码

if __name__ == '__main__':
    fr = open("testreal.html", "wb") # 新建一个testreal.html文件,并设置读写权限为读写
    runner = HTMLTestRunner.HTMLTestRunner(stream=fr, title="测试报告", description="详情")
    runner.run(suite())
       
    # 使用HTMLTestRunner模块中的HTMLTestRunner方法,构建一个运行器对象,并通过参数将结果写入testreal.html文件
    # 标题为"测试报告",描述为"详情",最后也是通过run()方法完成运行

五、实际问题汇总

Ⅰ、测试报告不生成

1、无报错:
PyCharm会默认使用自带的unittest框架来执行单元测试,不会执行main函数中的代码,所以不生成测试报告 ,判断可查看右上角文件名前有 Unittests in 文件名
在这里插入图片描述
解决:
在这里插入图片描述
2、有报错:
报错信息:.<_io.TextIOWrapper name=’’ mode=‘w’ encoding=‘UTF-8’>
解决:HTMLTestRunner.py文件修改631行,1或者2修改为3保存即可解决
1、print >> sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime)
2、print(sys.stderr, ‘\nTime Elapsed: %s’ % (self.stopTime-self.startTime))
3、sys.stderr.write(’\nTime Elapsed: %s\n’ % (self.stopTime - self.startTime))

Ⅱ、处理josn返回数据

1、转换为字典

import json

AA = {
    "statusCode": 200,
    "data": {
        "totoal": "5",
        "height": "5.97",
        "weight": "10.30",
        "age": "11"
    },
    "msg": "成功"
}

s = json.dumps(AA)  # dumps:把字典AA转换为json字符串
s1 = json.loads(s)  # loads:把json转换为dict

print(s1["statusCode"]) # 打印statusCode对应的值   200
print(s1["data"]["age"])   # 打印AA里  data下age对应的值   11
print(len(s1["data"]))   # 打印AA里    data对应的值的个数   4
print(len(s1))   # 打印AA里值对的个数   3
import json

  def test3(self):
        test_url = "https://xxx.goho.co/jdshop/api/wxapp/store/getBanner"
        r = requests.get(test_url)
        s1 = json.loads(r.text)        
        self.assertEqual(len(s1), 3)      # 判断数量是否为3
        
        # json.loads()返回josn数据主体转换为python字典,并赋值给s1
        # r.text 接口返回主体(是josn数据格式)
		 #  len(s1)获取字典内元素个数

Ⅲ、处理返回的cookies

response.cookies是获取response中cookie属性,返回的<class ‘requests.cookies.RequestsCookieJar’>,是一个类
response.cookies.get_dict()返回的是字典格式cookie
Eg:

import requests

url = "https://xxx.jdsq360.com/api/store/storer/login"
p = {"account": "wanglixin", "pwd": "123456"}
r = requests.get(url, params=p)
cookies = r.cookies.get_dict()
print(r.cookies)
print(cookies)

# 输出结果
<RequestsCookieJar[<Cookie JSESSIONID=B889AF415023FFD986C8E389CD9DFD58 for haohuo.jdsq360.com/>]>
{'JSESSIONID': 'B889AF415023FFD986C8E389CD9DFD58'}

Ⅳ、生成测试报告报错

1、 报错信息:<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>

解决方案:
HTMLTestRunner.py的631行,此时可能是1或者2,修改为3
1.print >> sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)
2.print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
3.sys.stderr.write('\nTime Elapsed: %s\n' % (self.stopTime - self.startTime)) <<< 修改为此内容即可

2、 报错信息:requests.exceptions.SSLError: HTTPSConnectionPool

解决方案1:抓包工具忘记关windows抓包导致证书错误,关闭即可.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值