52
52
Actual shape: {actual_shape}
53
53
{actual_path}"""
54
54
55
+ # The following are the subsets of formats supported by the Matplotlib image
56
+ # comparison machinery
57
+ RASTER_IMAGE_FORMATS = ['png' ]
58
+ VECTOR_IMAGE_FORMATS = ['eps' , 'pdf' , 'svg' ]
59
+ ALL_IMAGE_FORMATS = RASTER_IMAGE_FORMATS + VECTOR_IMAGE_FORMATS
60
+
55
61
56
62
def _hash_file (in_stream ):
57
63
"""
@@ -70,8 +76,8 @@ def pathify(path):
70
76
"""
71
77
path = Path (path )
72
78
ext = ''
73
- if path .suffixes [- 1 ] == '.png' :
74
- ext = '.png'
79
+ if path .suffixes [- 1 ][ 1 :] in ALL_IMAGE_FORMATS :
80
+ ext = path . suffixes [ - 1 ]
75
81
path = str (path ).split (ext )[0 ]
76
82
path = str (path )
77
83
path = path .replace ('[' , '_' ).replace (']' , '_' )
@@ -315,18 +321,24 @@ def __init__(self,
315
321
self .logger .setLevel (level )
316
322
self .logger .addHandler (handler )
317
323
324
+ def _file_extension (self , item ):
325
+ compare = get_compare (item )
326
+ savefig_kwargs = compare .kwargs .get ('savefig_kwargs' , {})
327
+ return savefig_kwargs .get ('format' , 'png' )
328
+
318
329
def generate_filename (self , item ):
319
330
"""
320
331
Given a pytest item, generate the figure filename.
321
332
"""
333
+ ext = self ._file_extension (item )
322
334
if self .config .getini ('mpl-use-full-test-name' ):
323
- filename = generate_test_name (item ) + '.png '
335
+ filename = generate_test_name (item ) + f'. { ext } '
324
336
else :
325
337
compare = get_compare (item )
326
338
# Find test name to use as plot name
327
339
filename = compare .kwargs .get ('filename' , None )
328
340
if filename is None :
329
- filename = item .name + '.png '
341
+ filename = item .name + f'. { ext } '
330
342
331
343
filename = str (pathify (filename ))
332
344
return filename
@@ -465,9 +477,11 @@ def compare_image_to_baseline(self, item, fig, result_dir, summary=None):
465
477
tolerance = compare .kwargs .get ('tolerance' , 2 )
466
478
savefig_kwargs = compare .kwargs .get ('savefig_kwargs' , {})
467
479
480
+ ext = self ._file_extension (item )
481
+
468
482
baseline_image_ref = self .obtain_baseline_image (item , result_dir )
469
483
470
- test_image = (result_dir / "result.png " ).absolute ()
484
+ test_image = (result_dir / f "result.{ ext } " ).absolute ()
471
485
fig .savefig (str (test_image ), ** savefig_kwargs )
472
486
summary ['result_image' ] = test_image .relative_to (self .results_dir ).as_posix ()
473
487
@@ -484,24 +498,26 @@ def compare_image_to_baseline(self, item, fig, result_dir, summary=None):
484
498
485
499
# setuptools may put the baseline images in non-accessible places,
486
500
# copy to our tmpdir to be sure to keep them in case of failure
487
- baseline_image = (result_dir / "baseline.png " ).absolute ()
501
+ baseline_image = (result_dir / f "baseline.{ ext } " ).absolute ()
488
502
shutil .copyfile (baseline_image_ref , baseline_image )
489
503
summary ['baseline_image' ] = baseline_image .relative_to (self .results_dir ).as_posix ()
490
504
491
505
# Compare image size ourselves since the Matplotlib
492
506
# exception is a bit cryptic in this case and doesn't show
493
- # the filenames
494
- expected_shape = imread (str (baseline_image )).shape [:2 ]
495
- actual_shape = imread (str (test_image )).shape [:2 ]
496
- if expected_shape != actual_shape :
497
- summary ['status' ] = 'failed'
498
- summary ['image_status' ] = 'diff'
499
- error_message = SHAPE_MISMATCH_ERROR .format (expected_path = baseline_image ,
500
- expected_shape = expected_shape ,
501
- actual_path = test_image ,
502
- actual_shape = actual_shape )
503
- summary ['status_msg' ] = error_message
504
- return error_message
507
+ # the filenames. However imread won't work for vector graphics so we
508
+ # only do this for raster files.
509
+ if ext in RASTER_IMAGE_FORMATS :
510
+ expected_shape = imread (str (baseline_image )).shape [:2 ]
511
+ actual_shape = imread (str (test_image )).shape [:2 ]
512
+ if expected_shape != actual_shape :
513
+ summary ['status' ] = 'failed'
514
+ summary ['image_status' ] = 'diff'
515
+ error_message = SHAPE_MISMATCH_ERROR .format (expected_path = baseline_image ,
516
+ expected_shape = expected_shape ,
517
+ actual_path = test_image ,
518
+ actual_shape = actual_shape )
519
+ summary ['status_msg' ] = error_message
520
+ return error_message
505
521
506
522
results = compare_images (str (baseline_image ), str (test_image ), tol = tolerance , in_decorator = True )
507
523
summary ['tolerance' ] = tolerance
@@ -538,6 +554,8 @@ def compare_image_to_hash_library(self, item, fig, result_dir, summary=None):
538
554
compare = get_compare (item )
539
555
savefig_kwargs = compare .kwargs .get ('savefig_kwargs' , {})
540
556
557
+ ext = self ._file_extension (item )
558
+
541
559
if not self .results_hash_library_name :
542
560
# Use hash library name of current test as results hash library name
543
561
self .results_hash_library_name = Path (compare .kwargs .get ("hash_library" , "" )).name
@@ -574,7 +592,7 @@ def compare_image_to_hash_library(self, item, fig, result_dir, summary=None):
574
592
f"{ hash_library_filename } for test { hash_name } ." )
575
593
576
594
# Save the figure for later summary (will be removed later if not needed)
577
- test_image = (result_dir / "result.png " ).absolute ()
595
+ test_image = (result_dir / f "result.{ ext } " ).absolute ()
578
596
fig .savefig (str (test_image ), ** savefig_kwargs )
579
597
summary ['result_image' ] = test_image .relative_to (self .results_dir ).as_posix ()
580
598
@@ -627,6 +645,8 @@ def pytest_runtest_call(self, item): # noqa
627
645
remove_text = compare .kwargs .get ('remove_text' , False )
628
646
backend = compare .kwargs .get ('backend' , 'agg' )
629
647
648
+ ext = self ._file_extension (item )
649
+
630
650
with plt .style .context (style , after_reset = True ), switch_backend (backend ):
631
651
632
652
# Run test and get figure object
@@ -665,7 +685,7 @@ def pytest_runtest_call(self, item): # noqa
665
685
summary ['status_msg' ] = 'Skipped test, since generating image.'
666
686
generate_image = self .generate_baseline_image (item , fig )
667
687
if self .results_always : # Make baseline image available in HTML
668
- result_image = (result_dir / "baseline.png " ).absolute ()
688
+ result_image = (result_dir / f "baseline.{ ext } " ).absolute ()
669
689
shutil .copy (generate_image , result_image )
670
690
summary ['baseline_image' ] = \
671
691
result_image .relative_to (self .results_dir ).as_posix ()
0 commit comments