簡體   English   中英

你如何正確地將文件解析的單元測試與pytest集成?

[英]How do you properly integrate unit tests for file parsing with pytest?

我正在嘗試用pytest測試文件解析。 我有一個目錄樹,對我的項目看起來像這樣:

project
    project/
        cool_code.py
    setup.py
    setup.cfg
    test/
        test_read_files.py
        test_files/
            data_file1.txt
            data_file2.txt

我的setup.py文件看起來像這樣:

from setuptools import setup

setup(
    name           = 'project',
    description    = 'The coolest project ever!',
    setup_requires = ['pytest-runner'],
    tests_require  = ['pytest'],
    )

我的setup.cfg文件看起來像這樣:

[aliases]
test=pytest

我用pytest編寫了幾個單元測試來驗證文件是否正確讀取。 當我從“ test ”目錄中運行pytest時,它們工作正常。 但是,如果我從項目目錄中執行以下任何操作,測試將失敗,因為它們無法在test_files中找到數據文件:

>> py.test
>> python setup.py pytest

測試似乎對執行pytest的目錄很敏感。

當我從測試目錄或項目根目錄調用它時,如何通過pytest單元測試來發現“data_files”中的文件進行解析?

一種解決方案是使用指向測試目錄的路徑定義rootdir fixture,並引用與此相關的所有數據文件。 這可以通過使用如下代碼創建test/conftest.py (如果尚未創建)來完成:

import os
import pytest

@pytest.fixture
def rootdir():
    return os.path.dirname(os.path.abspath(__file__))

然后在測試中使用os.path.join來獲取測試文件的絕對路徑:

import os

def test_read_favorite_color(rootdir):
    test_file = os.path.join(rootdir, 'test_files/favorite_color.csv')
    data = read_favorite_color(test_file)
    # ...

一種解決方案是嘗試多個路徑來查找文件。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from coolprogram import *
import os


def test_file_locations():
    """Possible locations where test data could be found."""

    return(['./test_files',
            './tests/test_files',
            ])


def find_file(filename):
    """ Searches for a data file to use in tests """

    for location in test_file_locations():
        filepath = os.path.join(location, filename)
        if os.path.exists(filepath):
            return(filepath)
    raise IOError('Could not find test file.')


def test_read_favorite_color():
    """ Test that favorite color is read properly """

    filename = 'favorite_color.csv'
    test_file = find_file(filename)

    data = read_favorite_color(test_file)
    assert(data['first_name'][1] == 'King')
    assert(data['last_name'][1] == 'Arthur')
    assert(data['correct_answers'][1] == 2)
    assert(data['cross_bridge'][1] == True)
    assert(data['favorite_color'][1] == 'green')

一種方法是將命令名和自定義命令類的字典傳遞給setup函數的cmdclass參數。

另一種方式就像這里一樣,貼在這里以供快速參考。

pytest-runner將在每次調用setup.py時自行安裝。 在某些情況下,這會導致調用setup.py的延遲,該調用永遠不會調用pytest-runner。 為了避免這種意外情況,請考慮在調用pytest時僅需要pytest-runner:

pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv)

pytest_runner = ['pytest-runner'] if needs_pytest else []

# ...

setup(
    #...
    setup_requires=[
        #... (other setup requirements)
    ] + pytest_runner,
)

確保您在測試模塊中讀取的所有數據都與setup.py目錄的位置相關。

在OP的情況下,數據文件路徑將是test/test_files/data_file1.txt ,我做了相同結構的項目,並讀取data_file1.txt在一些文本,它為我工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM