test_compare_images.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from pathlib import Path
  2. import shutil
  3. import pytest
  4. from pytest import approx
  5. from matplotlib.testing.compare import compare_images
  6. from matplotlib.testing.decorators import _image_directories
  7. # Tests of the image comparison algorithm.
  8. @pytest.mark.parametrize(
  9. 'im1, im2, tol, expect_rms',
  10. [
  11. # Comparison of an image and the same image with minor differences.
  12. # This expects the images to compare equal under normal tolerance, and
  13. # have a small RMS.
  14. ('basn3p02.png', 'basn3p02-minorchange.png', 10, None),
  15. # Now test with no tolerance.
  16. ('basn3p02.png', 'basn3p02-minorchange.png', 0, 6.50646),
  17. # Comparison with an image that is shifted by 1px in the X axis.
  18. ('basn3p02.png', 'basn3p02-1px-offset.png', 0, 90.15611),
  19. # Comparison with an image with half the pixels shifted by 1px in the X
  20. # axis.
  21. ('basn3p02.png', 'basn3p02-half-1px-offset.png', 0, 63.75),
  22. # Comparison of an image and the same image scrambled.
  23. # This expects the images to compare completely different, with a very
  24. # large RMS.
  25. # Note: The image has been scrambled in a specific way, by having
  26. # each color component of each pixel randomly placed somewhere in the
  27. # image. It contains exactly the same number of pixels of each color
  28. # value of R, G and B, but in a totally different position.
  29. # Test with no tolerance to make sure that we pick up even a very small
  30. # RMS error.
  31. ('basn3p02.png', 'basn3p02-scrambled.png', 0, 172.63582),
  32. # Comparison of an image and a slightly brighter image.
  33. # The two images are solid color, with the second image being exactly 1
  34. # color value brighter.
  35. # This expects the images to compare equal under normal tolerance, and
  36. # have an RMS of exactly 1.
  37. ('all127.png', 'all128.png', 0, 1),
  38. # Now test the reverse comparison.
  39. ('all128.png', 'all127.png', 0, 1),
  40. ])
  41. def test_image_comparison_expect_rms(im1, im2, tol, expect_rms, tmp_path,
  42. monkeypatch):
  43. """
  44. Compare two images, expecting a particular RMS error.
  45. im1 and im2 are filenames relative to the baseline_dir directory.
  46. tol is the tolerance to pass to compare_images.
  47. expect_rms is the expected RMS value, or None. If None, the test will
  48. succeed if compare_images succeeds. Otherwise, the test will succeed if
  49. compare_images fails and returns an RMS error almost equal to this value.
  50. """
  51. # Change the working directory using monkeypatch to use a temporary
  52. # test specific directory
  53. monkeypatch.chdir(tmp_path)
  54. baseline_dir, result_dir = map(Path, _image_directories(lambda: "dummy"))
  55. # Copy "test" image to result_dir, so that compare_images writes
  56. # the diff to result_dir, rather than to the source tree
  57. result_im2 = result_dir / im1
  58. shutil.copyfile(baseline_dir / im2, result_im2)
  59. results = compare_images(
  60. baseline_dir / im1, result_im2, tol=tol, in_decorator=True)
  61. if expect_rms is None:
  62. assert results is None
  63. else:
  64. assert results is not None
  65. assert results['rms'] == approx(expect_rms, abs=1e-4)