pytest-data-loader 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytest_data_loader-0.1.0/.github/dependabot.yml +8 -0
- pytest_data_loader-0.1.0/.github/workflows/release.yml +55 -0
- pytest_data_loader-0.1.0/.github/workflows/test.yml +73 -0
- pytest_data_loader-0.1.0/.gitignore +165 -0
- pytest_data_loader-0.1.0/.pre-commit-config.yaml +29 -0
- pytest_data_loader-0.1.0/PKG-INFO +252 -0
- pytest_data_loader-0.1.0/README.md +216 -0
- pytest_data_loader-0.1.0/pyproject.toml +114 -0
- pytest_data_loader-0.1.0/pytest.ini +6 -0
- pytest_data_loader-0.1.0/setup.cfg +4 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/__init__.py +9 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/compat.py +16 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/constants.py +2 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/errors.py +1 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/loaders/__init__.py +1 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/loaders/impl.py +342 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/loaders/loaders.py +270 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/plugin.py +131 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/py.typed +0 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/types.py +132 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader/utils.py +133 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader.egg-info/PKG-INFO +252 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader.egg-info/SOURCES.txt +62 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader.egg-info/dependency_links.txt +1 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader.egg-info/entry_points.txt +2 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader.egg-info/requires.txt +17 -0
- pytest_data_loader-0.1.0/src/pytest_data_loader.egg-info/top_level.txt +1 -0
- pytest_data_loader-0.1.0/tests/__init__.py +0 -0
- pytest_data_loader-0.1.0/tests/conftest.py +7 -0
- pytest_data_loader-0.1.0/tests/data/dir/.hidden_file +1 -0
- pytest_data_loader-0.1.0/tests/data/dir/0.txt +1 -0
- pytest_data_loader-0.1.0/tests/data/dir/1.txt +1 -0
- pytest_data_loader-0.1.0/tests/data/dir/2.txt +1 -0
- pytest_data_loader-0.1.0/tests/data/empty/.gitkeep +0 -0
- pytest_data_loader-0.1.0/tests/data/images/image1.jpg +0 -0
- pytest_data_loader-0.1.0/tests/data/images/image2.jpg +0 -0
- pytest_data_loader-0.1.0/tests/data/json_array.json +5 -0
- pytest_data_loader-0.1.0/tests/data/json_nested_object.json +12 -0
- pytest_data_loader-0.1.0/tests/data/json_object.json +5 -0
- pytest_data_loader-0.1.0/tests/data/json_scalar.json +1 -0
- pytest_data_loader-0.1.0/tests/data/text.txt +3 -0
- pytest_data_loader-0.1.0/tests/tests_loader/__init__.py +0 -0
- pytest_data_loader-0.1.0/tests/tests_loader/helper.py +20 -0
- pytest_data_loader-0.1.0/tests/tests_loader/test_load_file.py +101 -0
- pytest_data_loader-0.1.0/tests/tests_loader/test_parametrize_dir.py +51 -0
- pytest_data_loader-0.1.0/tests/tests_loader/test_parametrize_file.py +211 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/__init__.py +0 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/conftest.py +126 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/helper.py +176 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/test_data_path.py +84 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/test_ini_options.py +72 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/test_lazy_loading.py +66 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/test_loader_args.py +38 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/test_loader_func_validation.py +237 -0
- pytest_data_loader-0.1.0/tests/tests_plugin/test_test_id.py +39 -0
- pytest_data_loader-0.1.0/tests/unit/__init__.py +0 -0
- pytest_data_loader-0.1.0/tests/unit/data/dir +1 -0
- pytest_data_loader-0.1.0/tests/unit/data/text.txt +3 -0
- pytest_data_loader-0.1.0/tests/unit/test_data_loader_registration.py +22 -0
- pytest_data_loader-0.1.0/tests/unit/test_data_loader_setup.py +29 -0
- pytest_data_loader-0.1.0/tests/unit/test_directory_loader.py +37 -0
- pytest_data_loader-0.1.0/tests/unit/test_file_loader.py +111 -0
- pytest_data_loader-0.1.0/tests/unit/test_path_resolver.py +71 -0
- pytest_data_loader-0.1.0/tox.ini +32 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [ published ]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
name: Build package
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
with:
|
|
14
|
+
fetch-depth: 0
|
|
15
|
+
- name: Build and Check Package
|
|
16
|
+
uses: hynek/build-and-inspect-python-package@v2
|
|
17
|
+
|
|
18
|
+
publish-to-testpypi:
|
|
19
|
+
name: Publish to TestPyPI
|
|
20
|
+
needs: [ build ]
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
environment:
|
|
23
|
+
name: testpypi
|
|
24
|
+
url: https://test.pypi.org/project/pytest-data-loader/
|
|
25
|
+
permissions:
|
|
26
|
+
id-token: write
|
|
27
|
+
steps:
|
|
28
|
+
- name: Download all the dists
|
|
29
|
+
uses: actions/download-artifact@v4
|
|
30
|
+
with:
|
|
31
|
+
name: Packages
|
|
32
|
+
path: dist/
|
|
33
|
+
- name: Publish package to TestPyPI
|
|
34
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
35
|
+
with:
|
|
36
|
+
repository-url: https://test.pypi.org/legacy/
|
|
37
|
+
skip-existing: true
|
|
38
|
+
|
|
39
|
+
publish-to-pypi:
|
|
40
|
+
name: Publish to PyPI
|
|
41
|
+
needs: [ publish-to-testpypi ]
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
environment:
|
|
44
|
+
name: pypi
|
|
45
|
+
url: https://pypi.org/project/pytest-data-loader/
|
|
46
|
+
permissions:
|
|
47
|
+
id-token: write
|
|
48
|
+
steps:
|
|
49
|
+
- name: Download all the dists
|
|
50
|
+
uses: actions/download-artifact@v4
|
|
51
|
+
with:
|
|
52
|
+
name: Packages
|
|
53
|
+
path: dist/
|
|
54
|
+
- name: Publish package to PyPI
|
|
55
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
name: test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main]
|
|
7
|
+
|
|
8
|
+
concurrency:
|
|
9
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
10
|
+
cancel-in-progress: true
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.10"
|
|
20
|
+
- name: Install uv
|
|
21
|
+
uses: astral-sh/setup-uv@v5
|
|
22
|
+
with:
|
|
23
|
+
enable-cache: true
|
|
24
|
+
cache-dependency-glob: "**/pyproject.toml"
|
|
25
|
+
- name: Install dependencies
|
|
26
|
+
run: |
|
|
27
|
+
uv pip install --system .[lint]
|
|
28
|
+
- name: Run pre-commit
|
|
29
|
+
shell: bash
|
|
30
|
+
run: |
|
|
31
|
+
pre-commit run --all-files --show-diff-on-failure
|
|
32
|
+
|
|
33
|
+
package:
|
|
34
|
+
needs: [lint]
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
with:
|
|
39
|
+
fetch-depth: 0
|
|
40
|
+
- name: Build and Check Package
|
|
41
|
+
uses: hynek/build-and-inspect-python-package@v2
|
|
42
|
+
|
|
43
|
+
test:
|
|
44
|
+
needs: [package]
|
|
45
|
+
runs-on: ${{ matrix.os }}
|
|
46
|
+
strategy:
|
|
47
|
+
fail-fast: false
|
|
48
|
+
matrix:
|
|
49
|
+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
|
|
50
|
+
os: ["ubuntu-latest", "windows-latest"]
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@v4
|
|
53
|
+
- name: Download Package
|
|
54
|
+
uses: actions/download-artifact@v4
|
|
55
|
+
with:
|
|
56
|
+
name: Packages
|
|
57
|
+
path: dist
|
|
58
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
59
|
+
uses: actions/setup-python@v5
|
|
60
|
+
with:
|
|
61
|
+
python-version: ${{ matrix.python-version }}
|
|
62
|
+
- name: Install uv
|
|
63
|
+
uses: astral-sh/setup-uv@v5
|
|
64
|
+
with:
|
|
65
|
+
enable-cache: true
|
|
66
|
+
cache-dependency-glob: "**/pyproject.toml"
|
|
67
|
+
- name: Install tox
|
|
68
|
+
run: |
|
|
69
|
+
uv pip install --system tox tox-uv
|
|
70
|
+
- name: Test
|
|
71
|
+
shell: bash
|
|
72
|
+
run: |
|
|
73
|
+
tox -e py --installpkg `find dist/*.tar.gz`
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
.python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
110
|
+
.pdm.toml
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.venv
|
|
125
|
+
env/
|
|
126
|
+
venv/
|
|
127
|
+
ENV/
|
|
128
|
+
env.bak/
|
|
129
|
+
venv.bak/
|
|
130
|
+
|
|
131
|
+
# Spyder project settings
|
|
132
|
+
.spyderproject
|
|
133
|
+
.spyproject
|
|
134
|
+
|
|
135
|
+
# Rope project settings
|
|
136
|
+
.ropeproject
|
|
137
|
+
|
|
138
|
+
# mkdocs documentation
|
|
139
|
+
/site
|
|
140
|
+
|
|
141
|
+
# mypy
|
|
142
|
+
.mypy_cache/
|
|
143
|
+
.dmypy.json
|
|
144
|
+
dmypy.json
|
|
145
|
+
|
|
146
|
+
# Pyre type checker
|
|
147
|
+
.pyre/
|
|
148
|
+
|
|
149
|
+
# pytype static type analyzer
|
|
150
|
+
.pytype/
|
|
151
|
+
|
|
152
|
+
# Cython debug symbols
|
|
153
|
+
cython_debug/
|
|
154
|
+
|
|
155
|
+
# PyCharm
|
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
157
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
158
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
159
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
160
|
+
.idea/
|
|
161
|
+
|
|
162
|
+
.DS_Store
|
|
163
|
+
|
|
164
|
+
# Unofficial tests
|
|
165
|
+
tests/**/_*/**
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-toml
|
|
6
|
+
- id: check-yaml
|
|
7
|
+
args:
|
|
8
|
+
- --unsafe
|
|
9
|
+
- id: end-of-file-fixer
|
|
10
|
+
exclude: ^tests/(.*/)?data/
|
|
11
|
+
- repo: local
|
|
12
|
+
hooks:
|
|
13
|
+
- id: ruff
|
|
14
|
+
name: ruff
|
|
15
|
+
entry: ruff check
|
|
16
|
+
language: system
|
|
17
|
+
args:
|
|
18
|
+
- --fix
|
|
19
|
+
types: [ python ]
|
|
20
|
+
- id: ruff-format
|
|
21
|
+
name: ruff-format
|
|
22
|
+
entry: ruff format
|
|
23
|
+
language: system
|
|
24
|
+
types: [ python ]
|
|
25
|
+
- id: mypy
|
|
26
|
+
name: mypy
|
|
27
|
+
entry: mypy src
|
|
28
|
+
pass_filenames: false
|
|
29
|
+
language: system
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytest-data-loader
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Pytest plugin for loading test data for data-driven testing (DDT)
|
|
5
|
+
Author: Yugo Kato
|
|
6
|
+
Project-URL: Homepage, https://github.com/yugokato/pytest-data-loader
|
|
7
|
+
Keywords: pytest,data-driven testing,DDT
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Framework :: Pytest
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
19
|
+
Classifier: Topic :: Software Development :: Testing
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: pytest<9,>=7.0.0
|
|
23
|
+
Requires-Dist: pluggy>=1.2.0
|
|
24
|
+
Provides-Extra: lint
|
|
25
|
+
Requires-Dist: mypy<2,>=1.15.0; extra == "lint"
|
|
26
|
+
Requires-Dist: pre-commit<5,>=3.0.0; extra == "lint"
|
|
27
|
+
Requires-Dist: ruff<0.15.0,>=0.14.0; extra == "lint"
|
|
28
|
+
Provides-Extra: test
|
|
29
|
+
Requires-Dist: pytest-mock<4,>=3.0.0; extra == "test"
|
|
30
|
+
Requires-Dist: pytest-smoke; extra == "test"
|
|
31
|
+
Requires-Dist: pytest-xdist[psutil]<4,>=2.3.0; extra == "test"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: tox<5,>=4.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: tox-uv<2,>=1.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-data-loader[lint,test]; extra == "dev"
|
|
36
|
+
|
|
37
|
+
pytest-data-loader
|
|
38
|
+
======================
|
|
39
|
+
|
|
40
|
+
[](https://pypi.org/project/pytest-data-loader/)
|
|
41
|
+
[](https://pypi.org/project/pytest-data-loader/)
|
|
43
|
+
[](https://github.com/yugokato/pytest-data-loader/actions/workflows/test.yml?query=branch%3Amain)
|
|
44
|
+
[](https://docs.astral.sh/ruff/)
|
|
45
|
+
|
|
46
|
+
`pytest-data-loader` is a `pytest` plugin for loading test data from files to facilitate data-driven testing.
|
|
47
|
+
In addition to loading data from a single file, it supports dynamic test parametrization by splitting file data into
|
|
48
|
+
parts or by loading multiple files from a directory.
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install pytest-data-loader
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from pytest_data_loader import load
|
|
63
|
+
|
|
64
|
+
# Loads and injects data from data/example.json as the "data" fixture
|
|
65
|
+
# example.json: {"foo": 1, "bar": 2}
|
|
66
|
+
@load("data", "example.json")
|
|
67
|
+
def test_example(data):
|
|
68
|
+
assert "foo" in data
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
The plugin provides three data loaders — `@load`, `@parametrize`, and `@parametrize_dir` — available as decorators for
|
|
76
|
+
loading test data. As a common design, each loader takes two positional arguments:
|
|
77
|
+
|
|
78
|
+
- `fixture_names`: Name(s) of the fixture(s) that will be made available to the test function. It supports either one
|
|
79
|
+
(receiving file data) or two (receiving file path and file data) fixture names
|
|
80
|
+
- `relative_path`: File or directory path relative to one of the base "data" loader directories to load test data
|
|
81
|
+
from. The plugin will search for the closest "data" directory from the test file's directory and up
|
|
82
|
+
towards the Pytest root directory
|
|
83
|
+
|
|
84
|
+
Additionally, each loader supports different optional keyword arguments to customize how the data is loaded. See the
|
|
85
|
+
"Loader Options" section for details.
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
## Examples:
|
|
90
|
+
|
|
91
|
+
Given you have the following project structure:
|
|
92
|
+
```
|
|
93
|
+
.(pytest rootdir)
|
|
94
|
+
├── data/
|
|
95
|
+
│ ├── data1.json
|
|
96
|
+
│ ├── data2.txt
|
|
97
|
+
│ └── images/
|
|
98
|
+
│ ├── image1.gif
|
|
99
|
+
│ ├── image2.jpg
|
|
100
|
+
│ └── image3.png
|
|
101
|
+
├── tests1/
|
|
102
|
+
│ ├── data/
|
|
103
|
+
│ │ ├── data1.txt
|
|
104
|
+
│ │ └── data2.txt
|
|
105
|
+
│ └── test_something_else.py
|
|
106
|
+
└── test_something.py
|
|
107
|
+
```
|
|
108
|
+
The plugin searches for a `data` directory relative to the test file to locate data files.
|
|
109
|
+
|
|
110
|
+
### 1. Load file data (`@load`)
|
|
111
|
+
`@load` is a file loader that loads the file content and passes it to the test function.
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from pytest_data_loader import load
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@load("data", "data1.json")
|
|
118
|
+
def test_something1(data):
|
|
119
|
+
"""
|
|
120
|
+
This test loads the content of data/data1.json. The parsed JSON data is accessible through the specified
|
|
121
|
+
fixture argument, `data` in this example.
|
|
122
|
+
"""
|
|
123
|
+
...
|
|
124
|
+
|
|
125
|
+
@load(("file_path", "data"), "data2.txt")
|
|
126
|
+
def test_something2(file_path, data):
|
|
127
|
+
"""
|
|
128
|
+
This test loads the content of data/data2.txt. The file path and file content are accessible through the
|
|
129
|
+
specified fixture arguments, `file_path` and `data` in this example.
|
|
130
|
+
"""
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
> [!NOTE]
|
|
134
|
+
> If both `./test_something.py` and `./tests1/test_something_else.py` happen to have the above same loader definitions,
|
|
135
|
+
> the first test function will load `./data/data1.json` for both test files, and the second test function will load
|
|
136
|
+
> `data2.txt` from each test file's **nearest** `data` directory. This ensures that each test file loads data from its
|
|
137
|
+
> nearest data directory.
|
|
138
|
+
> This behavior applies to all loaders.
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
### 2. Parametrize file data (`@parametrize`)
|
|
142
|
+
`@parametrize` is a file loader that dynamically parametrizes the decorated test function by splitting the loaded file
|
|
143
|
+
content into logical parts. The test function will then receive the part data as loaded data for the current test.
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
from pytest_data_loader import parametrize
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
@parametrize("data", "data1.json")
|
|
150
|
+
def test_something1(data):
|
|
151
|
+
"""
|
|
152
|
+
This test will be dynamically parametrized with each key–value pair in a JSON object or each item in a JSON array,
|
|
153
|
+
depending on the data stored in data1.json.
|
|
154
|
+
The parametrized data is accessible through the specified fixture argument, `data` in this example.
|
|
155
|
+
"""
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
@parametrize(("file_path", "data"), "data2.txt")
|
|
159
|
+
def test_something2(file_path, data):
|
|
160
|
+
"""
|
|
161
|
+
This test will be dynamically parametrized with each text line from data2.txt.
|
|
162
|
+
The file path and each parametrized text line are accessible through the specified fixture arguments,
|
|
163
|
+
`file_path` and `data` in this example.
|
|
164
|
+
"""
|
|
165
|
+
...
|
|
166
|
+
```
|
|
167
|
+
> [!TIP]
|
|
168
|
+
> - By default, the plugin will apply the following logic for splitting file content:
|
|
169
|
+
> - Text file: Each line in a file
|
|
170
|
+
> - JSON file:
|
|
171
|
+
> - object: Each key–value pair in the object
|
|
172
|
+
> - array: Each item in the array
|
|
173
|
+
> - other types (string, number, boolean, null): The whole content as a single chunk
|
|
174
|
+
> - Binary file: Unsupported. Requires specifying a custom split logic as the `parametrizer_func` loader option
|
|
175
|
+
> - You can apply your own logic by specifying the `parametrizer_func` loader option
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
### 3. Parametrize files in a directory (`@parametrize_dir`)
|
|
179
|
+
|
|
180
|
+
`@parametrize_dir` is a file loader that dynamically parametrizes the decorated test function with the contents of the
|
|
181
|
+
files stored in the specified directory. The test function will then receive the content of each file as loaded data
|
|
182
|
+
for the current test.
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from pytest_data_loader import parametrize_dir
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@parametrize_dir("data", "images")
|
|
189
|
+
def test_something(data):
|
|
190
|
+
"""
|
|
191
|
+
This test will be dynamically parametrized with each image file in the `images` directory.
|
|
192
|
+
"""
|
|
193
|
+
...
|
|
194
|
+
```
|
|
195
|
+
> [!NOTE]
|
|
196
|
+
> File names starting with a dot (.) are considered hidden files regardless of your platform.
|
|
197
|
+
> These files are automatically excluded from the parametrization.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## Lazy Loading
|
|
202
|
+
|
|
203
|
+
Lazy loading is enabled by default for all loaders to improve performance, especially with large datasets. During the
|
|
204
|
+
test collection phase, Pytest receives a lazy object as a test parameter instead of the actual data. The data is
|
|
205
|
+
resolved only when it is needed during test setup.
|
|
206
|
+
If you need to disable this behavior for a specific test for some reason, you can specify the `lazy_loading=False`
|
|
207
|
+
option on the loader.
|
|
208
|
+
|
|
209
|
+
> [!NOTE]
|
|
210
|
+
> Lazy loading in the `@parametrize` loader works slightly differently from other loaders. Since Pytest needs to know
|
|
211
|
+
> the total number of parameters in advance, the plugin may still need to load the file data once and split during test
|
|
212
|
+
> collection phase, depending on the file type and the specified loader options. But once it's done, those part data
|
|
213
|
+
> will not be kept as parameter values and will be loaded lazily later.
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
## Loader Options
|
|
218
|
+
|
|
219
|
+
Each loader supports different optional parameters you can use to change how your data is loaded.
|
|
220
|
+
### @load
|
|
221
|
+
- `lazy_loading`: Enable or disable lazy loading
|
|
222
|
+
- `force_binary`: Force the file to be read in binary mode
|
|
223
|
+
- `onload_func`: A function to transform or preprocess loaded data before passing it to the test function
|
|
224
|
+
- `id`: An ID for the loaded data. The file name is used if not specified
|
|
225
|
+
|
|
226
|
+
### @parametrize
|
|
227
|
+
- `lazy_loading`: Enable or disable lazy loading
|
|
228
|
+
- `onload_func`: A function to adjust the shape of the loaded data before splitting into parts
|
|
229
|
+
- `parametrizer_func`: A function to customize how the loaded data should be split
|
|
230
|
+
- `filter_func`: A function to filter the split data parts. Only matching parts are included as test parameters
|
|
231
|
+
- `process_func`: A function to adjust the shape of each split data before passing it to the test function
|
|
232
|
+
- `id_func`: A function to generate a parameter ID for each test parameter, supported only when lazy_loading is `False`
|
|
233
|
+
|
|
234
|
+
### @parametrize_dir
|
|
235
|
+
- `lazy_loading`: Enable or disable lazy loading
|
|
236
|
+
- `force_binary`: Force each file to be read in binary mode
|
|
237
|
+
- `filter_func`: A function to filter file paths. Only the contents of matching file paths are included as the test
|
|
238
|
+
parameters
|
|
239
|
+
- `process_func`: A function to adjust the shape of each loaded file's data before passing it to the test function
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
## INI Options
|
|
244
|
+
|
|
245
|
+
### `data_loader_dir_name`
|
|
246
|
+
A base directory name to load test data from. The file or directory path specified to a loader is considered a
|
|
247
|
+
relative path to one of these base directories in the directory tree.
|
|
248
|
+
Plugin default: `data`
|
|
249
|
+
|
|
250
|
+
### `data_loader_strip_trailing_whitespace`
|
|
251
|
+
Automatically remove trailing whitespace characters when loading text data.
|
|
252
|
+
Plugin default: `true`
|