GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — fastplotlib/examples/tests/test_examples.py at streamplot · fastplotlib/fastplotlib Expand file tree/ Copy pathtest_examples.pyMore file actions 200 lines (155 loc) · 6.02 KB / Copy pathtest_examples.pyFile metadata and controls200 lines (155 loc) · 6.02 KB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 """ Test that examples run without error. """ import sys import importlib import runpy import pytest import os import numpy as np import imageio.v3 as iio import pygfx import fastplotlib as fpl MAX_TEXTURE_SIZE = 2048 pygfx.renderers.wgpu.set_wgpu_limits(**{"max-texture-dimension-2d": MAX_TEXTURE_SIZE}) from .testutils import ( ROOT, examples_dir, screenshots_dir, find_examples, wgpu_backend, is_lavapipe, diffs_dir, generate_diff, image_similarity, normalize_image, prep_for_write, ) # run all tests unless they opt-out examples_to_run = find_examples(negative_query="# run_example = false") # only test output of examples that opt-in examples_to_test = find_examples(query="# test_example = true") def check_skip_imgui(module): # skip any imgui, NDWidget or ImageWidget tests with open(module, "r") as f: contents = f.read() if "ImageWidget" in contents: pytest.skip("skipping ImageWidget tests since they require imgui") elif ( "imgui" in contents or "imgui_bundle" in contents or "NDWidget" in contents ): pytest.skip("skipping tests that require imgui") @pytest.mark.parametrize("module", examples_to_run, ids=lambda x: x.stem) def test_examples_run(module, prep_environment): """Run every example marked to see if they run without error.""" if not fpl.IMGUI: check_skip_imgui(module) runpy.run_path(module, run_name="__main__") @pytest.fixture def prep_environment(): """Force the offscreen canvas to be selected by the auto gui module.""" # Make that examples using rendercanvas.auto, will use the offscreen backend os.environ["RENDERCANVAS_FORCE_OFFSCREEN"] = "true" # Disable ppaa on the renderer by default. Otherwise all screenshots change when the ppaa shaders are updated. os.environ["PYGFX_DEFAULT_PPAA"] = "none" try: yield finally: del os.environ["RENDERCANVAS_FORCE_OFFSCREEN"] del os.environ["PYGFX_DEFAULT_PPAA"] # every example runs in this same process, so restore the config that an example has set fpl.style.default() def test_that_we_are_on_lavapipe(): print(wgpu_backend) if os.getenv("PYGFX_EXPECT_LAVAPIPE"): assert is_lavapipe def import_from_path(module_name, filename): spec = importlib.util.spec_from_file_location(module_name, filename) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # With this approach the module is not added to sys.modules, which # is great, because that way the gc can simply clean up when we lose # the reference to the module assert module.__name__ == module_name assert module_name not in sys.modules return module @pytest.mark.parametrize("module", examples_to_test, ids=lambda x: x.stem) def test_example_screenshots(module, prep_environment): """Make sure that every example marked outputs the expected.""" if not fpl.IMGUI: # skip any imgui or ImageWidget tests check_skip_imgui(module) # import the example module example = import_from_path(module.stem, module) # Render a frame. Twice, because layouts don't settle in one go? m1 = example.figure.renderer.target.draw() m2 = example.figure.renderer.target.draw() img = np.asarray(m2) # check if _something_ was rendered assert img is not None and img.size > 0 # if screenshots dir does not exist, will create if not os.path.exists(screenshots_dir): os.mkdir(screenshots_dir) # test screenshots for both imgui and non-gui installs if not fpl.IMGUI: prefix = "no-imgui-" else: prefix = "" screenshot_path = screenshots_dir / f"{prefix}{module.stem}.png" black = np.zeros(img.shape).astype(np.uint8) black[:, :, -1] = 255 img_alpha = img[..., -1] / 255 rgb = img[..., :-1] * img_alpha[..., None] + black[..., :-1] * np.ones( img_alpha.shape )[..., None] * (1 - img_alpha[..., None]) rgb = rgb.round().astype(np.uint8) if "REGENERATE_SCREENSHOTS" in os.environ.keys(): if os.environ["REGENERATE_SCREENSHOTS"] == "1": iio.imwrite(screenshot_path, rgb) assert screenshot_path.exists(), ( "found # test_example = true but no reference screenshot available" ) ref_img = iio.imread(screenshot_path) rgb = normalize_image(rgb) ref_img = normalize_image(ref_img) similar, rmse = image_similarity(rgb, ref_img) update_diffs(module.stem, similar, rgb, ref_img) assert similar, ( f"diff {rmse} above threshold for {module.stem}, see " f"the {diffs_dir.relative_to(ROOT).as_posix()} folder" " for visual diffs (you can download this folder from" " CI build artifacts as well)" ) def update_diffs(module, is_similar, img, stored_img): diffs_dir.mkdir(exist_ok=True) diffs_rgba = None def get_diffs_rgba(slicer): # lazily get and cache the diff computation nonlocal diffs_rgba if diffs_rgba is None: # cast to float32 to avoid overflow # compute absolute per-pixel difference diffs_rgba = np.abs(stored_img.astype("f4") - img) # magnify small values, making it easier to spot small errors diffs_rgba = ((diffs_rgba / 255) ** 0.25) * 255 # cast back to uint8 diffs_rgba = diffs_rgba.astype("u1") return diffs_rgba[..., slicer] # split into an rgb and an alpha diff diffs = { diffs_dir / f"diff-{module}-rgb.png": slice(0, 3), } for path, slicer in diffs.items(): if not is_similar: diff = get_diffs_rgba(slicer) iio.imwrite(path, diff) elif path.exists(): path.unlink() if __name__ == "__main__": # Need to apply these env vars *before* running this script, # since FPL selects its backend on import. # os.environ["RENDERCANVAS_FORCE_OFFSCREEN"] = "true" # os.environ["PYGFX_DEFAULT_PPAA"] = "none" test_example_screenshots(examples_to_test[0], None) |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |