成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

異步編程 101:如何測(cè)試 async 代碼

sPeng / 3194人閱讀

摘要:整個(gè)事件循環(huán)是在一個(gè)線程里面的,意味著任務(wù)切換更加高效,無(wú)需上下文轉(zhuǎn)換。異步代碼很高效,但是也有很蛋疼的地方,那就是測(cè)試。所以我們得想辦法告訴使用一個(gè)來(lái)運(yùn)行測(cè)試方法。

視頻原文:Strategies for testing Async code - PyCon 2019

同時(shí)參考了:

Testing Asyncio Python Code with Pytest

前面幾篇關(guān)于異步編程的文章:

異步編程 101: 是什么、小試Python asyncio

異步編程 101:Python async await發(fā)展簡(jiǎn)史

異步編程 101:寫(xiě)一個(gè)事件循環(huán)

異步編程 101:asyncio中的 for 循環(huán)

異步編程 101:asyncio 進(jìn)階上篇

異步編程,本質(zhì)上是通過(guò)合作(cooperation)來(lái)達(dá)成并發(fā)效果,也即:需要 wait 的時(shí)候,也就是發(fā)生 IO 的時(shí)候,把控制權(quán)交給主事件循環(huán)。 (yield control when "awaiting" asynchronous results.) 這個(gè)過(guò)程有點(diǎn)像事件循環(huán)完成了操作系統(tǒng)的工作,可以將事件循環(huán)看作是操作系統(tǒng),然后把協(xié)程看作是線程這么來(lái)理解。整個(gè)事件循環(huán)是在一個(gè)線程里面的,意味著任務(wù)切換更加高效,無(wú)需上下文轉(zhuǎn)換。

異步代碼很高效,但是也有很蛋疼的地方,那就是測(cè)試。

0x01 : async 測(cè)試實(shí)例

來(lái)通過(guò)一個(gè)簡(jiǎn)單的例子看一下吧:一個(gè)Cat類,有一個(gè) move 方法,這個(gè)方法是異步的。

然后用 unittest 寫(xiě)一個(gè)測(cè)試類,你能發(fā)現(xiàn)下面代碼的問(wèn)題嗎?

herd(grafield, "forward") 返回的是一個(gè)協(xié)程對(duì)象(coroutine object),如果你不await他,什么也不會(huì)發(fā)生。而coroutine object是 truthy 的,所以assertTrue() 是能夠通過(guò)的。如果你運(yùn)行一下 test,會(huì)看到coroutine herd was nerver awaited的 warning。

下圖這樣調(diào)用await還是不對(duì)的,因?yàn)?b>await關(guān)鍵字只能出現(xiàn)在async函數(shù)里面。

一個(gè)解決方案是加入事件循環(huán):

這能work,但是估計(jì)你也看出來(lái)了,這很麻煩。如果我有多個(gè)方法,難道我需要每個(gè) test方法都加一個(gè)事件循環(huán)嗎?更重要的是,我只是想做一下單元測(cè)試,事件循環(huán)在這個(gè)時(shí)候?qū)嶋H上是一個(gè)底層細(xì)節(jié),我不需要關(guān)心。

在 Python3.7 中,asyncio新增了一個(gè)方法:asyncio.run(),為你隱藏了事件循環(huán)的細(xì)節(jié),所以能夠讓代碼更加簡(jiǎn)潔:

0x02 pytest-asyncio

安裝:pip install pytest-asyncio,這實(shí)際上是pytest的一個(gè)插件。

用法很簡(jiǎn)單,重要的是我們得知道工作原理。之前的代碼問(wèn)題在于,pytest 默認(rèn)的的 runner 會(huì)將所有的函數(shù)當(dāng)作普通函數(shù)處理,而對(duì)于 async 函數(shù), 調(diào)用的時(shí)候返回的是一個(gè) coroutine object。所以我們得想辦法告訴 pytest 使用一個(gè) eventloop 來(lái)運(yùn)行測(cè)試方法。

一種方法是,實(shí)例化一個(gè)eventloop 然后注入到 tests里面,比如:

import asyncio
import pytest

async def say(what, when):
    await asyncio.sleep(when)
    return what

@pytest.fixture
def event_loop():
    loop = asyncio.get_event_loop()
    yield loop
    loop.close()


def test_say(event_loop):
    expected = "This should fail!"
    assert expected == event_loop.run_until_complete(say("Hello!", 0))

這種方法不方便之處在于每次都需要手動(dòng)注入 eventloop,更優(yōu)雅的方法是調(diào)整 test runner,讓它識(shí)別 async 函數(shù),當(dāng)作 asyncio tasks 來(lái)執(zhí)行。

pytest-asyncio完成的功能就是這樣的,它的 API 非常簡(jiǎn)單,你只需要為 async function 添加一個(gè) @pytest.mark.asyncio 修飾器即可:

