Barcode Scanning Testing Checklist (2026)
Barcode Scanning Testing Checklist (2026)
Barcode Scanning Testing Checklist (2026)
A practical, item‑by‑item guide for verifying that a barcode scanner works correctly in every situation a user might encounter. Use this checklist to plan manual tests, automate regression suites, and validate that autonomous exploration tools can catch the majority of issues in a single pass.
1. Happy Path Scenarios
These tests confirm that the core scanning flow works when everything is ideal.
1.1. Valid symbology detection
- Objective: Ensure the decoder recognises all supported barcode types (UPC‑A, UPC‑E, EAN‑8, EAN‑13, Code 128, Code 39, QR Code, Data Matrix, PDF417, Aztec).
- Pass criteria: Each symbology is decoded within 500 ms and returns the exact payload encoded in the symbol.
- Example: Print a UPC‑A barcode containing “012345678905”. Point the scanner at it; the app should display “012345678905” and enable the “Add to cart” button.
- Automation tip: Use an image asset bundle with one file per symbology. In an Appium test, load each image into a mock camera feed (see code snippet below) and assert the decoded text matches the file name.
// Appium Java – mock camera feed with a static bitmap
@Test
public void testUPCA() throws Exception {
File img = new File("src/test/resources/upca_012345678905.png");
driver.setCameraImage(img); // custom extension provided by SUSA agent
MobileElement result = driver.findElement(By.id("scan_result"));
assertEquals("012345678905", result.getText());
}
1.2. Correct data parsing
- Objective: Verify that the scanner applies the correct parsing rules (e.g., GS1 application identifiers, FNC1 handling in Code 128).
- Pass criteria: Parsed fields match the specification; no truncation or extra characters.
- Example: A GS1‑128 barcode encodes
(01)09501101530014(17)200615(10)ABC123. The app should show separate fields: GTIN = 09501101530014, expiration = 2020‑06‑15, batch = ABC123. - Test data: Use the GS1 General Specifications test set (available free from GS1.org) and compare each field with a reference parser.
1.3. UI feedback on successful scan
- Objective: Confirm that the user receives clear, accessible feedback when a scan succeeds.
- Pass criteria: Visual cue (checkmark, green border), haptic vibration (if enabled), and an audible tone (if not muted) occur within 200 ms of decode.
- Example: After scanning a QR code that contains a URL, the app shows a toast “Link opened: https://example.com” and navigates to the browser.
- Verification: Use Espresso/UiAutomator to assert the toast text and check that
AccessibilityEvent.TYPE_ANNOUNCEMENTis fired.
1.4. Multi‑code batch scanning
- Objective: Ensure the scanner can read several barcodes presented sequentially without manual reset.
- Pass criteria: Each code is decoded, stored, and the UI updates to reflect the count (e.g., “3 items scanned”).
- Example: A warehouse worker scans three pallet labels in quick succession; the app displays a list with three entries and allows bulk confirmation.
- Automation: Loop through a set of images, feeding each to the mock camera, and assert that the list size increments correctly.
2. Error Handling and Validation
These items check how the app reacts when something goes wrong.
2.1. Invalid or corrupted barcodes
- Objective: The app must gracefully handle symbols that fail checksum or have illegal patterns.
- Pass criteria: Shows an error message (“Unable to read barcode”) and does not crash. No partial data is accepted.
- Example: Print a Code 128 barcode with a deliberately wrong checksum. Scanning yields a red error banner and the scan button stays enabled.
- Test: Generate corrupted symbols using a barcode library (e.g., ZXing) by flipping random bits in the payload.
2.2. Unsupported symbology
- Objective: When a barcode type is not in the whitelist, the app should ignore it and inform the user.
- Pass criteria: No false positive; a toast “Barcode type not supported” appears.
- Example: Scan a MaxiCode symbol (often used in logistics) while the app only supports 1D codes. Expect the unsupported message.
- Edge: Verify that the scanner does not enter a tight loop consuming CPU.
2.3. No barcode in frame
- Objective: The scanner should not freeze when the viewfinder finds nothing.
- Pass criteria: After 2 seconds of no detection, the UI returns to idle state; optional “Tap to try again” hint appears.
- Example: Point the camera at a blank wall; after a brief pause the scan button label changes back to “Scan”.
- Automation: Feed a constant gray frame to the mock camera and assert that no result element appears.
2.4. Partial occlusion
- Objective: Determine tolerance for barcodes partially covered by fingers, stickers, or glare.
- Pass criteria: Up to 30 % occlusion is still decoded correctly; beyond that, a clear error is shown.
- Example: Place a semi‑transparent tape over the middle of a QR code; the app still reads it. Fully covering three modules yields an error.
- Method: Use image editing software to mask portions of a barcode image and test each level.
2.5. Low contrast / glare
- Objective: Ensure performance under poor lighting or reflective surfaces.
- Pass criteria: With a contrast ratio of at least 3:1 (per WCAG AA) the scanner succeeds; below that it fails gracefully.
- Example: Scan a barcode printed on glossy photo paper under direct sunlight; the app shows a glare warning and suggests adjusting angle.
- Tool: Use a light meter app to measure luminance and correlate with success/failure.
3. Edge / Boundary Cases
These tests push the scanner to its limits and uncover rare production bugs.
3.1. Extremely small / large barcodes
- Objective: Verify decoding of symbols at the minimum and maximum printable sizes.
- Pass criteria:
- Smallest: 0.8 mm module width (UPC‑E) still reads at 15 cm distance.
- Largest: 100 mm module width (industrial Code 128) reads at up to 2 m.
- Example: Print a UPC‑E on a 2 mm × 2 mm label; scan with a smartphone macro lens. Expect success.
- Note: Test with both fixed focus and autofocus cameras.
3.2. High density / QR code versions
- Objective: Confirm support for QR versions up to 40 (177 × 177 modules) and high‑error‑correction levels.
- Pass criteria: All versions decode; error correction recovers data when up to 30 % of modules are damaged.
- Example: Generate a QR‑Code v40 containing a 2 KB JSON payload; introduce random black/white noise covering 25 % of the area; the app still returns the original JSON.
- Automation: Use ZXing’s
QRCodeWriterwithErrorCorrectionLevel.Hand iterate versions.
3.3. Rotated / skewed images
- Objective: The scanner must tolerate rotation (0‑360°) and perspective skew.
- Pass criteria: Successful decode within 800 ms for rotations up to 45°; skewed up to 20° still works.
- Example: Print a barcode, photograph it from a 30° angle; the app decodes correctly.
- Implementation: Rotate the test bitmap in the mock camera feed before feeding it to the scanner.
3.4. Mirrored barcodes
- Objective: Some scanners mistakenly read mirrored images as valid; ensure this does not happen.
- Pass criteria: Mirrored symbols are rejected with an error (or, if the spec allows, produce the same data but flagged as mirrored).
- Example: Flip a Data Matrix horizontally; scanning yields “Unable to read barcode”.
- Why: Prevents accidental acceptance when using front‑facing camera preview.
3.5. Barcodes on curved surfaces
- Objective: Verify decoding when the symbol is wrapped around a cylinder or sphere.
- Pass criteria: Curvature up to 30° radius (approx. 30 mm diameter) still yields a correct read.
- Example: Print a QR code on a 50 mm diameter bottle; scan from various angles; success rate > 90 %.
- Tip: Use a 3‑D printed jig to hold the object at fixed distances during automated testing.
3.6. Different lighting conditions (IR, UV)
- Objective: Some industrial scanners may use infrared or UV illumination; ensure the app’s camera pipeline does not break.
- Pass criteria: No crash; if the camera cannot focus due to lack of visible light, show a “Low light” hint.
- Example: In a dark warehouse, enable the phone’s torch; the scanner still works. With torch off and no ambient light, the app displays a warning.
- Automation: Adjust the mock camera’s brightness/contrast parameters and assert appropriate UI messages.
3.7. Scanning from video stream vs still image
- Objective: The decoder should handle both live preview frames and static pictures (e.g., from gallery).
- Pass criteria: Same success rate for both inputs; latency difference < 100 ms for still image.
- Example: User selects a saved screenshot of a barcode; the app decodes it instantly.
- Test: Feed a sequence of frames (video) and a single frame (image) to the decoder and compare results.
4. Accessibility Checks
Ensure the scanner works for users with disabilities and complies with WCAG 2.2.
4.1. TalkBack / VoiceOver announcements
- Objective: All relevant states (scanning, success, error) must be announced.
- Pass criteria:
- Scanning started → “Scanning, point camera at barcode”.
- Success → “Barcode read, [content]”.
- Error → “Unable to read barcode”.
- Test: Enable TalkBack, perform a scan, and capture the spoken output via
adb shell service call accessibility 12 i32 0.
4.2. Sufficient touch target size for scan button
- Objective: Minimum 48 dp × 48 dp touch area.
- Pass criteria: Measured with Android Studio’s Layout Inspector or iOS Accessibility Inspector.
- Example: If the button is 40 dp, increase padding or replace with a larger icon.
4.3. Color contrast for UI elements
- Objective: Foreground/background contrast ≥ 4.5:1 for normal text, ≥ 3:1 for large text.
- Pass criteria: Use a contrast checker; fix any failures.
- Example: Red error text on orange background fails; change to white on red passes.
4.4. Alternative input methods (voice command to start scan)
- Objective: Users who cannot touch the screen can start scanning via voice.
- Pass criteria: Saying “Hey [App], start scan” triggers the scanner; the command is recognized even when the app is in background (if permitted).
- Test: Use Android’s Voice Access or iOS Siri Shortcuts to invoke a custom intent.
4.5. Screen reader labels for results
- Objective: The decoded value must be focusable and readable by a screen reader.
- Pass criteria: Result text has
contentDescription(Android) oraccessibilityLabel(iOS) set to the barcode payload. - Example: After scanning a QR code that contains a vCard, the screen reader reads “BEGIN:VCARD…END:VCARD”.
5. Security and Privacy Considerations
Barcodes can carry malicious payloads; the app must defend against injection and data leaks.
5.1. Preventing injection via barcode data
- Objective: Ensure that data extracted from a barcode is not directly executed as code or query.
- Pass criteria: All output is treated as untrusted string; SQL, shell, or script execution uses parameterized calls.
- Example: Encode a SQL injection string
'; DROP TABLE users;--in a Code 128 barcode. The app should display the literal string, not affect the database. - Test: Use a fuzzing payload list (OWASP XSS Filter Evasion Cheat Sheet) and verify no execution occurs.
5.2. Sanitizing output for SQL/XSS
- Objective: If the decoded value is shown in a web view or inserted into a DB, apply proper escaping.
- Pass criteria: HTML entities are escaped; SQL statements use prepared statements.
- Example: A QR code containing
appears as plain text in aTextView; no script runs. - Verification: Use a WebView with
addJavascriptInterfacedisabled and check thatonConsoleMessagedoes not fire.
5.3. Rate limiting to avoid scanning abuse
- Objective: Throttle rapid successive scans to prevent DoS on backend services.
- Pass criteria: After 5 scans within 2 seconds, the app shows “Please slow down” and ignores further scans for 3 seconds.
- Test: Send a burst of barcode images via mock camera and count accepted results.
5.4. Ensuring no PII leakage in logs
- Objective: Debug logs must not contain raw barcode data that could be personal (e.g., loyalty IDs).
- Pass criteria: Log statements redact or hash payloads; only metadata (symbology, timestamp) is logged.
- Example:
Log.d("Scan", "Symbology: QR, Length: 28")– no actual data appears. - Check: Run the app with
adb logcatand grep for known test payloads; ensure none appear.
5.5. Secure storage of scanned data
- Objective: If the app persists scanned values (e.g., for history), they must be encrypted at rest.
- Pass criteria: Use Android Keystore or iOS Keychain; files are AES‑256 encrypted.
- Test: Root the device, pull the app’s private folder, and attempt to read the history file; it should be unreadable without the key.
6. Performance and Resource Usage
These checks guarantee the scanner does not degrade the host device’s usability.
6.1. Scan latency benchmarks
- Objective: Measure end‑to‑end time from frame capture to result display.
- Pass criteria: 90 th percentile ≤ 600 ms on mid‑tier devices (Snapdragon 7 Gen 2, iPhone 13).
- Method: Use
Systraceor Xcode Instruments to timestamponPreviewFrameand UI update. - Example: On a Pixel 7 a, average latency is 420 ms; on a low‑end Mediatek Helio G25 it is 780 ms (fail → consider lowering resolution).
6.2. CPU / memory impact
- Objective: Ensure the decoder does not cause spikes that affect other UI elements.
- Pass criteria: Average CPU usage < 15 % on a single core; memory increase < 10 MB during scanning session.
- Tool: Android Studio Profiler, Instruments → Allocations.
- Example: Continuous scanning for 30 seconds shows a steady 8 % CPU and 6 MB heap growth.
6.3. Battery consumption during continuous scanning
- Objective: Quantify drain when the camera is kept on for extended periods (e.g., inventory scanning).
- Pass criteria: ≤ 5 % battery per hour on a 3000 mAh device with screen at 50 % brightness.
- Method: Run
adb shell dumpsys batterystats --reset, scan for 1 hour, then read drain. - Result: If drain is 8 %, consider lowering preview frame rate to 10 fps or using hardware‑accelerated YUV conversion.
6.4. Network usage if cloud‑based decoding
- Objective: Some apps offload decoding to a server; ensure bandwidth stays reasonable.
- Pass criteria: Average upload ≤ 30 KB per frame; no more than 2 frames/second sent unless user opts for high‑accuracy mode.
- Test: Use
Charles Proxyormitmproxyto capture traffic while scanning a QR code.
6.5. Frame drop rate on video feed
- Objective: The preview should remain smooth; dropped frames cause jerky UX.
- Pass criteria: < 2 % frame drop rate measured via
Camera2callbacks. - Example: On a device with thermal throttling, frame drops rise to 7 % → reduce preview size from 1080p to 720p.
7. Compatibility and Device Matrix
Validate that the scanner works across the hardware and software variations your users encounter.
7.1. Camera resolutions and focus modes
- Objective: Test with various preview sizes (480p, 720p, 1080p) and focus settings (fixed, auto, macro).
- Pass criteria: Decode success ≥ 95 % across all combinations.
- Method: Programmatically set
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAPin Android orAVCaptureSessionpresets in iOS.
7.2. Different Android/iOS versions
- Objective: Ensure no regression when the OS updates camera APIs or permissions model.
- Pass criteria: Same behavior on Android 12‑14 and iOS 16‑18.
- Test matrix: Use Firebase Test Lab (Android and Xcode Cloud to run the same test suite on each OS version.
7.3. External barcode scanners (USB, Bluetooth)
- Objective: If the app supports hardware wedges, verify they emulate keyboard input correctly.
- Pass criteria: Scanning a barcode with a Bluetooth scanner types the exact payload into the focused edit field, followed by an Enter key.
- Example: Pair a Zebra DS2200, focus a search bar, scan a Code 39; the app receives the string and triggers search.
7.4. Emulator vs real device
- Objective: Emulators are useful for CI but may lack camera fidelity.
- Pass criteria: All logic‑only tests pass in emulator; camera‑dependent tests are skipped or use a mock frame provider.
- Tip: Use the SUSA agent’s virtual camera feature to feed predefined images into emulator tests.
7.5. Cross‑platform web (Playwright) testing
- Objective: For progressive web apps that access
navigator.mediaDevices.getUserMedia, ensure the scanner works in Chrome/Firefox/Safari. - Pass criteria: Same latency and error handling as native.
- Example: Playwright script launches a page, grants camera permission, loads a test image via
page.evaluate(() => { navigator.mediaDevices.getUserMedia = … }), then asserts the result element.
// Playwright – mock video stream with a static canvas
test('web scanner reads QR', async ({ page }) => {
await page.goto('/scanner');
await page.evaluate(() => {
const stream = new MediaStream([
new CanvasCaptureMediaStream(
document.createElement('canvas')
).getVideoTracks()[0]
]);
return navigator.mediaDevices.getUserMedia = () => Promise.resolve(stream);
});
await page.waitForSelector('#result:has-text("HELLO")');
});
8. Release Readiness and Regression
Final steps before shipping a build to ensure the scanner stays reliable.
8.1. Automated test suite coverage
- Objective: Aim for ≥ 80 % line coverage on the decoding module and ≥ 70 % on UI layer.
- Pass criteria: CI fails if coverage drops below threshold.
- Tool: JaCoCo for Android,
llvm-covfor iOS,nycfor JavaScript/web.
8.2. Baseline image set for visual regression
- Objective: Detect unintended changes to the scanner UI (e.g., button moved, color altered).
- Pass criteria: No pixel difference > 2 % in the scan screen baseline.
- Method: Use Percy or Applitools; upload reference screenshots from a approved build.
8.3. Flaky test detection
- Objective: Identify tests that randomly pass/fail due to timing or camera noise.
- Pass criteria: Flakiness score < 1 % (computed by rerunning each test 20 times).
- Action: Replace sleep‑based waits with explicit conditions (
Espresso IdlingResource,WebDriverWait).
8.4. Release notes verification
- Objective: Confirm that any change to the scanning library is documented.
- Pass criteria: Every version bump of ZXing, ML Kit, or custom decoder appears in the changelog with a short impact note.
- Process: Automate a diff of
build.gradle/Podfileand require a matching entry inRELEASE.md.
8.5. Monitoring in production (canary)
- Objective: Catch regressions that only appear under real‑world load.
- Pass criteria: Canary release shows < 0.1 % increase in scan failure rate and no spike in ANR reports.
- Tool: Firebase Crashlytics + Performance Monitoring; set alerts on
scan_errorevents.
9. How Autonomous Exploration (SUSA) Covers This Checklist
Autonomous QA platforms can exercise many of the items above without writing test scripts manually.
9.1. Overview of SUSA agent behavior
The SUSA agent explores an app by treating the UI as a state machine: it taps buttons, enters text, handles dialogs, and, crucially, activates the camera preview when it encounters a scan‑initiating element. While exploring, it can:
- Inject custom image frames into the camera stream (via a provided hook).
- Vary lighting, focus, and zoom parameters programmatically.
- Record the decoded output and assert against expected values.
- Simulate different user personas (e.g., “impatient” taps rapidly, “elderly” uses longer presses).
9.2. Mapping checklist items to autonomous actions
| Checklist area | SUSA capability | Example action |
|---|---|---|
| Happy path – valid symbology | Load a bitmap into mock camera, trigger scan, verify result | Agent places a UPC‑A image, presses scan, checks that the result text matches the payload |
| Error handling – corrupted barcode | Generate corrupted bitmap on‑the‑fly, feed to camera, assert error message | Agent flips random bits in a Code 128 image, triggers scan, ensures “Unable to read” toast appears |
| Edge case – rotation | Rotate the bitmap by arbitrary degrees before injection | Agent rotates a QR code 30°, scans, confirms success |
| Accessibility – TalkBack | Enable accessibility service, capture spoken feedback | Agent turns on TalkBack, initiates scan, logs utterances and verifies they contain expected strings |
| Security – injection | Supply a barcode containing SQL/JavaScript payload, observe that it is rendered as plain text | Agent creates a Code 39 with ' OR 1=1 --, scans, asserts that the result view does not execute script |
| Performance – latency | Timestamp frame injection and result display, compute delta | Agent records System.nanoTime() before and after scan, logs latency; fails if > 800 ms |
| Release readiness – visual regression | Capture screenshot of scan screen after each successful scan, compare to baseline | Agent stores PNG, runs perceptual diff, flags if > 2 % change |
9.3. Example: generating Appium/Playwright scripts from a session
After an autonomous run, SUSA can export the sequence of interactions as reusable test code. For a barcode flow, the output might look like:
// Exported Appium test (Java)
@Test
public void testUpcaHappyPath() {
// set up mock camera image
File upca = new File("src/test/assets/upca_012345678905.png");
driver.setCameraImage(upca);
// tap scan button
driver.findElement(By.id("btn_scan")).click();
// wait for result
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
WebElement result = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("scan_result"))
);
assertEquals("012345678905", result.getText());
}
For a web‑based scanner, the exported Playwright script mirrors the actions shown earlier.
9.4. Benefits and limitations
- Benefits:
- One autonomous session can hit > 70 % of the checklist items (happy path, several error cases, a few edge cases, accessibility, and basic security checks).
- Continuous learning means the agent remembers which image inputs caused failures and prioritizes them in subsequent runs.
- No need to maintain a large matrix of manual test cases; the agent generates them on demand from the UI it discovers.
- Limitations:
- The agent cannot yet synthesize novel lighting spectra (e.g., IR) without explicit hardware hooks; those must be added as custom actions.
- Complex business‑logic validation (e.g., verifying that a decoded GTIN matches a product database) still requires domain‑specific assertions that the agent may not infer automatically.
- Camera permission handling varies across OEM skins; the agent may need a small amount of device‑specific configuration to reliably open the preview.
Despite these gaps, coupling autonomous exploration with a targeted manual/scripted suite for the remaining items yields a fast feedback loop while keeping coverage high.
10. Quick Reference Checklist (One‑Page)
Copy this into your test‑plan markdown or spreadsheet. Tick each item as you verify it.
- [ ] Happy Path
- [ ] All supported symbologies decode correctly
- [ ] Data parsing (GS1, AIM, etc.) matches spec
- [ ] UI feedback (visual, haptic, sound) appears ≤ 200 ms
- [ ] Batch scanning updates list and allows bulk actions
- [ ] Error Handling
- [ ] Invalid/corrupted barcodes show error, no crash
- [ ] Unsupported symbology yields clear message
- [ ] No‑barcode state returns to idle after timeout
- [ ] Partial occlusion ≤ 30 % still works
- [ ] Low contrast/graceful failure under glare
- [ ] Edge / Boundary
- [ ] Extremely small (≥ 0.8 mm module) and large (≤ 100 mm module) symbols read
- [ ] High‑density QR (v40) with error correction succeeds
- [ ] Rotation 0‑45° and skew ≤ 20° tolerated
- [ ] Mirrored symbols rejected
- [ ] Curved surface up to 30° radius readable
- [ ] IR/UV lighting handled with appropriate hints
- [ ] Video stream and still image give same results
- [ ] Accessibility
- [ ] TalkBack/VoiceOver announces start, success, error
- [ ] Scan button ≥ 48 dp touch target
- [ ] Color contrast ≥ 4.5:1 (text) / 3:1 (large)
- [ ] Voice command can launch scanner
- [ ] Result text has proper contentDescription/label
- [ ] Security & Privacy
- [ ] Barcode data treated as untrusted (no injection)
- [ ] HTML/SQL output escaped or parameterized
- [ ] Rate limiting after rapid scans
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free