test_compare_images.py 3.1 KB

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