如何在 Python 的测试中获取文件?
How can I get files within the tests in Python?
我有以下包结构:
.
├── my_app
│ ├── app.py
│ ├── cli.py
│ ├── db.py
│ └── __init__.py
├── setup.py
├── tests
│ ├── data
│ │ └── foobar.gz
│ ├── test_app.py
│ └── test_database.py
└── tox.ini
在 test_app.py
内,我这样做:
import pkg_resources
path = '../tests/data/foobar.gz'
full_path = pkg_resources.resource_filename(__name__, path)
现在我看到了消息:
/usr/local/lib/python3.7/site-packages/pkg_resources/__init__.py:1145:
DeprecationWarning: Use of .. or absolute path in a resource path
is not allowed and will raise exceptions in a future release.
self, resource_name
我应该怎么做?
(我也可以更改包的结构,但我想将测试数据保留在测试中 - 运行 应用程序不需要)
尝试os模块
import os.path
source_folder = os.getcwd()
path = os.path.join(source_folder, 'data/foobar.gz')
要获取相对于脚本目录的路径,请尝试使用脚本位置本身:
import sys
print(sys.argv[0])
您可以使用 os.path.dirname()
:
获取包含脚本的目录
import os
import sys
print(os.path.dirname(sys.argv[0]))
然后,os.path.join()
可能有助于创建任意路径:
import os
import sys
print(os.path.join(os.path.dirname(sys.argv[0]), "some_subdir"))
HTH!
要在将测试文件名传递给 pkg_resources
时获取测试资源,您需要使用文件中的路径进行测试,例如:
import pkg_resources
path = 'data/foobar.gz'
full_path = pkg_resources.resource_filename(__name__, path)
有了pytest,我也在conftest.py
中使用了这个模式:
@pytest.fixture('session')
def test_data_dir():
return os.path.join(os.path.dirname(__file__), 'data')
我可以使用 os.path.join()
轻松获取任何测试数据。
这是我使用 pytest
解决这个问题的方法。将以下夹具添加到 conftest.py
。通过将 resource_file
指定为测试的参数,从测试中请求此固定装置。当使用文件名调用此夹具时(例如 resource_file("expected_doc.html")
它将生成形式为 resources/path/to/test/test_file_name/test_name/expected_doc.html
的文件夹结构并创建资源文件(如果它尚不存在)(便于查找文件应该去的地方) . 最后,调用将 return 文件的路径。此解决方案的优点是您不需要在测试中进行任何路径修改。
夹具:
@fixture(scope="function")
def resource_file(request):
test_root = os.path.dirname(os.path.dirname(__file__))
relative_test_file_location = str(request.fspath).removeprefix(test_root).removesuffix(".py").removeprefix("/")
test_resource_dir = os.path.join(test_root, "resources", relative_test_file_location, request.function.__name__)
def resolve_and_create_if_missing(filename):
final_path = os.path.join(test_resource_dir, filename)
if not os.path.exists(final_path):
# creating the dir
os.makedirs(test_resource_dir, exist_ok=True)
# creating the file
open(final_path, "a").close()
return final_path
return resolve_and_create_if_missing
示例测试:
def test_something(resource_file):
resource_filename = resource_file("expected_doc.html")
# use the file via resource_filename
我有以下包结构:
.
├── my_app
│ ├── app.py
│ ├── cli.py
│ ├── db.py
│ └── __init__.py
├── setup.py
├── tests
│ ├── data
│ │ └── foobar.gz
│ ├── test_app.py
│ └── test_database.py
└── tox.ini
在 test_app.py
内,我这样做:
import pkg_resources
path = '../tests/data/foobar.gz'
full_path = pkg_resources.resource_filename(__name__, path)
现在我看到了消息:
/usr/local/lib/python3.7/site-packages/pkg_resources/__init__.py:1145: DeprecationWarning: Use of .. or absolute path in a resource path is not allowed and will raise exceptions in a future release. self, resource_name
我应该怎么做?
(我也可以更改包的结构,但我想将测试数据保留在测试中 - 运行 应用程序不需要)
尝试os模块
import os.path
source_folder = os.getcwd()
path = os.path.join(source_folder, 'data/foobar.gz')
要获取相对于脚本目录的路径,请尝试使用脚本位置本身:
import sys
print(sys.argv[0])
您可以使用 os.path.dirname()
:
import os
import sys
print(os.path.dirname(sys.argv[0]))
然后,os.path.join()
可能有助于创建任意路径:
import os
import sys
print(os.path.join(os.path.dirname(sys.argv[0]), "some_subdir"))
HTH!
要在将测试文件名传递给 pkg_resources
时获取测试资源,您需要使用文件中的路径进行测试,例如:
import pkg_resources
path = 'data/foobar.gz'
full_path = pkg_resources.resource_filename(__name__, path)
有了pytest,我也在conftest.py
中使用了这个模式:
@pytest.fixture('session')
def test_data_dir():
return os.path.join(os.path.dirname(__file__), 'data')
我可以使用 os.path.join()
轻松获取任何测试数据。
这是我使用 pytest
解决这个问题的方法。将以下夹具添加到 conftest.py
。通过将 resource_file
指定为测试的参数,从测试中请求此固定装置。当使用文件名调用此夹具时(例如 resource_file("expected_doc.html")
它将生成形式为 resources/path/to/test/test_file_name/test_name/expected_doc.html
的文件夹结构并创建资源文件(如果它尚不存在)(便于查找文件应该去的地方) . 最后,调用将 return 文件的路径。此解决方案的优点是您不需要在测试中进行任何路径修改。
夹具:
@fixture(scope="function")
def resource_file(request):
test_root = os.path.dirname(os.path.dirname(__file__))
relative_test_file_location = str(request.fspath).removeprefix(test_root).removesuffix(".py").removeprefix("/")
test_resource_dir = os.path.join(test_root, "resources", relative_test_file_location, request.function.__name__)
def resolve_and_create_if_missing(filename):
final_path = os.path.join(test_resource_dir, filename)
if not os.path.exists(final_path):
# creating the dir
os.makedirs(test_resource_dir, exist_ok=True)
# creating the file
open(final_path, "a").close()
return final_path
return resolve_and_create_if_missing
示例测试:
def test_something(resource_file):
resource_filename = resource_file("expected_doc.html")
# use the file via resource_filename