Refactor exif related test suite
* Use more specific pytest markers that automagically skip the tests * Split requirements into multiple files * Make exif related fixtures available for the complete test suite
This commit is contained in:
parent
78d9cd7ffd
commit
c661d40de3
|
@ -37,7 +37,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
toxenv: [pyqt513, pyqt514, pyqt515-cov, no_optionals, lint, packaging, mypy]
|
||||
toxenv: [pyqt513, pyqt514, pyqt515-cov, piexif, noexif, lint, packaging, mypy]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
piexif==1.1.3
|
|
@ -1,2 +1 @@
|
|||
piexif==1.1.3
|
||||
py3exiv2==0.8.0
|
|
@ -1,11 +1,13 @@
|
|||
[pytest]
|
||||
testpaths = tests
|
||||
addopts = --no-flaky-report
|
||||
addopts = --no-flaky-report --strict-markers
|
||||
faulthandler_timeout = 30
|
||||
markers =
|
||||
current: Mark tests during development
|
||||
imageformats: Require retrieving images from the web to test additional formats
|
||||
optional: Require optional dependencies
|
||||
no_optional: Require optional dependencies to NOT be installed
|
||||
exif: Require exif support
|
||||
piexif: Require piexif
|
||||
pyexiv2: Require pyexiv2
|
||||
noexif: Requires exif support NOT to be available
|
||||
ci: Run test only on ci
|
||||
ci_skip: Skip test on ci
|
||||
|
|
|
@ -12,6 +12,8 @@ import urllib.request
|
|||
|
||||
import pytest
|
||||
|
||||
from vimiv.imutils import exif
|
||||
|
||||
|
||||
CI = "CI" in os.environ
|
||||
|
||||
|
@ -20,25 +22,46 @@ PLATFORM_MARKERS = (
|
|||
("ci", CI, "Only run on ci"),
|
||||
("ci_skip", not CI, "Skipped on ci"),
|
||||
)
|
||||
|
||||
EXIF_MARKERS = (
|
||||
("exif", exif.has_exif_support, "Only run with exif support"),
|
||||
("noexif", not exif.has_exif_support, "Only run without exif support"),
|
||||
("pyexiv2", exif.pyexiv2 is not None, "Only run with pyexiv2"),
|
||||
("piexif", exif.piexif is not None, "Only run with piexif"),
|
||||
)
|
||||
# fmt: on
|
||||
|
||||
|
||||
def apply_platform_markers(item):
|
||||
"""Apply markers that skip tests depending on the current platform."""
|
||||
for marker_name, fulfilled, reason in PLATFORM_MARKERS:
|
||||
apply_markers_helper(item, PLATFORM_MARKERS)
|
||||
|
||||
|
||||
def apply_exif_markers(item):
|
||||
"""Apply markers that skip tests depending on specific exif support."""
|
||||
if os.path.basename(item.fspath) in ("test_exif.py",):
|
||||
for marker_name in "exif", "pyexiv2", "piexif":
|
||||
marker = getattr(pytest.mark, marker_name)
|
||||
item.add_marker(marker)
|
||||
apply_markers_helper(item, EXIF_MARKERS)
|
||||
|
||||
|
||||
def apply_markers_helper(item, markers):
|
||||
"""Helper function to apply an iterable of markers to a test item."""
|
||||
for marker_name, fulfilled, reason in markers:
|
||||
marker = item.get_closest_marker(marker_name)
|
||||
if not marker or fulfilled:
|
||||
continue
|
||||
skipif = pytest.mark.skipif(
|
||||
not fulfilled, *marker.args, reason=reason, **marker.kwargs
|
||||
)
|
||||
item.add_marker(skipif)
|
||||
if marker is not None:
|
||||
skipif = pytest.mark.skipif(
|
||||
not fulfilled, *marker.args, reason=reason, **marker.kwargs
|
||||
)
|
||||
item.add_marker(skipif)
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(items):
|
||||
"""Handle custom markers via pytest hook."""
|
||||
for item in items:
|
||||
apply_platform_markers(item)
|
||||
apply_exif_markers(item)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -140,3 +163,30 @@ def _retrieve_file_from_web(url: str, path: str) -> None:
|
|||
def tmpdir():
|
||||
"""Override tmpdir to raise a ValueError."""
|
||||
raise ValueError("Use the 'tmp_path' fixture instead of 'tmpdir'")
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def piexif(monkeypatch):
|
||||
"""Pytest fixture to ensure only piexif is available."""
|
||||
monkeypatch.setattr(exif, "pyexiv2", None)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def noexif(monkeypatch, piexif):
|
||||
"""Pytest fixture to ensure no exif library is available."""
|
||||
monkeypatch.setattr(exif, "piexif", None)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def add_exif_information():
|
||||
"""Fixture to retrieve a helper function that adds exif content to an image."""
|
||||
|
||||
def add_exif_information_impl(path: str, content):
|
||||
assert exif.piexif is not None, "piexif required to add exif information"
|
||||
exif_dict = exif.piexif.load(path)
|
||||
for ifd, ifd_dict in content.items():
|
||||
for key, value in ifd_dict.items():
|
||||
exif_dict[ifd][key] = value
|
||||
exif.piexif.insert(exif.piexif.dump(exif_dict), path)
|
||||
|
||||
return add_exif_information_impl
|
||||
|
|
|
@ -33,14 +33,9 @@ def handler():
|
|||
|
||||
|
||||
@bdd.when("I add exif information")
|
||||
def add_exif_information(handler, exif_content):
|
||||
def add_exif_information_bdd(add_exif_information, handler, exif_content):
|
||||
assert piexif is not None, "piexif required to add exif information"
|
||||
path = handler._path
|
||||
exif_dict = piexif.load(path)
|
||||
for ifd, ifd_dict in exif_content.items():
|
||||
for key, value in ifd_dict.items():
|
||||
exif_dict[ifd][key] = value
|
||||
# Wait for thumbnail creation so we don't interfere with the current reading by
|
||||
# adding more bytes
|
||||
utils.Pool.wait(5000)
|
||||
piexif.insert(piexif.dump(exif_dict), path)
|
||||
add_exif_information(handler._path, exif_content)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@optional
|
||||
@exif
|
||||
Feature: Metadata widget displaying image exif information
|
||||
|
||||
Scenario: Show metadata widget
|
||||
|
|
|
@ -11,7 +11,7 @@ Feature: Write an image to disk
|
|||
| new_path.png |
|
||||
| new_path.tiff |
|
||||
|
||||
@optional
|
||||
@exif
|
||||
Scenario: Write image preserving exif information
|
||||
Given I open any image
|
||||
When I add exif information
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@no_optional
|
||||
Feature: Ensure the application works correctly without optional dependencies
|
||||
|
||||
@noexif
|
||||
Scenario: No metadata command
|
||||
Given I open any image
|
||||
When I run metadata
|
||||
|
|
|
@ -17,18 +17,6 @@ def exif_handler(request):
|
|||
yield request.param
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def piexif(monkeypatch):
|
||||
"""Pytest fixture to ensure only piexif is available."""
|
||||
monkeypatch.setattr(exif, "pyexiv2", None)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def noexif(monkeypatch, piexif):
|
||||
"""Pytest fixture to ensure no exif library is available."""
|
||||
monkeypatch.setattr(exif, "piexif", None)
|
||||
|
||||
|
||||
def test_check_exif_dependency():
|
||||
default = None
|
||||
assert exif.check_exif_dependancy(default) == default
|
||||
|
|
|
@ -26,7 +26,6 @@ def no_exif_support(monkeypatch):
|
|||
monkeypatch.setattr(version, "piexif", None)
|
||||
|
||||
|
||||
@pytest.mark.optional
|
||||
def test_svg_support_info():
|
||||
assert "svg support: true" in version.info().lower()
|
||||
|
||||
|
@ -35,7 +34,7 @@ def test_no_svg_support_info(no_svg_support):
|
|||
assert "svg support: false" in version.info().lower()
|
||||
|
||||
|
||||
@pytest.mark.optional
|
||||
@pytest.mark.piexif
|
||||
def test_exif_support_info():
|
||||
assert piexif.VERSION in version.info()
|
||||
|
||||
|
|
18
tox.ini
18
tox.ini
|
@ -1,5 +1,5 @@
|
|||
[tox]
|
||||
envlist = pyqt-cov,no_optionals,lint,packaging,mypy
|
||||
envlist = pyqt-cov,piexif,noexif,lint,packaging,mypy
|
||||
|
||||
# Standard test suite using pytest
|
||||
[testenv]
|
||||
|
@ -9,7 +9,8 @@ passenv = PYTHONPATH CI USER HOME XDG_* DISPLAY
|
|||
basepython = {env:PYTHON:python3}
|
||||
deps =
|
||||
-r{toxinidir}/misc/requirements/requirements_tests.txt
|
||||
-r{toxinidir}/misc/requirements/requirements_optional.txt
|
||||
-r{toxinidir}/misc/requirements/requirements_pyexiv2.txt
|
||||
-r{toxinidir}/misc/requirements/requirements_piexif.txt
|
||||
pyqt: -r{toxinidir}/misc/requirements/requirements.txt
|
||||
pyqt59: PyQt5==5.9.2
|
||||
pyqt510: PyQt5==5.10.1
|
||||
|
@ -21,15 +22,20 @@ deps =
|
|||
cov: -r{toxinidir}/misc/requirements/requirements_cov.txt
|
||||
|
||||
commands_pre = {envpython} scripts/maybe_build_cextension.py
|
||||
commands = pytest -m "not no_optional" {posargs}
|
||||
commands = pytest {posargs}
|
||||
|
||||
# Test suite without optional dependencies
|
||||
[testenv:no_optionals]
|
||||
# Test suite using piexif
|
||||
[testenv:piexif]
|
||||
deps =
|
||||
-r{toxinidir}/misc/requirements/requirements.txt
|
||||
-r{toxinidir}/misc/requirements/requirements_tests.txt
|
||||
-r{toxinidir}/misc/requirements/requirements_piexif.txt
|
||||
|
||||
commands = pytest -m "not optional" {posargs}
|
||||
# Test suite without optional dependencies
|
||||
[testenv:noexif]
|
||||
deps =
|
||||
-r{toxinidir}/misc/requirements/requirements.txt
|
||||
-r{toxinidir}/misc/requirements/requirements_tests.txt
|
||||
|
||||
# Linters and checkers for the source code
|
||||
[testenv:lint]
|
||||
|
|
Loading…
Reference in New Issue