zoukankan      html  css  js  c++  java
  • 使用python asyncio+aiohttp做接口测试(TODO)

    线程是操作系统层面的“并行”, 协程是应用程序层面的“并行”。

    协程本质上就是:提供一个环境,保存一些需要等待的任务,当这些任务可以执行(等待结束)的时候,能够执行。再等待的过程中,程序可以执行别的任务。

    asyncio是python3.4版本引入到标准库因此要注意python版本

    我的python环境

    Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Inte
    l)] on win32
    Type "help", "copyright", "credits" or "license" for more information.

    平时做接口测试都是使用requests,但是requests是同步的库,如果想异步的话需要引入aiohttp

    • 安装aiohttp模块 
    pip install aiohttp
    • 关键字async 、await(python3.5开始引入)

    async 是明确将函数声明为协程的关键字,函数执行也会返回一个协程对象(async关键字可以定义一个协程对象,被async修饰的函数变成了一个协程对象而不是一个普通的函数)(python3.4是使用装饰器@asyncio.coroutine)

    await  在协程函数内部,可以在某个表达式之前使用这个关键字来挂起协程,执行别的协程(python3.4是使用yield from)

    直接调用异步函数不会返回结果,而是返回一个coroutine对象

    可以通过await语法来挂起自身的协程,并等待另一个协程完成直到返回结果

    • 关键字async with(参考whith的作用:https://www.cnblogs.com/DswCnblog/p/6126588.html)

    Aiohttp推荐使用ClientSession作为主要的接口发起请求。ClientSession允许在多个请求之间保存cookie以及相关对象信息。Session(会话)在使用完毕之后需要关闭,关闭Session是另一个异步操作,所以每次你都需要使用async with关键字,这样就不需要单独再去关闭了

    import asyncio
    import time
    from aiohttp import ClientSession
    #async英文为异步的+io操作
    url = 'http://127.0.0.1:505?c=1&d=2'
    #url = 'http://10.21.21.248:8002/sr_sys/v1/user/list'
    
    now = lambda: time.time()
    async def req_get(url):
        async with ClientSession() as session:
            async with session.get(url) as response:
                response = await response.read()
                #print(response,type(response))
    async def req_post(url):
        async with ClientSession() as session:
            async with session.post(url) as response:
                response = await response.read()
    
    if __name__ == '__main__':
        start = now()
        #方法可以创建一个事件循环,asyncio.BaseEventLoop。
        #协程对象不能直接运行,在注册事件循环的时候,其实是run_until_complete方法将协程包装成为了一个任务(task)对象。
        #所谓task对象是Future类的子类。保存了协程运行后的状态,用于未来获取协程的结果
        loop = asyncio.get_event_loop()
        #需要处理的任务
        tasks = [asyncio.ensure_future(req_get(url)) for i in range(512)]
        #tasks = [loop.create_task(req_get(url)) for i in range(512)] 确定参数是协程的时候可以用这个
        #将协程注册到事件循环,并启动事件循环
        #loop.run_until_complete(asyncio.gather(*tasks))
        loop.run_until_complete(asyncio.wait(tasks))
        for task in tasks:
            print(task)
            print('Task ret: ', task.result())
        print('TIME: ', now() - start)

    aiohttp库的一些方法具体使用可以参考:https://blog.csdn.net/biheyu828/article/details/87896507

    ①相关概念的理解: 

    • event_loop 事件循环:程序开启一个无限的循环,程序员会把一些函数注册到事件循环上。当满足事件发生的时候,调用相应的协程函数。
    • coroutine 协程:协程对象,指一个使用async关键字定义的函数,它的调用不会立即执行函数,而是会返回一个协程对象。协程对象需要注册到事件循环,由事件循环调用。
    • task 任务:一个协程对象就是一个原生可以挂起的函数,任务则是对协程进一步封装,其中包含任务的各种状态。
    • future: 代表将来执行或没有执行的任务的结果。它和task上没有本质的区别
    • async/await 关键字:python3.5 用于定义协程的关键字,async定义一个协程,await用于挂起阻塞的异步调用接口。

    耗时的操作一般是一些IO操作,例如网络请求,文件读取等。我们可以使用asyncio.sleep函数来模拟IO操作。协程的目的也是让这些IO操作异步化。

    ②ensure_future()  asyncio.BaseEventLoop.create_task asyncio.Task三者的区别和取舍:

    ensure_future 除了接受 coroutine 作为参数,还接受 future 作为参数。

    看 ensure_future 的代码,会发现 ensure_future 内部在某些条件下会调用 create_task,综上所述:

    • encure_future: 最高层的函数,推荐使用,除了接受coroutine 作为参数,还接受 future 作为参数,返回一个task
    • create_task: 在确定参数是 coroutine 的情况下可以使用,因为它只接受协程程序。
    • Task: 可能很多时候也可以工作,但真的没有使用的理由!

    参考文档:

       https://www.sohu.com/a/74542662_218897

       https://www.cnblogs.com/shenh/p/9090586.html

       https://blog.csdn.net/hanglinux/article/details/75068400

       https://www.cnblogs.com/zhaof/p/8490045.html

    aiohttp

  • 相关阅读:
    一线架构师实践指南第三编阅读笔记
    学习七
    《信息领域热词分析》,如何设计编码实现六种质量属性战术
    学习六
    一线架构师实践指南第二部分阅读笔记
    学习五
    echarts实现省市区地图下钻
    python提取文本关键词
    后缀自动机复习笔记
    bzoj 1552
  • 原文地址:https://www.cnblogs.com/yy-cola/p/9532007.html
Copyright © 2011-2022 走看看