Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow saving generated images to dir #22

Merged
merged 6 commits into from
Jan 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions pytest_pyvista/pytest_pyvista.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-


import os
import pathlib
import platform
Expand Down Expand Up @@ -28,6 +27,16 @@ def pytest_addoption(parser):
action="store_true",
help="Enables failure if image cache does not exist.",
)
group.addoption(
"--generated_image_dir",
action="store",
help="Path to dump test images from the current run.",
)
group.addoption(
"--add_missing_images",
action="store_true",
help="Adds images to cache if missing.",
)
group.addoption(
"--skip_image_cache_vtk8",
action="store_true",
Expand Down Expand Up @@ -75,6 +84,7 @@ class VerifyImageCache:
reset_image_cache = False
ignore_image_cache = False
fail_extra_image_cache = False
add_missing_images = False
skip_image_cache_vtk8 = False

def __init__(
Expand All @@ -86,6 +96,7 @@ def __init__(
warning_value=200,
var_error_value=1000,
var_warning_value=1000,
generated_image_dir=None,
):
self.test_name = test_name

Expand All @@ -100,6 +111,11 @@ def __init__(
self.var_error_value = var_error_value
self.var_warning_value = var_warning_value

self.generated_image_dir = generated_image_dir
if self.generated_image_dir is not None and not os.path.isdir(self.generated_image_dir):
warnings.warn(f"pyvista test generated image dir: {self.generated_image_dir} does not yet exist. Creating dir.")
os.makedirs(self.generated_image_dir)

self.high_variance_test = False
self.windows_skip_image_cache = False
self.macos_skip_image_cache = False
Expand Down Expand Up @@ -151,16 +167,17 @@ def __call__(self, plotter):
# cached image name. We remove the first 5 characters of the function name
# "test_" to get the name for the image.
image_filename = os.path.join(self.cache_dir, test_name[5:] + ".png")

if not os.path.isfile(image_filename) and self.fail_extra_image_cache:
raise RuntimeError(f"{image_filename} does not exist in image cache")
# simply save the last screenshot if it doesn't exist or the cache
# is being reset.
if self.reset_image_cache or not os.path.isfile(image_filename):
return plotter.screenshot(image_filename)

# otherwise, compare with the existing cached image
if self.add_missing_images and not os.path.isfile(image_filename):
plotter.screenshot(image_filename)

if self.generated_image_dir is not None:
gen_image_filename =os.path.join(self.generated_image_dir, test_name[5:] + ".png")
plotter.screenshot(gen_image_filename)
error = pyvista.compare_images(image_filename, plotter)

if error > allowed_error:
raise RuntimeError(
f"{test_name} Exceeded image regression error of "
Expand All @@ -184,6 +201,9 @@ def verify_image_cache(request, pytestconfig):
VerifyImageCache.fail_extra_image_cache = pytestconfig.getoption(
"fail_extra_image_cache"
)
VerifyImageCache.add_missing_images = pytestconfig.getoption(
"add_missing_images"
)
VerifyImageCache.skip_image_cache_vtk8 = pytestconfig.getoption(
"skip_image_cache_vtk8"
)
Expand All @@ -192,7 +212,9 @@ def verify_image_cache(request, pytestconfig):
if cache_dir is None:
cache_dir = pytestconfig.getini("image_cache_dir")

verify_image_cache = VerifyImageCache(request.node.name, cache_dir)
gen_dir = pytestconfig.getoption("generated_image_dir")

verify_image_cache = VerifyImageCache(request.node.name, cache_dir, generated_image_dir=gen_dir)
pyvista.global_theme.before_close_callback = verify_image_cache

return verify_image_cache
45 changes: 44 additions & 1 deletion tests/test_pyvista.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
skip_vtk8 = pytest.mark.skipif(pv.vtk_version_info < (9,), reason="vtk8 not supported")
skip_vtk9 = pytest.mark.skipif(pv.vtk_version_info >= (9,), reason="vtk8 only test")


@skip_vtk8
def test_arguments(testdir):
"""Test pytest arguments"""
Expand Down Expand Up @@ -189,6 +190,49 @@ def test_imcache_var(verify_image_cache):
result = testdir.runpytest("--fail_extra_image_cache", "test_file2.py")
result.stdout.fnmatch_lines("*[Pp]assed*")


@skip_vtk8
def test_generated_image_dir_commandline(testdir):
"""Test setting generated_image_dir via CLI option."""
make_cached_images(testdir.tmpdir)
testdir.makepyfile(
"""
import pyvista as pv
pv.OFF_SCREEN = True
def test_imcache(verify_image_cache):
sphere = pv.Sphere()
plotter = pv.Plotter()
plotter.add_mesh(sphere, color="red")
plotter.show()
"""
)

result = testdir.runpytest("--fail_extra_image_cache", "--generated_image_dir", "gen_dir")
assert os.path.isdir(os.path.join(testdir.tmpdir, "gen_dir"))
assert os.path.isfile(os.path.join(testdir.tmpdir, "gen_dir", "imcache.png"))
result.stdout.fnmatch_lines("*[Pp]assed*")


@skip_vtk8
def test_add_missing_images_commandline(testdir):
"""Test setting add_missing_images via CLI option."""
testdir.makepyfile(
"""
import pyvista as pv
pv.OFF_SCREEN = True
def test_imcache(verify_image_cache):
sphere = pv.Sphere()
plotter = pv.Plotter()
plotter.add_mesh(sphere, color="red")
plotter.show()
"""
)

result = testdir.runpytest("--add_missing_images")
assert os.path.isfile(os.path.join(testdir.tmpdir, "image_cache_dir", "imcache.png"))
result.stdout.fnmatch_lines("*[Pp]assed*")


@skip_vtk9
def test_skip_vtk8_commandline(testdir):
"""Test skip vtk8 via CLI option."""
Expand All @@ -201,7 +245,6 @@ def test_imcache(verify_image_cache):
sphere = pv.Sphere()
plotter = pv.Plotter()
plotter.add_mesh(sphere, color="red")

plotter.show()
"""
)
Expand Down