def test_rotated(): # given an image that has been rotated image = PIL.open("tests/rotated.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then the message should be decoded assert barcode_count == 1 assert decoder.barcode_data_index_to_string(0) == "Rotated Image Test"
def test_upside_down(): # given an image that is upside down image = PIL.open("tests/upside_down.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then the message should be decoded assert barcode_count == 1 assert decoder.barcode_data_index_to_string(0) == "Upside Down Test"
def test_multiple_barcodes(): # given an image that has multiple barcodes image = PIL.open("tests/multiple_barcodes.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then multiple barcodes should be decoded assert barcode_count == 2 assert decoder.barcode_data_index_to_string(0) == "Multiple" assert decoder.barcode_data_index_to_string(1) == "Barcodes Test"
def test_missing_data(): # given an image that is upside down image = PIL.open("tests/missing_data.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then the message should be decoded assert barcode_count == 1 assert decoder.barcode_data_index_to_string( 0) == "Barcode with missing data codewords."
def test_against_zxing(): test_number = 0 success = 0 failure = 0 zxing_success = 0 zxing_failure = 0 while (True): test_number += 1 # Randomize barcode settings columns = 10 #random.randint(5,15) security_level = 3 #random.randint(2,5) scale = 2 #random.randint(2,5) ratio = 2 #random.randint(2,4) # With random text valid for a PDF417 barcode text_length = 300 #random.randint(1, 5) * 50 text = ''.join(random.choices(string.ascii_letters + string.digits + "&,:#-.$/+%* =^;<>@[\\]_'~!|()?{}", k=text_length)) # and Create the barcode. barcode = BarcodeTest(text, columns, security_level, scale, ratio) barcode.CrappifiedImage.save("barcode.png") # Start decoding try: reader = zxing.BarCodeReader() decodedZxing = reader.decode("barcode.png", possible_formats="PDF_417").parsed except: decodedZxing = '' try: decoder = PDF417Decoder(barcode.CrappifiedImage) barcode_count = decoder.decode() if (barcode_count == 0): decoded = '' else: decoded = decoder.barcode_data_index_to_string(0) except: decoded = '' if (decoded == barcode.EncodedData): success += 1 else: failure += 1 if (decodedZxing == barcode.EncodedData): zxing_success += 1 else: zxing_failure += 1 print(f"Success: {success} - Failure: {failure} - ZXing Success: {zxing_success} - ZXing: Failure {zxing_failure} - Total: {test_number}")
def test_byte_mode_data(): # given an image that has a barcode with a byte mode block image = PIL.open("tests/byte_mode.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then the message should match the expected binary data block assert barcode_count == 1 assert decoder.barcode_binary_data == bytearray( b"\x05\x01\xff\xff\x00\x00062S;Gp\x00\xf2\xed\x10\x00\x00\x14\x1e\x00VR3\x01Y3\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x02\x00\x00\\\xda\x00\x008034\xaeiW\rYB\x1c\xd4\x0b\x00\xf2\xd3\x7fO\xf8\xefiS\xa0\xaa\xfb\x9b\xcf0\x16\x13\xc3\x08>\x86Jz\xe8L\xfe\x1f\xebM,R\x05\x00o3\x01\x00" )
def test_binary_data(): # given an image that has a barcode with binary data image = PIL.open("tests/binary_data.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then the message should be decoded assert barcode_count == 1 assert decoder.barcode_data_index_to_string( 0 ) == "Pdf417DecoderDemo - Rev 1.0.0 - 2019-05-01 © 2019 Uzi Granot. All rights reserved."
def test_blurred(): # given an image that has errors due to blurring image = PIL.open("tests/blurred_error_correction.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then the message should be decoded assert barcode_count == 1 assert decoder.barcode_data_index_to_string( 0 ) == "Blurred Image Test: Additional data is being added to this test increase error count. ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"
def test_character_decodes(): # given an image that has a barcode with each character type transition # permutation (Upper, Lower, Mixed and Punctuation) image = PIL.open("tests/character_type_transitions.png") # when we decode the image decoder = PDF417Decoder(image) barcode_count = decoder.decode() # then the message should be decoded assert barcode_count == 1 assert decoder.barcode_data_index_to_string( 0 ) == "Character Type Switches Test: AaAAA1A@bbbBb1b@1c1C1111@@d@D@1@@A aA AA 1A @b bb Bb 1b @1 c1 C1 11 1@@ d@ D@ 1@ @"
def test_image(filepath, expected_decode): barcode = Image.open(filepath) decoder = PDF417Decoder(barcode) try: barcode_count = decoder.decode() if (barcode_count > 0): decoded = decoder.barcode_data_index_to_string(0) if (decoded == expected_decode): print("Success") else: print("Failure: Mismatch") print("Expected: " + expected_decode) print("Decoded : " + decoded) else: print("Failure: No barcode detected") except: print("Failure: Exception occurred")
def fuzz_testing(): # Collection of test result successes, failures and decode time for this test run. fields = ['Columns', 'Security Level', 'Scale', 'Ratio', 'Length', 'Successes', 'Failures', 'Average Decode Time'] test_results = list() test_number = 0 while (True): test_number += 1 # Randomize barcode settings columns = random.randint(5,15) security_level = random.randint(2,5) scale = random.randint(2,5) ratio = random.randint(2,4) # With random text valid for a PDF417 barcode text_length = 300 #random.randint(1, 5) * 50 text = ''.join(random.choices(string.ascii_letters + string.digits + "&,:#-.$/+%* =^;<>@[\\]_'~!|()?{}", k=text_length)) # and Create the barcode. barcode = BarcodeTest(text, columns, security_level, scale, ratio) # Search for existing configuration of above settings in test results. test_result = (0,0,0,0,0,0,0,0.0) for result in test_results: if (result[0] == columns and result[1] == security_level and result[2] == scale and result[3] == ratio and result[4] == text_length): test_result = result break # Create a new one if not found or remove it from the list if it was found. if (test_result[0] == 0): test_result == (columns, security_level, scale, ratio, text_length, 0, 0, 0.0) else: test_results.remove(test_result) # Start decoding decode_start_time = time.perf_counter() try: decoder = PDF417Decoder(barcode.CrappifiedImage) barcode_count = decoder.decode() if (barcode_count == 0): decoded = '' else: decoded = decoder.barcode_data_index_to_string(0) except: decoded = '' decode_stop_time = time.perf_counter() decode_time = round(decode_stop_time - decode_start_time, 2) # Record Success or Failure of decoding if (decoded == barcode.EncodedData): successes = test_result[5] + 1 failures = test_result[6] total = successes + failures total_decode = test_result[7] + decode_time avg_decode = round(total_decode / total, 2) print(f"SUCCESS #{successes} out of {total}: Columns: {columns} Security: {security_level} Scale: {scale} Ratio: {ratio} Length: {text_length} Average time to Decode: {avg_decode} seconds") # Add updated test result for this random barcode configuration back to the test results. test_results.append((columns, security_level, scale, ratio, text_length, successes, failures, total_decode)) else: successes = test_result[5] failures = test_result[6] + 1 total = successes + failures total_decode = test_result[7] + decode_time avg_decode = round(total_decode / total, 2) print(f"FAILURE #{failures} out of {total}: Columns: {columns} Security: {security_level} Scale: {scale} Ratio: {ratio} Length: {text_length} Average time to Decode: {avg_decode} seconds") # Add updated test result for this random barcode configuration back to the test results. test_results.append((columns, security_level, scale, ratio, text_length, successes, failures, total_decode)) # Save out failure image if necessary for debugging. #barcode.CrappifiedImage.save("errors/failure-" + str(failures) + "_columns-" + str(columns) + "_security-" + str(security_level) + "_ratio-" + str(ratio) + ".png") # Export test run results every 20 tests. if (test_number % 20 == 0): with open('test_results.csv', 'w') as f: # using csv.writer method from CSV package write = csv.writer(f) write.writerow(fields) write.writerows(test_results)