[英]`pytest`: Downloading a test file once, and using it for multiple tests
我正在使用pytest
為我正在開發的 package 運行測試用例。 測試使用我保存為 github 資產的小圖像文件。 下面的代碼工作得很好,但我認為pytest
每次運行新測試時都會下載圖像,這會花費不必要的時間和資源。 我試圖弄清楚如何下載文件一次,然后在測試用例中共享它
這是一些示例代碼。
# -- in conftest.py --
import sys
import pytest
import os
import shutil
import requests
@pytest.fixture(scope="function")
def small_image(tmpdir):
url = 'https://github.com/.../sample_image_small.tif'
r = requests.get(url)
with open(os.path.join(str(tmpdir), 'sample_image_small.tif'), 'wb') as f:
f.write(r.content)
return os.path.join(str(tmpdir), 'sample_image_small.tif')
然后這里有一些非常簡單的測試用例應該能夠共享相同的圖像。
# -- test_package.py --
import pytest
import os
@pytest.mark.usefixtures('small_image')
def test_ispath(small_image, compression):
assert os.path.exists(small_image)
def test_isfile(small_image, compression):
assert os.path.isfile(small_image)
現在我相信pytest
會嘗試自己隔離每個測試,這就是導致重復下載文件的原因。 我試圖設置@pytest.fixture(scope="module")
而不是function
但這會產生奇怪的錯誤:
ScopeMismatch: You tried to access the 'function' scoped fixture 'tmpdir' with a 'module' scoped request object, involved factories
有沒有更好的方法來設置測試,這樣我就不會一遍又一遍地下載文件?
您可以使用相同的代碼,只需自己處理臨時文件,而不是使用tmpdir
夾具(不能在模塊范圍的夾具中使用):
import os
import tempfile
import pytest
import requests
@pytest.fixture(scope="module")
def small_image():
url = 'https://github.com/.../sample_image_small.tif'
r = requests.get(url)
f = tempfile.NamedTemporaryFile(delete=False):
f.write(f.content)
yield f.name
os.remove(f.name)
這將創建文件,返回文件名,並在測試完成后刪除文件。
編輯: @hoefling 的答案顯示了一種更標准的方法,我將把這個留作參考。
首先,事先說明:舊tmpdir
/ tmpdir_factory
固定裝置對的更好替代方法是tmp_path
/ tmp_path_factory
處理pathlib
對象而不是不推薦使用的py.path
,請參閱臨時目錄和文件。
其次,如果您想處理會話范圍(或模塊范圍)的文件, tmp*_factory
固定裝置就是為此而生的。 例子:
@pytest.fixture(scope='session')
def small_image(tmp_path_factory):
img = tmp_path_factory.getbasetemp() / 'sample_image_small.tif'
img.write_bytes(b'spam')
return img
sample_image_small.tif
現在將在每次測試運行時寫入一次。
當然,@MrBean Bremen 在他的回答中建議使用tempfile
並沒有錯,這只是一種替代方法,但僅使用標准pytest
夾具。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.