conftest.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import pytest
  2. import matplotlib
  3. from matplotlib import cbook
  4. def pytest_configure(config):
  5. # config is initialized here rather than in pytest.ini so that `pytest
  6. # --pyargs matplotlib` (which would not find pytest.ini) works. The only
  7. # entries in pytest.ini set minversion (which is checked earlier) and
  8. # testpaths/python_files, as they are required to properly find the tests.
  9. for key, value in [
  10. ("markers", "flaky: (Provided by pytest-rerunfailures.)"),
  11. ("markers", "timeout: (Provided by pytest-timeout.)"),
  12. ("markers", "backend: Set alternate Matplotlib backend temporarily."),
  13. ("markers", "style: Set alternate Matplotlib style temporarily."),
  14. ("markers", "baseline_images: Compare output against references."),
  15. ("markers", "pytz: Tests that require pytz to be installed."),
  16. ("filterwarnings", "error"),
  17. ]:
  18. config.addinivalue_line(key, value)
  19. matplotlib.use('agg', force=True)
  20. matplotlib._called_from_pytest = True
  21. matplotlib._init_tests()
  22. def pytest_unconfigure(config):
  23. matplotlib._called_from_pytest = False
  24. @pytest.fixture(autouse=True)
  25. def mpl_test_settings(request):
  26. from matplotlib.testing.decorators import _cleanup_cm
  27. with _cleanup_cm():
  28. backend = None
  29. backend_marker = request.node.get_closest_marker('backend')
  30. if backend_marker is not None:
  31. assert len(backend_marker.args) == 1, \
  32. "Marker 'backend' must specify 1 backend."
  33. backend, = backend_marker.args
  34. skip_on_importerror = backend_marker.kwargs.get(
  35. 'skip_on_importerror', False)
  36. prev_backend = matplotlib.get_backend()
  37. # Default of cleanup and image_comparison too.
  38. style = ["classic", "_classic_test_patch"]
  39. style_marker = request.node.get_closest_marker('style')
  40. if style_marker is not None:
  41. assert len(style_marker.args) == 1, \
  42. "Marker 'style' must specify 1 style."
  43. style, = style_marker.args
  44. matplotlib.testing.setup()
  45. if backend is not None:
  46. # This import must come after setup() so it doesn't load the
  47. # default backend prematurely.
  48. import matplotlib.pyplot as plt
  49. try:
  50. plt.switch_backend(backend)
  51. except ImportError as exc:
  52. # Should only occur for the cairo backend tests, if neither
  53. # pycairo nor cairocffi are installed.
  54. if 'cairo' in backend.lower() or skip_on_importerror:
  55. pytest.skip("Failed to switch to backend {} ({})."
  56. .format(backend, exc))
  57. else:
  58. raise
  59. with cbook._suppress_matplotlib_deprecation_warning():
  60. matplotlib.style.use(style)
  61. try:
  62. yield
  63. finally:
  64. if backend is not None:
  65. plt.switch_backend(prev_backend)
  66. @pytest.fixture
  67. def mpl_image_comparison_parameters(request, extension):
  68. # This fixture is applied automatically by the image_comparison decorator.
  69. #
  70. # The sole purpose of this fixture is to provide an indirect method of
  71. # obtaining parameters *without* modifying the decorated function
  72. # signature. In this way, the function signature can stay the same and
  73. # pytest won't get confused.
  74. # We annotate the decorated function with any parameters captured by this
  75. # fixture so that they can be used by the wrapper in image_comparison.
  76. baseline_images, = request.node.get_closest_marker('baseline_images').args
  77. if baseline_images is None:
  78. # Allow baseline image list to be produced on the fly based on current
  79. # parametrization.
  80. baseline_images = request.getfixturevalue('baseline_images')
  81. func = request.function
  82. with cbook._setattr_cm(func.__wrapped__,
  83. parameters=(baseline_images, extension)):
  84. yield
  85. @pytest.fixture
  86. def pd():
  87. """Fixture to import and configure pandas."""
  88. pd = pytest.importorskip('pandas')
  89. try:
  90. from pandas.plotting import (
  91. deregister_matplotlib_converters as deregister)
  92. deregister()
  93. except ImportError:
  94. pass
  95. return pd