Fault Injection
The interesting bugs in printing code are not in the happy path. They are in what happens when the paper runs out halfway through a receipt and the application reports success anyway.
Real hardware makes this awkward to stage: you have to physically open the cover, pull the roll, or unplug the network at the right moment. Here it is an HTTP call, which means it can run on every commit.
Hardware faults
curl -sf -X PATCH "$VP_API/printers/$PRINTER_ID/operational-flags" \
-H "Authorization: Bearer $ACCESS" \
-H 'Content-Type: application/json' \
-d '{"IsPaperOut": true}'
The flags available are IsPaperOut, IsPaperNearEnd, IsCoverOpen, IsOffline and HasError. Set
one, print, and assert on how your application reacts. Clear it by sending false.
What makes this more than a flag on a screen: the printer answers status requests accordingly. A
client that polls DLE EOT n, or reads Automatic Status Back, receives the status bytes a real printer
in that condition would send. If your application checks the printer before printing, this is what
exercises that code.
Taking the listener down
The same endpoint sets TargetState to Stopped or Started. A stopped printer refuses connections
outright, which is how you test the reconnect path - a different failure from a printer that is
reachable but not ready.
A slow printer
Real thermal printers have a small receive buffer and print slowly. A long receipt sent faster than the printer prints it fills that buffer, and what happens next is exactly the case worth testing.
Enable buffer emulation on the printer, giving it a capacity and a drain rate. The buffer then fills as bytes arrive and empties at the rate you set, and:
- a job that outruns the capacity is marked in the document with a buffer overflow, so a test can assert that the receipt did not survive intact;
- while the buffer holds data the printer reports itself busy, and reports full when it is at capacity, which is what a client polling the status sees;
- the buffered byte count is visible in the runtime status and on its live stream, so a test can watch it fill and drain.
The cash drawer
curl -sf -X PATCH "$VP_API/printers/$PRINTER_ID/drawers" \
-H "Authorization: Bearer $ACCESS" \
-H 'Content-Type: application/json' \
-d '{"Drawer1State": "Closed"}'
Drawer state is readable from the runtime status, and an ESC/POS pulse from your application opens the emulated drawer - enough to assert that the till opens when it should, and stays shut when it should not.
A worked order
A test for "the paper runs out mid-receipt" usually looks like this:
- Create the printer, print a normal receipt, assert it arrived.
- Set
IsPaperOut. - Print the next receipt.
- Assert your application surfaced an alert, retried, or queued the order - whatever it is supposed to do - rather than reporting success.
- Clear the flag and assert it recovers.
Step 4 is the one that finds real bugs.
Next pageESC/POS, EPL and TSPL →