OLD | NEW |
(Empty) | |
| 1 import os |
| 2 import re |
| 3 import subprocess |
| 4 import unittest |
| 5 import sys |
| 6 |
| 7 import selenium_utilities |
| 8 import selenium_constants |
| 9 |
| 10 class PDiffTest(unittest.TestCase): |
| 11 """A perceptual diff test class, for running perceptual diffs on any |
| 12 number of screenshots.""" |
| 13 |
| 14 def __init__(self, name, num_screenshots, screenshot_name, pdiff_path, |
| 15 gen_dir, ref_dir, options): |
| 16 unittest.TestCase.__init__(self, name) |
| 17 self.name = name |
| 18 self.num_screenshots = num_screenshots |
| 19 self.screenshot_name = screenshot_name |
| 20 self.pdiff_path = pdiff_path |
| 21 self.gen_dir = gen_dir |
| 22 self.ref_dir = ref_dir |
| 23 self.options = options |
| 24 |
| 25 def shortDescription(self): |
| 26 """override unittest.TestCase shortDescription for our own descriptions.""" |
| 27 return "Screenshot comparison for: " + self.name |
| 28 |
| 29 def PDiffTest(self): |
| 30 """Runs a generic Perceptual Diff test.""" |
| 31 # Get arguments for perceptual diff. |
| 32 pixel_threshold = "10" |
| 33 alpha_threshold = "1.0" |
| 34 use_colorfactor = False |
| 35 use_downsample = False |
| 36 use_edge = True |
| 37 edge_threshold = "5" |
| 38 |
| 39 for opt in self.options: |
| 40 if opt.startswith("pdiff_threshold"): |
| 41 pixel_threshold = selenium_utilities.GetArgument(opt) |
| 42 elif (opt.startswith("pdiff_threshold_mac") and |
| 43 sys.platform == "darwin"): |
| 44 pixel_threshold = selenium_utilities.GetArgument(opt) |
| 45 elif (opt.startswith("pdiff_threshold_win") and |
| 46 sys.platform == 'win32' or sys.platform == "cygwin"): |
| 47 pixel_threshold = selenium_utilities.GetArgument(opt) |
| 48 elif (opt.startswith("pdiff_threshold_linux") and |
| 49 sys.platform[:5] == "linux"): |
| 50 pixel_threshold = selenium_utilities.GetArgument(opt) |
| 51 elif (opt.startswith("colorfactor")): |
| 52 colorfactor = selenium_utilities.GetArgument(opt) |
| 53 use_colorfactor = True |
| 54 elif (opt.startswith("downsample")): |
| 55 downsample_factor = selenium_utilities.GetArgument(opt) |
| 56 use_downsample = True |
| 57 elif (opt.startswith("pdiff_edge_ignore_off")): |
| 58 use_edge = False |
| 59 elif (opt.startswith("pdiff_edge_threshold")): |
| 60 edge_threshold = selenium_utilities.GetArgument(opt) |
| 61 |
| 62 results = [] |
| 63 # Loop over number of screenshots. |
| 64 for screenshot_no in range(self.num_screenshots): |
| 65 # Find reference image. |
| 66 J = os.path.join |
| 67 platform_img_path = J(self.ref_dir, |
| 68 selenium_constants.PLATFORM_SCREENSHOT_DIR, |
| 69 self.screenshot_name + str(screenshot_no + 1) + |
| 70 '_reference.png') |
| 71 reg_img_path = J(self.ref_dir, |
| 72 selenium_constants.DEFAULT_SCREENSHOT_DIR, |
| 73 self.screenshot_name + str(screenshot_no + 1) + |
| 74 '_reference.png') |
| 75 |
| 76 if os.path.exists(platform_img_path): |
| 77 ref_img_path = platform_img_path |
| 78 elif os.path.exists(reg_img_path): |
| 79 ref_img_path = reg_img_path |
| 80 else: |
| 81 self.fail('Reference image for ' + self.screenshot_name + ' not found.' |
| 82 + '\nNeither file exists %s NOR %s' % |
| 83 (reg_img_path, platform_img_path)) |
| 84 |
| 85 # Find generated image. |
| 86 gen_img_path = J(self.gen_dir, self.screenshot_name + |
| 87 str(screenshot_no + 1) + '.png') |
| 88 diff_img_path = J(self.gen_dir, 'cmp_' + self.screenshot_name + |
| 89 str(screenshot_no + 1) + '.png') |
| 90 |
| 91 self.assertTrue(os.path.exists(gen_img_path), |
| 92 'Generated screenshot for ' + self.screenshot_name + |
| 93 ' not found.\nFile does not exist: %s' % gen_img_path) |
| 94 |
| 95 # Run perceptual diff |
| 96 arguments = [self.pdiff_path, |
| 97 ref_img_path, |
| 98 gen_img_path, |
| 99 "-output", diff_img_path, |
| 100 "-fov", "45", |
| 101 "-alphaThreshold", alpha_threshold, |
| 102 # Turn on verbose output for the percetual diff so we |
| 103 # can see how far off we are on the threshold. |
| 104 "-verbose", |
| 105 # Set the threshold to zero so we can get a count |
| 106 # of the different pixels. This causes the program |
| 107 # to return failure for most images, but we can compare |
| 108 # the values ourselves below. |
| 109 "-threshold", "0"] |
| 110 if use_colorfactor: |
| 111 arguments += ["-colorfactor", colorfactor] |
| 112 if use_downsample: |
| 113 arguments += ["-downsample", downsample_factor] |
| 114 if use_edge: |
| 115 arguments += ["-ignoreEdges", edge_threshold] |
| 116 |
| 117 pdiff_pipe = subprocess.Popen(arguments, |
| 118 stdout=subprocess.PIPE, |
| 119 stderr=subprocess.PIPE) |
| 120 (pdiff_stdout, pdiff_stderr) = pdiff_pipe.communicate() |
| 121 result = pdiff_pipe.returncode |
| 122 # Find out how many pixels were different by looking at the output. |
| 123 pixel_re = re.compile("(\d+) pixels are different", re.DOTALL) |
| 124 pixel_match = pixel_re.search(pdiff_stdout) |
| 125 different_pixels = "0" |
| 126 if pixel_match: |
| 127 different_pixels = pixel_match.group(1) |
| 128 |
| 129 results += [(gen_img_path, int(different_pixels))] |
| 130 |
| 131 all_tests_passed = True |
| 132 msg = "Pixel Threshold is %s. Failing screenshots:\n" % pixel_threshold |
| 133 for path, pixels in results: |
| 134 if pixels >= pixel_threshold: |
| 135 all_tests_passed = False |
| 136 msg += " %s, differing by %s\n" % (path, str(pixels)) |
| 137 |
| 138 if not all_tests_passed: |
| 139 self.assertTrue(all_tests_passed, msg) |
OLD | NEW |