Package dogtail :: Module tc
[hide private]
[frames] | no frames]

Source Code for Module dogtail.tc

  1  # -*- coding: utf-8 -*- 
  2  """Test Case magic 
  3   
  4  Author: Ed Rousseau <rousseau@redhat.com>""" 
  5  __author__ = "Ed Rousseau <rousseau@redhat.com>" 
  6   
  7  import string 
  8  import sys 
  9  import os 
 10  import re 
 11  import time 
 12  import datetime 
 13  import os.path 
 14  from config import config 
 15  from logging import ResultsLogger, TimeStamp, debugLogger 
 16  from PIL import Image, ImageChops, ImageStat 
 17   
 18   
19 -class TC(object):
20 """ 21 The Test Case Superclass 22 """ 23 logger = ResultsLogger()
24 - def __init__(self):
25 self.encoding = config.encoding 26 # ascii + unicode. 8 bit extended char has been ripped out 27 self.supportedtypes = ("ascii", "utf-8", "utf-16", "utf-16-be", "utf-16-le", "unicode-escape", "raw-unicode-escape", 28 "big5", "gb18030", "eucJP", "eucKR", "shiftJIS")
29 30 # String comparison function
31 - def compare(self, label, baseline, undertest, encoding=config.encoding):
32 """ 33 Compares 2 strings to see if they are the same. The user may specify 34 the encoding to which the two strings are to be normalized for the 35 comparison. Default encoding is the default system encoding. 36 Normalization to extended 8 bit charactersets is not supported. 37 38 When the origin of either baseline or undertest is a text file whose 39 encoding is something other than ASCII, it is necessary to use 40 codecs.open() instead of open(), so the file's encoding may be 41 specified. 42 """ 43 self.label = label.strip() 44 self.baseline = baseline 45 self.undertest = undertest 46 for string in [self.baseline, self.undertest]: 47 try: string = unicode(string, 'utf-8') 48 except TypeError: pass 49 self.encoding = encoding 50 51 # Normalize the encoding type for the comparaison based on self.encoding 52 if self.encoding in self.supportedtypes: 53 self.baseline = (self.baseline).encode(self.encoding) 54 self.undertest = (self.undertest).encode(self.encoding) 55 # Compare the strings 56 if self.baseline == self.undertest: 57 self.result = {self.label: "Passed"} 58 else: 59 self.result = {self.label: "Failed - " + self.encoding + " strings do not match. " + self.baseline + " expected: Got " + self.undertest} 60 # Pass the test result to the ResultsLogger for writing 61 TC.logger.log(self.result) 62 return self.result 63 64 else: 65 # We should probably raise an exception here 66 self.result = {self.label: "ERROR - " + self.encoding + " is not a supported encoding type"} 67 TC.logger.log(self.result) 68 return self.result
69 70 71 # String Test Case subclass
72 -class TCString(TC):
73 """ 74 String Test Case Class 75 """
76 - def __init__(self):
77 TC.__init__(self)
78 79 # Image test case subclass
80 -class TCImage(TC):
81 """ 82 Image Test Case Class. 83 """
84 - def compare(self, label, baseline, undertest):
85 for _file in (baseline, undertest): 86 if type(_file) is not unicode and type(_file) is not str: 87 raise TypeError("Need filenames!") 88 self.label = label.strip() 89 self.baseline = baseline.strip() 90 self.undertest = undertest.strip() 91 diffName = TimeStamp().fileStamp("diff") + ".png" 92 self.diff = os.path.normpath( 93 os.path.sep.join((config.scratchDir, diffName))) 94 95 self.baseImage = Image.open(self.baseline) 96 self.testImage = Image.open(self.undertest) 97 try: 98 if self.baseImage.size != self.testImage.size: 99 self.result = {self.label: "Failed - images are different sizes"} 100 raise StopIteration 101 102 self.diffImage = ImageChops.difference(self.baseImage, 103 self.testImage) 104 self.diffImage.save(self.diff) 105 result = False 106 for stat in ('stddev', 'mean', 'sum2'): 107 for item in getattr(ImageStat.Stat(self.diffImage), stat): 108 if item: 109 self.result = {self.label: "Failed - see %s" % 110 self.diff} 111 raise StopIteration 112 else: result = True 113 except StopIteration: 114 result = False 115 116 if result: self.result = {self.label: "Passed"} 117 118 TC.logger.log(self.result) 119 return self.result
120 121
122 -class TCNumber(TC):
123 """ 124 Number Comparaison Test Case Class 125 """
126 - def __init__(self):
127 TC.__init__(self) 128 self.supportedtypes = ("int", "long", "float", "complex", "oct", "hex")
129 130 # Compare 2 numbers by the type provided in the type arg
131 - def compare(self, label, baseline, undertest, type):
132 """ 133 Compares 2 numbers to see if they are the same. The user may specify 134 how to normalize mixed type comparisons via the type argument. 135 """ 136 self.label = label.strip() 137 self.baseline = baseline 138 self.undertest = undertest 139 self.type = type.strip() 140 141 # If we get a valid type, convert to that type and compare 142 if self.type in self.supportedtypes: 143 # Normalize for comparison 144 if self.type == "int": 145 self.baseline = int(self.baseline) 146 self.undertest = int(self.undertest) 147 elif self.type == "long": 148 self.baseline = long(self.baseline) 149 self.undertest = long(self.undertest) 150 elif self.type == "float": 151 self.baseline = float(self.baseline) 152 self.undertest = float(self.undertest) 153 else: 154 self.baseline = complex(self.baseline) 155 self.undertest = complex(self.undertest) 156 157 #compare 158 if self.baseline == self.undertest: 159 self.result = {self.label: "Passed - numbers are the same"} 160 else: 161 self.result = {self.label: "Failed - " + str(self.baseline) + " expected: Got " + str(self.undertest)} 162 TC.logger.log(self.result) 163 return self.result 164 else: 165 self.result = {self.label: "Failed - " + self.type + " is not in list of supported types"} 166 TC.logger.log(self.result) 167 return self.result
168
169 -class TCBool(TC):
170 - def __init__(self): pass
171
172 - def compare(self, label, _bool):
173 """ 174 If _bool is True, pass. 175 If _bool is False, fail. 176 """ 177 if type(_bool) is not bool: raise TypeError 178 if _bool: result = {label: "Passed"} 179 else: result = {label: "Failed"} 180 TC.logger.log(result)
181 182 from tree import Node
183 -class TCNode(TC):
184 - def __init__(self): pass
185
186 - def compare(self, label, baseline, undertest):
187 """ 188 If baseline is None, simply check that undertest is a Node. 189 If baseline is a Node, check that it is equal to undertest. 190 """ 191 if baseline is not None and not isinstance(baseline, Node): 192 raise TypeError 193 194 if not isinstance(undertest, Node): 195 result = {label: "Failed - %s is not a Node" % undertest} 196 elif baseline is None: 197 result = {label: "Passed - %s is a Node" % undertest} 198 elif isinstance(baseline, Node): 199 if baseline == undertest: 200 result = {label: "Passed - %s == %s" % (baseline, undertest)} 201 else: result = {label: "Failed - %s != %s" % (baseline, undertest)} 202 TC.logger.log(result)
203 204 205 if __name__ == '__main__': 206 # import the test modules 207 import codecs 208 from utils import * 209 210 # Set up vars to use to test TC class 211 baseline = "test" 212 undertest = "test" 213 label = "unit test case 1.0" 214 encoding = "utf-8" 215 result = {} 216 217 # Create the TC instance 218 case1 = TC() 219 220 # Fire off the compaison 221 result = case1.compare(label, baseline, undertest, encoding) 222 223 # Print the result - should be label - passed 224 print(result) 225 226 # Reset variables for failure path 227 undertest = "testy" 228 encoding = "utf-8" 229 result = {} 230 label = "unit test case 1.1" 231 232 # Compare again 233 result = case1.compare(label, baseline, undertest, encoding) 234 235 # Print the result - should be label - failure 236 print(result) 237 238 # Create a TCString instance 239 case2 = TCString() 240 241 # Load our variables for this test 242 label = " unit test case 2.0" 243 encoding = "utf-8" 244 baseline = u"groß" 245 undertest = u"gro\xdf" 246 result = {} 247 248 # Fire off a UTF-8 compare 249 result = case2.compare(label, baseline, undertest, encoding) 250 251 # Print the result - should be label - passed 252 print(result) 253 254 # Fire the test for ASCII converted to UTF-8 testing 255 label = " unit test case 2.1" 256 encoding = "utf-8" 257 baseline = "please work" 258 undertest = "please work" 259 result = {} 260 261 result = case2.compare(label, baseline, undertest, encoding) 262 263 # Print the result - should be label - passed 264 print(result) 265 266 # Reset variables for an out of range encoding type 267 label = " unit test case 2.2" 268 encoding = "swahilli" 269 baseline = "please work" 270 undertest = "please work" 271 result = {} 272 273 result = case2.compare(label, baseline, undertest, encoding) 274 275 # Print the result - should be label - Error - not supported 276 print(result) 277 278 # Reset variables for unmatched utf-8 strings 279 label = " unit test case 2.3" 280 encoding = "utf-8" 281 baseline = u"groß" 282 undertest = "nomatch" 283 result = {} 284 285 # result = case2.compare(label, baseline, undertest, encoding) 286 287 # Print the result - should be label - failure 288 print(result) 289 290 # Reset variables for inherited TC base compare 291 label = " unit test case 2.4" 292 baseline = "This is inhereited" 293 undertest = "This is inhereited" 294 encoding = "utf-8" 295 result = {} 296 297 result = case2.compare(label, baseline, undertest, encoding) 298 299 # Print the result - should be label - Passed 300 print(result) 301 302 303 # Include real CJKI (UTF-8) charcters for string compare 304 # For this first test case, we are comparing same JA characters 305 label = " unit test case 2.5" 306 encoding = "utf-8" 307 baseline = u"あか" 308 undertest = u"あか" 309 result = {} 310 311 result = case2.compare(label, baseline, undertest, encoding) 312 313 # Print the result - should be label - Passed 314 print(result) 315 316 317 # Testing different JA characters 318 label = " unit test case 2.6" 319 encoding = "utf-8" 320 baseline = u"あか" 321 undertest = u"元気" 322 result = {} 323 324 result = case2.compare(label, baseline, undertest, encoding) 325 326 # Print the result - should be label - Failed 327 print(result) 328 329 330 331 # Test the timestamper class 332 # Create a new timestamp instance 333 # Print the file format time 334 stamp1 = TimeStamp() 335 presently = stamp1.fileStamp("filestamp") 336 337 # Print - should be filenameYYYYMMDD with local systems date 338 print presently 339 340 # Make a stamp entry 341 entry = stamp1.entryStamp() 342 343 # Print the entrystamp - should be YYYY-MM-DD_HH:MM:SS with local system time 344 print entry 345 346 # Copmare different colors 347 label = "unit test case 3.0" 348 baseline = "../examples/data/20w.png" 349 undertest = "../examples/data/20b.png" 350 result = {} 351 352 # Create a TCImage instance 353 case3 = TCImage() 354 355 # Fire off the compare 356 result = case3.compare(label, baseline, undertest) 357 358 # Print the result Should be label - Failed 359 print result 360 361 # Compare different sizes 362 label = "unit test case 3.1" 363 baseline = "../examples/data/20w.png" 364 undertest = "../examples/data/10w.png" 365 result = {} 366 367 # Fire off the compare 368 result = case3.compare(label, baseline, undertest) 369 370 # Print the result Should be label - Failed 371 print result 372 373 # Compare the same image 374 label = "unit test case 3.2" 375 baseline = "../examples/data/10w.png" 376 undertest = "../examples/data/10w.png" 377 result = {} 378 379 # Fire off the compare 380 result = case3.compare(label, baseline, undertest) 381 382 # Print the result Should be label - Passed 383 print result 384 385 # Number comparison tests 386 label = "unit test case 4.0" 387 baseline = 42 388 undertest = 42 389 type = "int" 390 result = {} 391 392 # Make a TCNumber instance 393 case4 = TCNumber() 394 395 # Make a simple int compare 396 result = case4.compare(label, baseline, undertest, type) 397 398 # Should be Passed 399 print result 400 401 # Now make the int fail 402 label = "unit test case 4.1" 403 undertest = 999 404 result = {} 405 406 result = case4.compare(label, baseline, undertest, type) 407 408 # Should fail 409 print result 410 411 # Now long pass 412 label = "unit test case 4.2" 413 baseline = 1112223334445556667778889990L 414 undertest = 1112223334445556667778889990L 415 type = "long" 416 result = {} 417 418 result = case4.compare(label, baseline, undertest, type) 419 420 # Should pass 421 print result 422 423 # Float Pass 424 label = "unit test case 4.3" 425 baseline = 99.432670 426 undertest = 99.432670 427 type = "float" 428 result = {} 429 430 result = case4.compare(label, baseline, undertest, type) 431 432 # Should pass 433 print result 434 435 # Complex pass 436 label = "unit test case 4.4" 437 baseline = 67+3j 438 undertest = 67+3j 439 type = "complex" 440 result = {} 441 442 result = case4.compare(label, baseline, undertest, type) 443 444 # Should pass 445 print result 446 447 # Octal pass 448 label = "unit test case 4.5" 449 baseline = 0400 450 undertest = 0400 451 type = "oct" 452 result = {} 453 454 result = case4.compare(label, baseline, undertest, type) 455 456 # Should pass 457 print result 458 459 # Hex pass 460 label = "unit test case 4.6" 461 baseline = 0x100 462 undertest = 0x100 463 type = "hex" 464 result = {} 465 466 result = case4.compare(label, baseline, undertest, type) 467 468 # Should pass 469 print result 470 471 # Conversion pass - pass in equivalent hex and octal but compare as int 472 label = "unit test case 4.7" 473 baseline = 0x100 474 undertest = 0400 475 type = "int" 476 result = {} 477 478 result = case4.compare(label, baseline, undertest, type) 479 480 # Should pass 481 print result 482 483 # Give a bogus type 484 label = "unit test case 4.8" 485 type = "face" 486 result = {} 487 488 result = case4.compare(label, baseline, undertest, type) 489 490 # Should fail - unsupported type 491 print result 492