繁体   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