精华内容
下载资源
问答
  • python接口自动化

    千次阅读 2020-08-18 19:17:33
    python接口自动化-unittest简介 测试框架-unittest,相当于是一个 python 版的 junit。python 里面的单元测试框架除了 unittest,还有一个 pytest 框架,这个实际上用的比较少,后面有空再继续介绍和分享。unittest...

    python接口自动化-unittest简介

       测试框架-unittest,相当于是一个 python 版的 junit。python 里面的单元测试框架除了 unittest,还有一个 pytest 框架,这个实际上用的比较少,后面有空再继续介绍和分享。unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果。
    

    用法
    1.首先从print的help里查找unittest用法
    在这里插入图片描述2、将上图的这段代码 copy 出来,单独运行,看看测试和运行结果
    在这里插入图片描述代码分析和说明:
    1、第一行是导入 unittest 这个模块
    2、class 这一行是定义一个测试的类,并继承 unittest.TestCase 这个类
    定义测试类,父类为unittest.TestCase。 #可继承unittest.TestCase的方法,如setUp和tearDown方法,不过此方法可以在子类重写,覆盖父类方法。 #可继承unittest.TestCase的各种断言方法。
    3、接下来是定义了两个测试 case 名称:testAdd 和 testMultiply4、注释里面有句话很重要:## test method names begin ‘test*’–翻译:测试用例的名称要以 test 开头
    4、然后是断言 assert,这里的断言方法是 assertEqual-判断两个是否相等,这个断言可以是一个也可以是多个
    5、if 下面的这个 unittest.main()是运行主函数,运行后会看到测试结果(跑了两个用例耗时 0.000 秒,两个用例都通过)
    模仿和实践
    1、既然都了解的差不多了,还等什么呢,开始模仿和敲起了来吧。
    2、上面的两个案例是加法和乘法,我们可以写个 case 试下减法和除法。
    3、有很多小伙伴不知道断言怎么写,断言其实就是拿实际结果和期望结果去对比,对比的方法很多,这里只是举的最简单的一个判断相等的方法
    在这里插入图片描述参考代码
    1 # coding=utf-8 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4 #2.注释:包括记录创建时间,创建人,项目名称。 5 ‘’’ 6 Created on 2019-4-23 7 @author: 北京-宏哥 8 Project:学习和使用unittest框架编写测试用例思路 9 ‘’’ 10 #3.导入unittest模块 11 import unittest 12 13 #4.copy 和运行测试 14 class IntegerArithmeticTestCase(unittest.TestCase): 15 def testSubtract(self): # test method names begin with ‘test’ 16 result = 6-5 #实际结果 17 hope = 1 #期望结果 18 self.assertEqual(result, hope) 19 20 def testDivide(self): 21 result = 7 / 2 # 实际结果 22 hope = 3.5 # 期望结果 23 self.assertEqual(result, hope) 24 25 if name == ‘main’: 26 unittest.main()
    前置条件和后置条件
    1、setUp:在写测试用例的时候,每次操作其实都是基于打开浏览器输入对应网址这些操作,这个就是执行用例的前置条件。
    2、tearDown:执行完用例后,为了不影响下一次用例的执行,一般有个数据还原的过程,这就是执行用例的后置条件。
    3、很多小伙伴执行完用例,都不去做数据还原,以致于下一个用例执行失败,这就是典型的自己给自己挖坑埋自己,自己坑自己,习惯不好。
    4、前置和后置都是非必要的条件,如果没有也可以写 pass
    在这里插入图片描述参考代码
    1 # coding=utf-8 2 #1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 3 4 #2.注释:包括记录创建时间,创建人,项目名称。 5 ‘’’ 6 Created on 2019-4-23 7 @author: 北京-宏哥 8 Project:学习和使用unittest框架编写测试用例思路 9 ‘’’ 10 #3.导入unittest模块 11 import unittest 12 13 #4.前置、后置 和运行测试 14 class Test(unittest.TestCase): 15 16 def setUp(self): 17 pass #如果没有可以不写或者pass代替 18 19 def tearDown(self): 20 pass 21 22 def testSubtract(self): # test method names begin with ‘test’ 23 result = 6-5 #实际结果 24 hope = 1 #期望结果 25 self.assertEqual(result, hope) 26 27 def testDivide(self): 28 result = 7 / 2 # 实际结果 29 hope = 3.5 # 期望结果 30 self.assertEqual(result, hope) 31 32 if name == ‘main’: 33 unittest.main()
    小结
    一、unittest模块的各个属性说明
    先来聊一聊unittest模块的各个属性,所谓知己知彼方能百战百胜,了解unittest的各个属性,对于后续编写用例有很大的帮助。
    1.unittest的属性如下:
    [‘BaseTestSuite’, ‘FunctionTestCase’, ‘SkipTest’, ‘TestCase’, ‘TestLoader’, ‘TestProgram’, ‘TestResult’, ‘TestSuite’, ‘TextTestResult’, ‘TextTestRunner’, ‘_TextTestResult’, ‘all’, ‘builtins’, ‘doc’, ‘file’, ‘name’, ‘package’, ‘path’, '_unittest’, ‘case’, ‘defaultTestLoader’, ‘expectedFailure’, ‘findTestCases’, ‘getTestCaseNames’, ‘installHandler’, ‘loader’, ‘main’, ‘makeSuite’, ‘registerResult’, ‘removeHandler’, ‘removeResult’, ‘result’, ‘runner’, ‘signals’, ‘skip’, ‘skipIf’, ‘skipUnless’, ‘suite’, ‘util’]
    说明:
    unittest.TestCase:TestCase类,所有测试用例类继承的基本类。
    class BaiduTest(unittest.TestCase):
    unittest.main():使用她可以方便的将一个单元测试模块变为可直接运行的测试脚本,main()方法使用TestLoader类来搜索所有包含在该模块中以“test”命名开头的测试方法,并自动执行他们。执行方法的默认顺序是:根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。
    unittest.TestSuite():unittest框架的TestSuite()类是用来创建测试套件的。
    unittest.TextTextRunner():unittest框架的TextTextRunner()类,通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。
    unittest.defaultTestLoader(): defaultTestLoader()类,通过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试套件,因此可以直接通过run()方法执行discover。用法如下:
    discover=unittest.defaultTestLoader.discover(test_dir, pattern='test
    .py’)
    unittest.skip():装饰器,当运行用例时,有些用例可能不想执行等,可用装饰器暂时屏蔽该条测试用例。一种常见的用法就是比如说想调试某一个测试用例,想先屏蔽其他用例就可以用装饰器屏蔽。
    @unittest.skip(reason): skip(reason)装饰器:无条件跳过装饰的测试,并说明跳过测试的原因。
    @unittest.skipIf(reason): skipIf(condition,reason)装饰器:条件为真时,跳过装饰的测试,并说明跳过测试的原因。
    @unittest.skipUnless(reason): skipUnless(condition,reason)装饰器:条件为假时,跳过装饰的测试,并说明跳过测试的原因。
    @unittest.expectedFailure(): expectedFailure()测试标记为失败。
    2.TestCase类的属性如下:
    [‘call’, ‘class’, ‘delattr’, ‘dict’, ‘doc’, ‘eq’, ‘format’, ‘getattribute’, ‘hash’, ‘init’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘_addSkip’, ‘_baseAssertEqual’, ‘_classSetupFailed’, ‘_deprecate’, ‘_diffThreshold’, ‘_formatMessage’, ‘_getAssertEqualityFunc’, ‘truncateMessage’, ‘addCleanup’, ‘addTypeEqualityFunc’, ‘assertAlmostEqual’, ‘assertAlmostEquals’, ‘assertDictContainsSubset’, ‘assertDictEqual’, ‘assertEqual’, ‘assertEquals’, ‘assertFalse’, ‘assertGreater’, ‘assertGreaterEqual’, ‘assertIn’, ‘assertIs’, ‘assertIsInstance’, ‘assertIsNone’, ‘assertIsNot’, ‘assertIsNotNone’, ‘assertItemsEqual’, ‘assertLess’, ‘assertLessEqual’, ‘assertListEqual’, ‘assertMultiLineEqual’, ‘assertNotAlmostEqual’, ‘assertNotAlmostEquals’, ‘assertNotEqual’, ‘assertNotEquals’, ‘assertNotIn’, ‘assertNotIsInstance’, ‘assertNotRegexpMatches’, ‘assertRaises’, ‘assertRaisesRegexp’, ‘assertRegexpMatches’, ‘assertSequenceEqual’, ‘assertSetEqual’, ‘assertTrue’, ‘assertTupleEqual’, 'assert’, ‘countTestCases’, ‘debug’, ‘defaultTestResult’, ‘doCleanups’, ‘fail’, ‘failIf’, ‘failIfAlmostEqual’, ‘failIfEqual’, ‘failUnless’, ‘failUnlessAlmostEqual’, ‘failUnlessEqual’, ‘failUnlessRaises’, ‘failureException’, ‘id’, ‘longMessage’, ‘maxDiff’, ‘run’, ‘setUp’, ‘setUpClass’, ‘shortDescription’, ‘skipTest’, ‘tearDown’, ‘tearDownClass’]
    说明:
    setUp():setUp()方法用于测试用例执行前的初始化工作。如测试用例中需要访问数据库,可以在setUp中建立数据库连接并进行初始化。如测试用例需要登录web,可以先实例化浏览器。
    tearDown():tearDown()方法用于测试用例执行之后的善后工作。如关闭数据库连接。关闭浏览器。
    assert
    ():一些断言方法:在执行测试用例的过程中,最终用例是否执行通过,是通过判断测试得到的实际结果和预期结果是否相等决定的。
    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的一个实例,不是则测试用例通过。
    3.TestSuite类的属性如下:(组织用例时需要用到)
    [‘call’, ‘class’, ‘delattr’, ‘dict’, ‘doc’, ‘eq’, ‘format’, ‘getattribute’, ‘hash’, ‘init’, ‘iter’, ‘module’, ‘ne’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘_addClassOrModuleLevelException’, ‘_get_previous_module’, ‘_handleClassSetUp’, ‘_handleModuleFixture’, ‘_handleModuleTearDown’, ‘_tearDownPreviousClass’, ‘_tests’, ‘addTest’, ‘addTests’, ‘countTestCases’, ‘debug’, ‘run’]
    说明:
    addTest(): addTest()方法是将测试用例添加到测试套件中,如下方,是将test_baidu模块下的BaiduTest类下的test_baidu测试用例添加到测试套件。
    suite = unittest.TestSuite() suite.addTest(test_baidu.BaiduTest(‘test_baidu’))
    4.TextTextRunner的属性如下:(组织用例时需要用到)
    [‘class’, ‘delattr’, ‘dict’, ‘doc’, ‘format’, ‘getattribute’, ‘hash’, ‘init’, ‘module’, ‘new’, ‘reduce’, ‘reduce_ex’, ‘repr’, ‘setattr’, ‘sizeof’, ‘str’, ‘subclasshook’, ‘weakref’, ‘_makeResult’, ‘buffer’, ‘descriptions’, ‘failfast’, ‘resultclass’, ‘run’, ‘stream’, ‘verbosity’]
    说明:
    run(): run()方法是运行测试套件的测试用例,入参为suite测试套件。
    runner = unittest.TextTestRunner() runner.run(suite)

    展开全文
  • python 接口自动化

    2019-06-08 09:11:00
    转自:https://www.cnblogs.com/yoyoketang/tag/python接口自动化/ 转载于:https://www.cnblogs.com/dreamhighqiu/p/10989942.html

    转自:https://www.cnblogs.com/yoyoketang/tag/python接口自动化/

    转载于:https://www.cnblogs.com/dreamhighqiu/p/10989942.html

    展开全文
  • python接口自动化测试二:python代码实现接口测试

    url = ‘接口地址‘

    r = requests.get(url) #发送get请求

    print(r.status_code) #打印状态码,若有重定向,返回的是重定向之后的代码

    print(r.headers) #打印返回的报头(头部)

    print(r.text) #查看返回结果的文本形式

    r.status_code #响应状态码

    r.content #字节方式的响应体,会自动为你解码 gzip 和 deflate 压缩

    r.headers #以字典对象存储服务器响应头,但是这个字典比较特殊,字典键不区分大小写,若键不存在则返回None

    r.json() #Requests中内置的JSON解码器 ,json转成python的字典了

    r.url # 如果没有重定向,就是请求的url,如果有重定向,就是重定向后的url

    r.encoding # 查看返回的编码格式

    r.cookies # 获取cookie

    r.raw #返回原始响应体

    r.history #追踪重定向过程(list类型)

    r.text #字符串方式的响应体,会自动根据响应头部的字符编码进行解码

    r.content.decode(‘utf-8‘) # 返回内容有乱码时,用此方法打印

    r.raise_for_status() #失败请求(非200响应)抛出异常

    loginCookies = r.cookies: # 获取登录的cookies

    cookies=loginCookies: # 把获取到的cookies传入请求

    s = requests.session() # 可以理解为代码的微型浏览器,这样做的好处就是可以保存cookies,不用每次都去获取(只适用于网站是cookies这种,网站是token的没用)

    print(r.encoding) # 查看返回的编码格式

    r.json # 获取返回的json

    verify=False # 访问https请求时加上后不验证证书

    # open打开excel文件,保存为后缀为xls的文件

    fp = open(‘yoyo.xls‘, ‘wb‘) # w:写入, b:二进制的形式

    去掉Warning警告:

    import urllib3

    urllib3.disable_warnings()

    一、HTTP:

    get请求:

    1、get请求(无参数):

    2、get请求(带参数):

    接口地址:http://japi.juhe.cn/qqevaluate/qq

    返回格式:json

    请求方式:get post

    请求示例:http://japi.juhe.cn/qqevaluate/qq?key=您申请的appKey&qq=295424589

    接口备注:根据传入的参数 qq 号码和您申请的 appKey 测试 qq 的吉凶

    请求参数说明(入参) :

    名称 必填 类型 说明

    key 是 string 您申请的 appKey:8dbee1fcd8627fb6699bce7b986adc45

    qq 是 string 需要测试的 QQ 号码:907728701

    2.1、以url的方式传参:

    url = ‘http://japi.juhe.cn/qqevaluate/qq?key= 8dbee1fcd8627fb6699bce7b986adc45&qq=907728701‘

    2.2、以字典的形式传参:

    url = ‘http://japi.juhe.cn/qqevaluate/qq‘

    par = {

    ‘key‘:‘ 8dbee1fcd8627fb6699bce7b986adc45‘,

    ‘qq‘:‘907728701‘

    }

    r = requests.get(url,params=par) #发送get请求

    Post请求:

    1、 post请求(无参数):

    url = ‘http://japi.juhe.cn/qqevaluate/qq‘

    r = requests.post(url) #发送post请求

    print(r.status_code) #打印状态码

    print(r.headers) #打印返回的报头(头部)

    print(r.text) #查看返回结果的文本形式(body部分)

    2、 post请求(有参数):

    2.1、以url的方式传参:

    url = ‘http://japi.juhe.cn/qqevaluate/qq?key= 8dbee1fcd8627fb6699bce7b986adc45&qq=907728701‘

    r = requests.post(url) #发送post请求

    2.2、以字典的形式传参:

    url = ‘http://japi.juhe.cn/qqevaluate/qq‘

    par = {

    ‘key‘:‘8dbee1fcd8627fb6699bce7b986adc45‘,

    ‘qq‘:‘907728701‘

    }

    r = requests.post(url,params=par) #发送get请求

    二、HTTPS:

    1、get:

    url = ‘https://www.juhe.cn/docs/api/id/39‘

    r = requests.get(url) #发送get请求

    print(r.status_code) #打印状态码

    print(r.headers) #打印返回的报头(头部)

    print(r.text) #查看返回结果的文本形式(body部分)

    SSLError:证书问题:

    方法1.检查faddler是否关闭,关闭后,访问成功:

    方法2.请求参数后加上:verify=False

    verify默认为True,此时会验证证书,改为False将不会验证证书

    有Body部分:

    Content-Type: application/x-www-form-urlencoded; charset=UTF-8:传data

    Content-Type: application/json:传json

    把返回的内容解析为json格式:

    前提:一定内容为json格式

    若乱码::

    以content字节流输出,解码成utf-8:

    print(r.encoding) # 查看返回的编码格式:

    去掉Warning警告:

    import urllib3

    urllib3.disable_warnings()

    错误处理:

    403:拒绝或者禁止访问:须伪装头部(头部详情根据接口文档)

    1、服务器识别出为代码访问:

    1.1.代码访问的头部:User-Agent为python

    1.2.浏览器访问的头部:User-Agent为浏览器

    1.3.在头部加上User-Agent:

    2、伪装头部后仍然403:服务器校验Cookic (Cookic有时效性)

    2.1.代码访问时没有加Cookic

    2.2.浏览器访问时有Cookic

    2.3.在头部加上Cookic访问成功

    原文:https://www.cnblogs.com/zhongyehai/p/9159282.html

    展开全文
  • python 接口自动化测试python 接口自动化测试python 接口自动化测试python 接口自动化测试python 接口自动化测试python 接口自动化测试python 接口自动化测试python 接口自动化测试python 接口自动化测试python 接口...
  • 2019 Python接口自动化测试框架实战开发(一)

    万次阅读 多人点赞 2019-06-28 15:55:25
    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!...整个项目分为四个部分:接口基础丶接口开发丶Unittest与接口测试结合以及接口自动化框架从设计到开发 接口基础包括:H...

    说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

    项目源码下载

    目录

    一丶叙述

    二丶接口基础知识

    三丶接口测试工具

    四丶Fiddler的使用

    五丶unittest使用

    六丶mock服务入门到实战

    七丶接口自动化框架设计到开发


    一丶叙述

    1.项目介绍

    整个项目分为四个部分:接口基础丶接口开发丶Unittest与接口测试结合以及接口自动化框架从设计到开发

    接口基础包括:HTTP接口 / 常见接口 / 接口工具 / 接口基础知识

    接口开发:通过Django来开发get/post接口

    Unittest与接口测试结合:unittest应用 / 断言 / requests引入 / HTMLTestRunner / case的管理

    接口自动化框架从设计到开发:如何设计框架 / 封装工具类 / 重构基类 / 错误调试 / 结果收集以及处理 / 解决数据依赖 / 结果统计及报告发送

    项目整体思路:通过对接口数据文档的读写操作,来获取文档中case的所有数据,然后通过requests模块来发送请求获取的响应数据,通过返回的响应数据中的某个标志性字段的值来判断是否测试成功或者失败,最后将测试的结果数据写入到测试文档或者是html页面又或者是将结果以邮件的形式发送到指定邮箱,这是整个大框架思路,要完成这一系列自动化的测试框架,则需要有一定的python代码基础,博主这里只是粗略的叙述了思路,有很多地方就不细说了比如数据依赖等就请大家慢慢的阅读吧

    2.测试报告效果预览

    • unittest和HTMLTestRunner结合生成报告(新版本的)

    •  unittest和HTMLTestRunner结合生成报告(经典版本的)

    •  测试报告邮件通知

    二丶接口基础知识

    1.什么是接口

    连接前后端以及移动端,通俗来说就是前端和后端之间的桥梁,比如网站需要去调用银行丶微信及支付宝的接口来完成业务需求

    2.接口的种类

    外部接口和内部接口;内部接口又分为上层服务与下层服务以及同级服务

    3.接口的分类

    请求方式:post丶get丶delete丶put

    4.为什么要做接口测试

    原因:不同端的工作进度肯定是不一致的,那么就需要对最开始开发出来的接口进行测试;对于项目来说缩短项目周期,提高开发效率以及提高系统的健壮性

    5.接口测试流程

    需求讨论——需求评审——场景设计——用例设计——数据准备——执行

    6.为什么要设计测试用例

    • 理清思路,避免侧漏
    • 提高测试效率
    • 跟进测试进度
    • 告诉领导做过
    • 跟进重复重复性工作

    7.用例设计分类

    功能用例测试:测试功能是否正常丶测试功能是否按照接口文档实现

    逻辑用例设计:是否存在依赖业务,例如有些操作是需要用户登录成功的状态下才能进行的操作

    异常测试用例设计:参数异常以及数据异常;参数异常包括关键字参数丶参数为空丶多参数丶少参数丶错误参数,数据异常包括关键字数据丶数据为空丶长度不一致丶错误数据

    安全测试用例设计:cookie丶header丶唯一识别码

    三丶接口测试工具

    1.接口测试工具分类

    • 抓取接口工具

    httpwatch:集成于IE和Firefox浏览器中,在其他浏览器中无法使用,查看数据也比较麻烦

    wireshark:只要是经过电脑的所有请求都会去抓取,导致数据量比较庞大,看数据也比较麻烦

    fiddler:轻量级抓包工具,功能比较全,只会记录http请求不会像wireshark工具记录tcp和udp等请求

    • 测试接口工具:

    loadrunner:不仅仅是性能测试工具,由于该工具几乎都是基于http请求,所以也可以用来测试接口

    fiddler:它除了可以抓包还可以向接口发送各种请求

    soapui:接口和自动化测试工具,功能也比较强大

    jmeter:跟loadrunner一样不仅仅是做性能测试,也可以对接口进行测试

    postman:谷歌旗下的接口测试工具

    四丶Fiddler的使用

    1.抓取不同类型接口数据(http以及https)

    • 查看windows本机的IP

    • 配置fiddler

    • 需要保证要抓取的手机与电脑保持同一网段,博主这里使用逍遥模拟器模拟安卓手机,修改手机网络

    • 在高级选项中设置手动代理IP为windows本机IP地址,端口设置与fiddler抓取端口保持一致

    • 再安卓手机中打开知乎app,抓取知乎app的http服务的数据

    • 现在的移动app都是基于https请求的,所以需要在fiddler中设置https请求

    • 然后在手机端浏览器中访问windows电脑IP+port,进行网络安全证书的下载安装

    • 点击下面一个下载证书

    • 然后设置密码即可

    • 证书安装成功后,重新打开知乎app,则成功抓取https请求的数据

    • 在知乎app中随便对一文章进行评论,抓取该app评论接口

    2.数据模拟以及过滤规则

    • 如下图进行选择要过滤的hosts类型,并在输入框添加要过滤的hosts即可

    • 对知乎上的一篇文章进行回答后,获取https://api.zhihu.com/answers接口,查看发送的post请求数据中的content字段内容也就是博主回答的内容

    • 然后进行数据模拟,也就是点击fiddler软件上的replay对https://api.zhihu.com/answers接口进行post请求数据的而二次发送,由于知乎这边设定对一个问题只能进行一次回答,所以知乎服务器返回的json数据提示我们失败,同时也说明对接口进行二次数据发送成功,只是规则逻辑失败

    3.如何模拟接口响应数据

    • 首先第一步,访问知乎app热榜,在fiddler软件中获取接口查看服务器响应的json格式数据,从服务器返回的json数据看出热榜标题字段名为title_area

    • 然后选择服务器返回的数据类型为TextView,点击.View in Notepad即打开数据记事本,如下图在记事本中找到title_area字段的内容,该字段内容进行了将中文转换为一串字符串

    • 将记事本中的title_area字段的数据修改为this is a test for cdtaogang

    • 点击文件——另存为保存到桌面 

    • 回到fiddler中,左侧选中热榜接口,右侧选中AutoResponder,在此窗口下点击Add Rule将左侧的接口添加进去,在右侧下方导入保存在桌面的zhihu_hot.htm文件,最后点击sava保存

    • 回到知乎app中刷新当前热榜页面,则成功返回修改的热榜标题

    4.使用fiddler进行评论接口测试

    • 对一篇文章进行评论,抓取评论接口,因为get请求的接口测试太简单,所以博主这里选择评论接口即POST请求方式

    • 右击评论接口选择copy复制接口的url地址

    • 右侧选择Composer,将复制的评论接口url粘贴到地址栏,并选择POST请求方式

    • 因为评论接口涉及到用户身份验证也就是登录后才能进行评论的,所以需要将comments接口中request headers请求头中的所有请求数据以及请求数据中的TextView的值进行复制

    请求头数据

    请求体数据

    • 将上面复制的请求头和请求体数据分别粘贴到如下输入框中,点击Execute执行发送,然后在左侧则出现了另一个comments接口数据

    • 查看该comments接口,服务器返回的响应数据中与第一个comments接口一致,说明接口测试成功

    五丶unittest使用

    1.unittest简单使用

    • 在IDE中使用python的环境随便创建个py文件,需要注意的是该py文件的名字不能是test.py,否在运行时会出错,unittest包是python自带的不需要下载安装,代码如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/17 13:10'
    
    import unittest
    
    
    class TestMethod(unittest.TestCase):
    
        @classmethod
        def setUpClass(cls):
            print("Method before class execution")
    
        @classmethod
        def tearDownClass(cls):
            print("Method after class execution")
    
        def setUp(self):
            print("------setUp------")
    
        def tearDown(self):
            print("------tearDown------")
    
        def test_01(self):
            print("First test method")
    
        def test_02(self):
            print("The second test method")
    
    
    if __name__ == '__main__':
        unittest.main()
    • 直接run运行以上代码

    2.unittest和request重构封装

    说明:使用requests模块对接口url地址发送请求,通过unittest测试框架进行case测试

    • 首先博主在逍遥安卓模拟器中下载了一个看书app,通过fiddler对app上的某一接口进行获取,之所以选择对此app进行接口测试,是因为该app的所有接口全是POST请求

    • 在PyCharm下新建工程目录,目录下创建base包,在包下创建一个demo.py文件以及test_method.py文件,用于使用unittest框架来测试以上app接口

    • 在demo.py文件中,使用requests get以及post方法进行了封装,主要是根据传递的参数method来对get以及post方法进行分别调用而已,具体实现如下
    import requests
    
    
    class RunMain:
    	def send_get(self,url,data):
    		res = requests.get(url=url,data=data).json()
    		return res
    		
    	def send_post(self,url,data):
    		res = requests.post(url=url,data=data).json()
    		return res
    
    	def run_main(self,url,method,data=None):
    		res = None
    		if method == 'GET':
    			res = self.send_get(url,data)
    		else:
    			res = self.send_post(url,data)
    		return res
    • 在test_method.py文件中则创建测试类以及test方法,在test方法中调用demo.py中的run_main方法,即使用requests模块向传递的接口url地址和请求方式以及请求体发送对应的请求,这里使用setUp方法则是利用其优先调用而对RunMain类进行实例化
    import unittest
    import json
    import HtmlTestRunner
    from .demo import RunMain
    
    
    class TestMethod(unittest.TestCase):
        def setUp(self):
            self.run = RunMain()
    
        def test_01(self):
            url = 'http://api.ishugui.com/asg/portal/call/265.do'
            data = {
                "sstoken":"eyJleHAiOjE1Njg1MzgyNTczMzUsImlhdCI6MTU2MDc2MjI1NzMzNSwicHAiOiIxMTQwNTQ1Njg5MDYwMDQ0ODAwQHNvaHUuY29tIiwidGsiOiIwZkNYSHpjTUZzR0dFMEswbVdvUVFCNWVCanpXa0hmWiIsInYiOjB9.SDYkT9FpWrBbko6xRrESN74IXJhzkqQLtijKjGiVrqA",
                "gidinf":"x011060802ff0fd40695d68140002799751474c540b3",
                "ppinf":"2|1560762257|1561971857|bG9naW5pZDowOnx1c2VyaWQ6Mjg6MTE0MDU0NTY4OTA2MDA0NDgwMEBzb2h1LmNvbXxzZXJ2aWNldXNlOjMwOjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMHxjcnQ6MTA6MjAxOS0wNi0xN3xlbXQ6MTowfGFwcGlkOjY6MTEwNjA4fHRydXN0OjE6MXxwYXJ0bmVyaWQ6MTowfHJlbGF0aW9uOjA6fHV1aWQ6MTY6czk1YWIwNDk5NjE3YmJhNnx1aWQ6MTY6czk1YWIwNDk5NjE3YmJhNnx1bmlxbmFtZTowOnw",
                "pprdig":"kaKPdU0WwIdzL58CqxNz5pgMyv23P0-Y5GRnd5ufPlXIGzrk7_7TlIK5XFQiuoqAHNqGVXHCVd4cB1DIkR5yFZ_nExnSjIZbBJWYlMkrsiIjDYqWCvedZRLm8sZqS0WqA0FcKXuSn3Z0gVRus9YpEonNz5wyuWdUqxaSmzlzygY",
                "ppsmu":"1|1560762257|1561971857|dXNlcmlkOjI4OjExNDA1NDU2ODkwNjAwNDQ4MDBAc29odS5jb218dWlkOjA6fHV1aWQ6MDo|byWcaoPqy02s2_9GHLhZFAQ6Ov_GazMPFLrq115HiSTBS9Ijr33a55quRq2Mr1_6ZMruKEk-BYFpShUaMtwRYA"
            }
            res1 = self.run.run_main(url, "POST", json.dumps(data))
            print(res1)
    
    
        def test_02(self):
            url = 'http://api.ishugui.com/asg/portal/call/265.do'
            data = {
    
            }
            res2 = self.run.run_main(url, 'POST', data)
    
            print(res2)
    
    
    if __name__ == '__main__':
        unittest.main()
    • 运行test_method模块,查看测试接口,test_02则是错误测试

    3.unittest中assert的使用

    • 首先根据返回的结果字典dict数据中的status状态值来判断测试是否通过或者失败,逻辑很基础就不细说了
    class TestMethod(unittest.TestCase):
        def setUp(self):
            self.run = RunMain()
    
        def test_01(self):
            url = 'http://api.ishugui.com/asg/portal/call/265.do'
            data = {
                "sstoken":"eyJleHAiOjE1Njg1MzgyNTczMzUsImlhdCI6MTU2MDc2MjI1NzMzNSwicHAiOiIxMTQwNTQ1Njg5MDYwMDQ0ODAwQHNvaHUuY29tIiwidGsiOiIwZkNYSHpjTUZzR0dFMEswbVdvUVFCNWVCanpXa0hmWiIsInYiOjB9.SDYkT9FpWrBbko6xRrESN74IXJhzkqQLtijKjGiVrqA",
                "gidinf":"x011060802ff0fd40695d68140002799751474c540b3",
                "ppinf":"2|1560762257|1561971857|bG9naW5pZDowOnx1c2VyaWQ6Mjg6MTE0MDU0NTY4OTA2MDA0NDgwMEBzb2h1LmNvbXxzZXJ2aWNldXNlOjMwOjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMHxjcnQ6MTA6MjAxOS0wNi0xN3xlbXQ6MTowfGFwcGlkOjY6MTEwNjA4fHRydXN0OjE6MXxwYXJ0bmVyaWQ6MTowfHJlbGF0aW9uOjA6fHV1aWQ6MTY6czk1YWIwNDk5NjE3YmJhNnx1aWQ6MTY6czk1YWIwNDk5NjE3YmJhNnx1bmlxbmFtZTowOnw",
                "pprdig":"kaKPdU0WwIdzL58CqxNz5pgMyv23P0-Y5GRnd5ufPlXIGzrk7_7TlIK5XFQiuoqAHNqGVXHCVd4cB1DIkR5yFZ_nExnSjIZbBJWYlMkrsiIjDYqWCvedZRLm8sZqS0WqA0FcKXuSn3Z0gVRus9YpEonNz5wyuWdUqxaSmzlzygY",
                "ppsmu":"1|1560762257|1561971857|dXNlcmlkOjI4OjExNDA1NDU2ODkwNjAwNDQ4MDBAc29odS5jb218dWlkOjA6fHV1aWQ6MDo|byWcaoPqy02s2_9GHLhZFAQ6Ov_GazMPFLrq115HiSTBS9Ijr33a55quRq2Mr1_6ZMruKEk-BYFpShUaMtwRYA"
            }
            res1 = self.run.run_main(url, "POST", json.dumps(data))
            # print(type(res1))
            # print(res1['pub'])
            # print(type(res1['pub']))
            if res1['pub']['status'] == 0:
                print("测试通过")
            else:
                print("测试失败")
            print(res1)
    
    
        def test_02(self):
            url = 'http://api.ishugui.com/asg/portal/call/265.do'
            data = {
    
            }
            res2 = self.run.run_main(url, 'POST', data)
            if res2['pub']['status'] == 0:
                print("测试通过")
            else:
                print("测试失败")
            print(res2)
    
    
    if __name__ == '__main__':
        unittest.main()
    • 运行以上代码,查看结果与预期一样

    • 将if判断代码更换成unittest模块中的assert断言进行判断,这里使用assertEqual方法来判断两个值是否相等,当两个值相等则返回OK,当不相同时返回assertEqual方法msg变量自定义的值
    class TestMethod(unittest.TestCase):
        def setUp(self):
            self.run = RunMain()
    
        def test_01(self):
            url = 'http://api.ishugui.com/asg/portal/call/265.do'
            data = {
                "sstoken":"eyJleHAiOjE1Njg1MzgyNTczMzUsImlhdCI6MTU2MDc2MjI1NzMzNSwicHAiOiIxMTQwNTQ1Njg5MDYwMDQ0ODAwQHNvaHUuY29tIiwidGsiOiIwZkNYSHpjTUZzR0dFMEswbVdvUVFCNWVCanpXa0hmWiIsInYiOjB9.SDYkT9FpWrBbko6xRrESN74IXJhzkqQLtijKjGiVrqA",
                "gidinf":"x011060802ff0fd40695d68140002799751474c540b3",
                "ppinf":"2|1560762257|1561971857|bG9naW5pZDowOnx1c2VyaWQ6Mjg6MTE0MDU0NTY4OTA2MDA0NDgwMEBzb2h1LmNvbXxzZXJ2aWNldXNlOjMwOjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMHxjcnQ6MTA6MjAxOS0wNi0xN3xlbXQ6MTowfGFwcGlkOjY6MTEwNjA4fHRydXN0OjE6MXxwYXJ0bmVyaWQ6MTowfHJlbGF0aW9uOjA6fHV1aWQ6MTY6czk1YWIwNDk5NjE3YmJhNnx1aWQ6MTY6czk1YWIwNDk5NjE3YmJhNnx1bmlxbmFtZTowOnw",
                "pprdig":"kaKPdU0WwIdzL58CqxNz5pgMyv23P0-Y5GRnd5ufPlXIGzrk7_7TlIK5XFQiuoqAHNqGVXHCVd4cB1DIkR5yFZ_nExnSjIZbBJWYlMkrsiIjDYqWCvedZRLm8sZqS0WqA0FcKXuSn3Z0gVRus9YpEonNz5wyuWdUqxaSmzlzygY",
                "ppsmu":"1|1560762257|1561971857|dXNlcmlkOjI4OjExNDA1NDU2ODkwNjAwNDQ4MDBAc29odS5jb218dWlkOjA6fHV1aWQ6MDo|byWcaoPqy02s2_9GHLhZFAQ6Ov_GazMPFLrq115HiSTBS9Ijr33a55quRq2Mr1_6ZMruKEk-BYFpShUaMtwRYA"
            }
            res1 = self.run.run_main(url, "POST", json.dumps(data))
            # print(type(res1))
            # print(res1['pub'])
            # print(type(res1['pub']))
            # if res1['pub']['status'] == 0:
            #     print("测试通过")
            # else:
            #     print("测试失败")
            self.assertEqual(res1['pub']['status'], 0, "测试失败")
            print(res1)
    
    
        def test_02(self):
            url = 'http://api.ishugui.com/asg/portal/call/265.do'
            data = {
    
            }
            res2 = self.run.run_main(url, 'POST', data)
            # if res2['pub']['status'] == 0:
            #     print("测试通过")
            # else:
            #     print("测试失败")
            self.assertEqual(res2['pub']['status'], 0, "测试失败")
            print(res2)
    
    
    if __name__ == '__main__':
        unittest.main()
    • 测试查看结果,断言失败,测试结果如下很清晰

    4.unittest中case的管理及运用

    • 在测试一些接口时,有些接口的返回数据需要在下一个接口进行使用,所以需要定义全局变量,方便每个case都能够得着,当在test_01中定义全局变量userid,然后在test_02中进行打印

    • 在unittest中,是按照字母数字来进行case先后执行顺序的,将test_01改为test_03后,运行代码后,会提示test_02中的userid未定义,原因是程序先去执行了test_02这个case,所以出现该提示是正常的

    • 当在测试代码中有很多case时,我想跳过某个case,则在该case方法上定义unittest的skip方法装饰器,并需要传递此方法名作为实参进行传递

    • 除了在if __name__ == '__main__'中使用unittest.main方法执行所有的case以外,还可以将要测试的case添加到unittest.TestSuite集合中执行想要执行的case,若想要全部都执行则需要一个一个的添加

    5.unittest和HTMLTestRunner结合生成报告(博主这里给大家展现两种)

    第一种:比较新版本的htmltestrunner报告

    • 然后将下载好的whl文件放在你的项目环境的Scripts目录下

    • 最后在Terminal终端或者cmd终端中进入以上目录,执行如下命令即可

    • 安装成功后,即在以下路径中可以找到安装的HTMLTestRunner的包了

    • 在if __name__ == '__main__'中只需要调用HtmlTestRunner模块中的HtmlTestRunner类,向该类传递报告标题参数值即可,其他均默认,需要注意的时启动文件run为当前的py文件,如果是Unittests开头的启动文件,则不会运行if __name__ == '__main__'下的代码,只会执行unittest框架的setUp以及test开头的case代码

    • 运行test_method.py文件,成功在base目录下创建reports目录,并在该目录下生成对应时间的测试报告

    • 打开reports目录下生成的html测试报告,查看测试内容,与预期设定一样,test_02失败test_03成功,说明一下报告中的乱码为中文

    第二种:比较经典版本的htmltestrunner报告

    • 为了方便演示效果,博主在testItems项目目录下,创建base2的模块,将base模块下的demo.py和test_method.py文件拷贝到base2目录下并将test_method.py命令为test_method2.py免得搞混淆,然后在base2目录下新建HTMLTestRunner.py文件用于存放其源码,目录结构如下

    第94行, 将import StringIO修改成import io
    第539行,将self.outputBuffer = StringIO.StringIO()修改成self.outputBuffer = io.StringIO()
    第642行,将if not rmap.has_key(cls):修改成if not cls in rmap:
    第631行,将print >> sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime)修改成print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
    第766行,将uo = o.decode('latin-1')修改成uo = e
    第775行,将ue = e.decode('latin-1')修改成ue = e
    • 在test_method2模块中首先需要从base2模块中去导入HTMLTestRunner文件,然后if __name__ == '__main__'中,需要创建一个文件源,同样是调用HTMLTestRunner模块中的HTMLTestRunner类,不同的是需要将创建的文件源传递给实例属性stream变量

    • 运行test_method2.py,成功在上一级report目录下生成html_report.html报告文件

    • 打开html_report.html测试报告,测试结果与代码设定一致

    六丶mock服务入门到实战

    1.mock简介

    mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,mock是在测试过程中,对于一些不容易构造/获取的对象,创建一个mock对象来模拟对象的行为即就是模拟fiddler返回接口响应数据的一个过程。

    2.mock安装

    • 在终端使用pip进行安装即可

    3.在case中通过底层函数实现mock

    • 在test_method模块中导入mock,然后在test_03函数中通过以下代码设置返回的return_value的值为请求的data数据
    mock_data = mock.Mock(return_value=data)
    print(mock_data)
    • run运行Unittests in test_method.py,打印出Mock id的值

    • 将调用run_main方法的值设定为mock_data,即print(res1)则表示打印请求的data数据的值,因为res1的数据不再是接口返回的响应数据,则arrest断言是会提示报错的,这是正常的

    4.重构封装mock服务

    • 在base目录下创建mock_demo.py文件,构造一个mock_test方法,该方法就是将test_03方法中self.run.run_main = mock.Mock(return_value=data) 和 res1 = self.run.run_main(url, "POST", json.dumps(data))方法的调用进行了封装成为test_02和test_03方法通用的一个方法,上一步骤中的代码mock_data = mock.Mock(return_value=data) 和self.run.run_main = mock_data,即就相当于self.run.run_main = mock.Mock(return_value=data)而已,都是python基本的调用封装基础知识,mock_demo.py中的代码如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/20 16:26'
    from mock import mock
    import json
    
    def mock_test(mock_method, request_data, url, method, response_data):
        """
        :param mock_method:
        :param request_data:
        :param url:
        :param method:
        :param response_data:
        :return: res
        """
        mock_method = mock.Mock(return_value=response_data)
        print('mock_method:', mock_method)
        res = mock_method(url, method, json.dumps(request_data))
        return res
    • 那么在test_03方法中,如下进行调用即可
    res1 = mock_test(self.run.run_main, data, url, 'POST', 'ssssssss')
    print('res1:', res1)
    • 运行Unittests in test_method.py,查看运行结果和博主设定一样成功返回自定义的response_data数据

    七丶接口自动化框架设计到开发

    1.如何设计一个接口自动化测试框架

    根据接口地址丶接口类型丶请求数据丶预期结果来进行设计,对于需要登录后才能进行操作的接口那么则需要进行header cookie等数据的传递,自动化测试的难点就是数据依赖。

    2.python操作excel获得内容

    • 首先python操作excel,需要安装两个包,分别是xlrd和xlwt这两个库,xlrd这个库是负责读取excel数据的,而xlwt库是负责向excel写入数据的

    • 在项目目录下创建utils工具包,在该包下创建op_excel.py文件,在该文件中通过导入xlrd包,对excel表的数据进行读取操作

    3.重构操作excel函数

    • 根据上一步骤读取excel表的内容代码后,进行了一个简单的封装,提高代码的通用性,过程相当的简单,实现代码如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/20 17:33'
    import xlrd
    
    data = xlrd.open_workbook("../test_data/rs.xls")
    tables = data.sheets()[0]  # 获取表格数据对象
    print(tables.nrows) # 打印表格行数
    print(tables.cell_value(0,0))  # 打印excel表格数据,需要传递数据所在的坐标(x,y)
    print(tables.cell_value(0,1))
    print("*"*50+"封装前后数据对比"+"*"*50)
    
    
    class operationExcel(object):
        def __init__(self, file_path="../test_data/rs.xls", sheet_id=0):
            self.file_path = file_path
            self.sheet_id = sheet_id
            self.data = self.get_data()
    
        def get_data(self):
            data = xlrd.open_workbook(self.file_path)
            tables = data.sheets()[self.sheet_id]
            return tables
    
        def get_rows(self):
            """获取单元格的排数"""
            return self.data.nrows
    
        def get_cell_value(self, x=0, y=0):
            """获取某个单元格的数据"""
            return self.data.cell_value(x, y)
    
    
    if __name__ == '__main__':
        print(operationExcel().get_rows())
        print(operationExcel().get_cell_value())
        print(operationExcel().get_cell_value(0,1))
    • 运行op_excel.py文件后,结果与封装之前代码结果一致,表示重构封装代码成功

    4.学习操作json文件

    • 自定义一个登录的json文件名为login.json,文件内容如下,存放在test_data目录下

    • 在utils工具包下创建op_json.py文件,在文件中对login.json文件内容进行读取操作,代码如下

    5.重构json工具类

    • 将上一步操作json的代码进行封装
    class operationJson(object):
        def __init__(self, file_path="../test_data/login.json"):
            self.file_path = file_path
            self.data = self.get_data()
    
        def get_data(self):
            with open(self.file_path) as f:
                data = json.load(f)
                return data
    
        def get_key_words(self, key=None):
            if key:
                return self.data[key]
            else:
                return self.data
    
    
    if __name__ == '__main__':
        print(operationJson().get_key_words())
        print(operationJson().get_key_words("login"))
        print(operationJson().get_key_words("login")['username'])
    • 运行op_json.py文件,结果与封装之前代码结果一致,表示重构封装代码成功

    6.封装获取常量方法

    • 首先打开excel表格,查看需要获取的字段有哪些

    • 对excel表的字段进行获取,在项目目录下创建名为data的python包,在该包下创建data_conf.py,代码就是简单的获取对应的变量值,具体如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/21 9:29'
    
    
    class global_var:
        id = '0'  # id
        module = '1'  # 模块
        url = '2'  # url
        run = '3'  # 是否运行
        request_type = '4'  # 请求类型
        request_header = '5'  # 是否携带header
        case_depend = '6'  # case依赖
        response_data_depend = '7'  # 依赖的返回数据
        data_depend = '8'  #  数据依赖
        request_data = '9'  # 请求数据
        expect_result = '10'  # 预期结果
        reality_result = '11'  # 实际结果
    
    
    def get_id():
        return global_var.id
    
    def get_module():
        return global_var.module
    
    def get_url():
        return global_var.url
    
    def get_run():
        return global_var.run
    
    def get_request_type():
        return global_var.request_type
    
    def get_request_header():
        return global_var.request_header
    
    def get_case_depend():
        return global_var.case_depend
    
    def get_response_data_depend():
        return global_var.response_data_depend
    
    def get_data_depend():
        return global_var.data_depend
    
    def get_request_data():
        return global_var.request_data
    
    def get_expect_result():
        return global_var.expect_result
    
    def get_reality_result():
        return global_var.reality_result

    7.封装获取接口数据

    • 在data目录下创建data_get.py文件,在该文件中对excel表数据以及json数据结合上一步封装的常量方法整合后的实现,代码如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/21 10:01'
    from utils.op_excel import operationExcel
    from utils.op_json import operationJson
    from data import data_conf
    
    class getData(object):
        def __init__(self):
            self.op_excel = operationExcel()
    
        def get_case_lines(self):
            """获取表格行数"""
            return self.op_excel.get_rows()
    
        def get_is_run(self, x):
            """获取case是否运行"""
            flag = None
            y = data_conf.get_run()
            run_value = self.op_excel.get_cell_value(x, y)
            if run_value == 'yes':
                flag = True
            else:
                flag = False
            return flag
    
        def get_is_header(self, x):
            """是否携带header"""
            y = data_conf.get_request_header()
            header = self.op_excel.get_cell_value(x, y)
            if header == 'yes':
                return data_conf.get_header_value()
            else:
                return None
    
        def get_request_method(self, x):
            """获取请求方式"""
            y = data_conf.get_request_type()
            request_method = self.op_excel.get_cell_value(x, y)
            return request_method
    
        def get_request_url(self, x):
            """获取请求地址"""
            y = data_conf.get_url()
            request_url = self.op_excel.get_cell_value(x, y)
            return request_url
    
        def get_request_data(self, x):
            """获取请求数据"""
            y = data_conf.get_request_data()
            request_data = self.op_excel.get_cell_value(x, y)
            if request_data == '':
                return None
            return request_data
    
        def get_data_for_json(self, x):
            """通过excel中的关键字去获取json数据"""
            op_json = operationJson()
            data = op_json.get_key_words(self.get_request_data(x))
            return data
    
        def get_expect_data(self, x):
            """获取预期结果数据"""
            y = data_conf.get_expect_result()
            expect_data = self.op_excel.get_cell_value(x, y)
            if expect_data == '':
                return None
            return expect_data

    8.post、get基类的封装

    • 在base包下创建run_method.py文件,在文件中重新编写对get丶post请求方式的代码封装,具体如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/21 11:19'
    import requests
    
    
    class RunMain(object):
    
        def get_main(self, url, data=None, header=None):
            res = None
            if header is not None:
                res = requests.get(url=url, data=data, headers=header).json()
            else:
                res = requests.get(url=url, data=data).json()
            return res
    
        def post_main(self, url, data, header=None):
            res = None
            if header is not None:
                res = requests.post(url=url, data=data, headers=header).json()
            else:
                res = requests.post(url=url, data=data).json()
            return res
    
    
        def run_main(self, url, method, data=None, header=None):
            res = None
            if method.lower() == 'post':
                res = self.post_main(url, data, header)
            elif method.lower() == 'get':
                res = self.get_main(url, data, header)
            else:
                return "what ?????"
            return res

    9.主流程封装及错误解决调试

    • 首先在testItems项目目录下新建一个名为main的python包,在该包下创建名为run_test的py文件,该文件为主程序启动文件,代码的逻辑就是将前面封装的方法进行了调用核心就是读取excel表的数据,通过读取到的数据,发送请求,其中包括某一些变量的判断,根据该判断然后到json数据中获取请求的数据,最后就这么的简单,代码如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/21 11:57'
    from base.run_method import RunMain
    from data.data_get import getData
    
    
    class RunTest(object):
        def __init__(self):
            self.runmain = RunMain()
            self.data = getData()
    
        def run(self):
            res = None
            row_counts = self.data.get_case_lines()  # 获取excel表格行数
            # print(row_counts) 5
            for row_count in range(1, row_counts):
                # print(row_count) 1,2,3,4
                url = self.data.get_request_url(row_count)  # y行不变遍历获取x列的请求地址
                method = self.data.get_request_method(row_count)  # y行不变遍历获取x列的请求方式
                is_run = self.data.get_is_run(row_count)  # y行不变遍历获取x列的是否运行
                data = self.data.get_data_for_json(row_count)  # y行不变遍历获取x列的请求数据,这里面时三次调用,依次分别是get_data_for_json丶get_key_words丶get_request_data
                header = self.data.get_is_header(row_count)
                print('url:', url)
                print('method:', method)
                print('is_run:', is_run)
                print('data:', data)
                print('header:', header)
    
                if is_run:
                    res = self.runmain.run_main(url,method,data,header)
                    print("*"*60+"分割线"+"*"*60)
            return res
    
    
    if __name__ == '__main__':
        print('res:', RunTest().run())
    • 运行run_test,成功的将excel以及json数据正确打印出来,返回res服务器返回结果,需要说明的是excel表中的所有数据都不是真实存在的,包括json文档数据也是,这里主要是测试整个框架的正确性读取excel以及json文档数据,并正确的发送请求获得相应数据

    • 运行结果出现红色的内容,是由requests模块发送请求的安全请求警告,如不想显示此警告,可以在run_method.py发送请求核心代码进行禁用,禁用代码如下

    • 重新运行run_test,安全请求警告不再显示

    • 根据代码运行结果,对比excel表以及json数据文档内容,数据正确无误

    10. 返回数据格式处理以及调错

    • 为了测试返回的接口的响应数据,博主这里在excel文档以及json文档中添加了一条数据

    • 因为在excel文档中小说的接口不携带header所以在向接口发送请求数据核心代码块,进行了如下修改,因为在excel文档中的最后一个接口时真实的,所以只需要对最后一个接口url返回的字典类型的响应数据进行转换成json格式的数据,并按照关键字进行排序

    • 运行run_test,在最后一个接口中成功打印出我们想要的数据

    11.获取接口返回状态

    • 在发送请求数据核心代码中,进行打印返回的状态码status_code即可,最后一个接口比较特殊,返回的响应数据中没有status_code,所以需要对返回的json数据中的status进行判断,并向其返回数据中添加我们所要的status_code的值

    • 运行代码,当返回的状态码为404表示接口不存在,只要是存在响应数据,则status_code为200,必须说明一点的就是status_code为200不一定表示接口存在,有些大型网站会对其域名下不存在的接口返回200的错误页面显示,所以在测试文档中会体现预期结果和实际结果两项数据需要一致才能表示测试通过

    12.通过预期结果判断case是否执行成功

    • 进行接下来的测试,博主这里重新准备了另一个excel表来进行测试,需要对json文件中的数据进行添加,在excel表Book-05中的请求数据book5关键字对应的json文件的数据故意为空,可以对测试结果有一个对比

    • 在数据获取核心类中定义了一个方法来获取excel表模块字段的数据

    • 回过头在启动文件中获取模块名预期结果并进行打印

    • 运行启动文件,查看运行结果

    • 在utils目录下,创建common_util.py文件,在该文件代码中通过启动文件传递过来的数据来判断excel表预期结果数据的status状态码与res结果中的status状态码是否一致,一致表示测试通过,不一致则失败,代码如下
    # -*- coding: utf-8 -*-
    __author__ = 'cdtaogang'
    __date__ = '2019/6/21 18:43'
    import json
    
    class CommonUtil(object):
        def is_contains(self, expect, reality):
            flag = None
            reality = json.loads(reality)
            expect = json.loads(expect)
            if expect['status'] == reality['pub']['status']:
                flag = True
            else:
                flag = False
            return flag
    • 在启动文件中需要注释掉res响应数据,利于查看测试结果,还需要在启动文件调用is_contains方法来根据其返回值判断测试是否通过

    • 运行启动文件,查看测试结果

    13.将测试结果写入到excel中

    • 首先在op_excel.py中定义一个方法,该方法实现读取excel的数据,并进行copy复制,然后再write方法将数据写入到坐标位置

    • 然后在data_get.py中需要定义一个方法,在该方法中核心逻辑为获取y坐标的值

    • 最后在启动文件中,调用data_get模块中的write_reality_data方法,并将剩余的x坐标的值以及data数据传递给最终的核心方法write_reality_result_data来完成对excel表中的实际结果数据的写入

    • 将excel表进行关闭后,运行启动文件,再次打开excel表,实际结果数据写入正确,之所以需要关闭excel是避免提示提示错误,无法写入保存数据

     

    展开全文
  • Python 接口自动化框架(第一版)简介从业务测试的角度看,已经不再着眼于功能、性能测试了,自动化框架的搭建旨在提升工作效率。从项目的执行有效性来看,接口自动化已经比UI自动化更实用了,维护成本也更低。当然,...
  • ——————·今天距2021年260天·——————这是ITester软件测试小栈第112次推文在上一篇Python接口自动化测试系列文章:Python接口自动化-requests模块之post请求,介绍了post源码,data、json参数应用场景及...
  • Python 接口自动化

    2020-02-09 21:18:44
    python环境搭建 第三方库 requests安装 pip install requests ,网烂时可能安装失败,嗯… pip安装第三方库提示版本较低时需要更新pip的版本 命令:python -m pip install --upgrade pip 查看安装的第三方库:pip ...
  • Python接口自动化

    千次阅读 2018-07-20 11:38:30
    公司内部的一个接口自动化使用框架(非使用工具)  工作原理: 测试用例在excel上编辑,使用第三方库xlrd,读取表格sheet和内容,sheetName对应模块名,Jenkins集成服务发现服务moduleName查找对应表单,运用第三...
  • python接口自动化测试

    2018-09-21 11:07:01
    python接口自动化测试教程,主要内容如下:基本原理,网络接口,json处理,网络请求,自动化
  • 之前小编写过Rest-assuert接口测试框架,它是基于java的,那么怎么轻轻松松玩转python接口自动化测试呢?今天小编就写写如何使用python Request进行接口自动测试。学习任何一门技术一门语言,首先要知道从哪些学起,...
  • python接口自动化测试框架---包括请求的封装、数据库操作、多断言、ddt数据驱动、多种请求方式等
  • 本节开始,开始介绍python接口自动化测试,首先需要搭建python开发环境,到https://www.python.org/下载python版本直接安装就以了,建议 下载python2.7.11版本,当然,也是可以下载python最新版本的。 接口测试是...
  • python接口自动化02集

    2018-09-22 22:29:37
    python接口自动化项目实战视频02集
  • postman接口用例转化为python自动化测试用例postman接口用例转化为python自动化测试用例(二)postman接口用例转化为python自动化测试用例(三)python自动化测试用例之----引入ddt数据驱动python接口自动化测试完毕-...
  • python接口自动化03集

    2018-09-22 22:32:09
    python接口自动化项目实战视频03集 java1234
  • 本书主要介绍如何用Python实现接口自动化测试。全书主要内容包括接口基础、接口手工测试、编程前的准备、用Python处理MySQL数据库、用Python发送HTTP请求、用Python处理HTTP返回包、用Python导出测试数据、接口自动...
  • python接口自动化_YY.pdf

    2019-08-07 09:36:30
    python接口自动化测试教程,适合有Python基础的同学进行接口自动化测试
  • 原标题:Python接口自动化——Web接口1.2.1 web接口的概念这里用一个浏览器调试工具捕捉课程管理页面请求作为例子: 当请求页面时,服务器会返回资源,将协议看做是路的话,http可以看做高速公路,soap看做铁路传输...
  • 导读:有许多小伙伴关注Python接口自动化测试框架实战 从设计到开发这一问题。关于此IT猫也是收集了很多材料,加上自己的理解,分享给大家。下面就来一起看一看IT猫收集到的关于《Python接口自动化测试框架实战 从...
  • 我们在使用python进行接口自动化测试过程中,可能会用到httplib或者requests或者urllib2库,那么怎么模拟http的请求呢,今天小编大概写几个例子吧.def httpget(url):try:conn = httplib.HTTPConnection(url)conn....
  • python接口自动化测试是PDF文档形式,文档中的实现以Python语言为基础,进行HTTP接口自动化框架,模块包括Excel进行参数化,读取配置文件,读取测试用例,执行测试用例,记录...是学习python接口自动化测试的绝佳文档。
  • VOL 117292020-04今天距2020年246天这是ITester软件测试小栈第117次推文点击上方蓝字“ITester软件测试小栈“关注我,每周...本文4829字,阅读约需13分钟在上一篇Python接口自动化测试系列文章:Python接口自动化之u...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,195
精华内容 3,278
关键字:

python接口自动化

python 订阅