import pytest
from say import say

@pytest.mark.asyncio
async def test_say():
    assert "Hello!" == await say("Hello!", 0)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/7001.html

相關(guān)文章

  • Python爬蟲(chóng)入門(mén)教程 7-100 蜂鳥(niǎo)網(wǎng)圖片爬取之二

    摘要:蜂鳥(niǎo)網(wǎng)圖片簡(jiǎn)介今天玩點(diǎn)新鮮的,使用一個(gè)新庫(kù),利用它提高咱爬蟲(chóng)的爬取速度。上下文不在提示,自行搜索相關(guān)資料即可創(chuàng)建一個(gè)對(duì)象,然后用該對(duì)象去打開(kāi)網(wǎng)頁(yè)。可以進(jìn)行多項(xiàng)操作,比如等代碼中等待網(wǎng)頁(yè)數(shù)據(jù)返回創(chuàng)建線程,方法負(fù)責(zé)安排執(zhí)行中的任務(wù)。 1. 蜂鳥(niǎo)網(wǎng)圖片-簡(jiǎn)介 今天玩點(diǎn)新鮮的,使用一個(gè)新庫(kù) aiohttp ,利用它提高咱爬蟲(chóng)的爬取速度。 安裝模塊常規(guī)套路 pip install aiohtt...

    z2xy 評(píng)論0 收藏0
  • Python爬蟲(chóng)入門(mén)教程 7-100 蜂鳥(niǎo)網(wǎng)圖片爬取之二

    摘要:蜂鳥(niǎo)網(wǎng)圖片簡(jiǎn)介今天玩點(diǎn)新鮮的,使用一個(gè)新庫(kù),利用它提高咱爬蟲(chóng)的爬取速度。上下文不在提示,自行搜索相關(guān)資料即可創(chuàng)建一個(gè)對(duì)象,然后用該對(duì)象去打開(kāi)網(wǎng)頁(yè)??梢赃M(jìn)行多項(xiàng)操作,比如等代碼中等待網(wǎng)頁(yè)數(shù)據(jù)返回創(chuàng)建線程,方法負(fù)責(zé)安排執(zhí)行中的任務(wù)。 1. 蜂鳥(niǎo)網(wǎng)圖片-簡(jiǎn)介 今天玩點(diǎn)新鮮的,使用一個(gè)新庫(kù) aiohttp ,利用它提高咱爬蟲(chóng)的爬取速度。 安裝模塊常規(guī)套路 pip install aiohtt...

    hufeng 評(píng)論0 收藏0
  • Python爬蟲(chóng)入門(mén)教程 7-100 蜂鳥(niǎo)網(wǎng)圖片爬取之二

    摘要:蜂鳥(niǎo)網(wǎng)圖片簡(jiǎn)介今天玩點(diǎn)新鮮的,使用一個(gè)新庫(kù),利用它提高咱爬蟲(chóng)的爬取速度。上下文不在提示,自行搜索相關(guān)資料即可創(chuàng)建一個(gè)對(duì)象,然后用該對(duì)象去打開(kāi)網(wǎng)頁(yè)??梢赃M(jìn)行多項(xiàng)操作,比如等代碼中等待網(wǎng)頁(yè)數(shù)據(jù)返回創(chuàng)建線程,方法負(fù)責(zé)安排執(zhí)行中的任務(wù)。 1. 蜂鳥(niǎo)網(wǎng)圖片-簡(jiǎn)介 今天玩點(diǎn)新鮮的,使用一個(gè)新庫(kù) aiohttp ,利用它提高咱爬蟲(chóng)的爬取速度。 安裝模塊常規(guī)套路 pip install aiohtt...

    mcterry 評(píng)論0 收藏0
  • js-csp 異步編程的一些簡(jiǎn)單的例子

    摘要:發(fā)現(xiàn)一個(gè)月沒(méi)刷技術(shù)文章了有點(diǎn)慌整理一篇短的用法出來(lái)只包含最基本的用法在里邊最清晰不過(guò)我是在寫(xiě)的版本的實(shí)現(xiàn)包含異步用法會(huì)更繁瑣一些但是也值得看看我相信普及之前還是一個(gè)很有意思的選擇我的代碼寫(xiě)的是可以自動(dòng)腦補(bǔ)圓括號(hào)花括號(hào)上去注意包含的函數(shù)自動(dòng) 發(fā)現(xiàn)一個(gè)月沒(méi)刷技術(shù)文章了, 有點(diǎn)慌, 整理一篇短的 CSP 用法出來(lái),只包含最基本的用法, 在 Go 里邊最清晰, 不過(guò)我是在 Clojure 寫(xiě)的...

    curried 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<