The $3,000 Barcode Scanner Sitting on Every Developer's Desk (Or Not)
If you've ever implemented Odoo's Barcode or IoT modules for a warehouse client, you know the pain: you can't test what you can't plug in. Barcode scanners, electronic scales, label printers, cash drawers—these aren't the kind of peripherals that sit on a developer's home office desk.
The result? Developers write IoT integration code blind, push it to staging, and pray it works when the warehouse team plugs in real hardware. Spoiler: it usually doesn't. Not on the first try. Sometimes not on the fifth.
Odoo 19 changes this entirely. The new Mock IoT Driver Framework lets you simulate barcode scanners, scales, printers, and other peripherals directly on your Linux or macOS development machine—no hardware required. This post is a step-by-step guide to setting up a virtualized warehouse testing environment, written for the QA engineers and implementation partners who've been fighting this battle for years.
QA engineers testing warehouse flows remotely, Odoo implementation partners validating IoT integrations before on-site deployment, and developers building custom IoT drivers who need a fast feedback loop.
How Odoo 19 Decoupled IoT Drivers From Physical Hardware
In Odoo 18 and earlier, the IoT Box was a hard dependency. The hw_* driver modules (e.g., hw_escpos, hw_scale, hw_scanner) communicated directly with USB/serial devices through the IoT Box's Raspberry Pi. If you didn't have the physical chain—device → USB → IoT Box → network → Odoo—you couldn't test anything.
Odoo 19 introduces a driver abstraction layer that sits between the IoT module and the hardware interface. Each driver now implements a standardized IoTDriver base class with two concrete backends:
The production path. Communicates with real USB/serial devices through pyserial, python-escpos, and platform-specific libraries. Identical to Odoo 18 behavior.
The development/testing path. Simulates device responses using configurable JSON fixtures. Runs entirely in-process—no IoT Box, no USB, no network round-trip.
The backend is selected via the iot.driver.mode system parameter or the --iot-mock CLI flag. No code changes required to switch between real and simulated hardware.
The key architectural insight: mock drivers emit identical event payloads to real drivers. Your warehouse workflows, barcode processing logic, and scale reading handlers don't need separate test code paths—they receive the same data structures regardless of whether the input came from a physical scanner or a JSON fixture.
Setting Up a Virtualized Warehouse Testing Environment on Linux/macOS
Here's the setup we use at Octura Solutions for every warehouse implementation project. This gets your entire team—developers, QA, and even project managers—able to run full picking/packing/shipping flows without touching a single piece of hardware.
Step 1: Enable Mock IoT Mode
Start your Odoo 19 instance with the mock flag. This tells the IoT module to load mock backends instead of scanning for real USB devices.
# Start Odoo with mock IoT drivers enabled
./odoo-bin --addons-path=addons,enterprise \
--iot-mock \
-d my_warehouse_db
# Or set it permanently via system parameter:
# Settings → Technical → Parameters → System Parameters
# Key: iot.driver.mode
# Value: mockStep 2: Configure Mock Device Fixtures
Mock drivers read from JSON fixture files that define simulated device behavior. Create a mock_devices/ directory in your custom addons path.
{
"device_type": "scanner",
"device_name": "Mock Barcode Scanner",
"connection": "usb",
"responses": {
"scan": [
{"barcode": "5901234123457", "delay_ms": 200},
{"barcode": "LOT-2026-03-A1", "delay_ms": 150},
{"barcode": "WH/OUT/00042", "delay_ms": 300}
],
"mode": "sequential"
}
}{
"device_type": "scale",
"device_name": "Mock Warehouse Scale",
"connection": "serial",
"responses": {
"read_weight": {
"value": 2.450,
"unit": "kg",
"stable": true
},
"tare": {"value": 0.0, "unit": "kg", "stable": true}
}
}Step 3: Register Mock Devices in Odoo
Once mock mode is active, the IoT module auto-discovers your fixture files. Verify in IoT → Devices—you should see your mock scanner and scale listed with a [MOCK] badge.
# In a custom module's post_init_hook or test setUp:
from odoo.addons.iot.mock import MockDeviceRegistry
registry = MockDeviceRegistry(env)
registry.register_fixture('mock_devices/barcode_scanner.json')
registry.register_fixture('mock_devices/scale.json')
# Trigger a simulated scan event:
scanner = registry.get_device('Mock Barcode Scanner')
scanner.trigger('scan') # Emits first barcode in sequenceStep 4: Write Automated Test Scenarios
The real power is in automated testing. Here's a test case that validates a complete pick-pack-ship flow using mock devices:
from odoo.tests.common import TransactionCase
from odoo.addons.iot.mock import MockDeviceRegistry
class TestWarehouseIoTFlow(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.registry = MockDeviceRegistry(cls.env)
cls.scanner = cls.registry.register_fixture(
'mock_devices/barcode_scanner.json'
)
cls.scale = cls.registry.register_fixture(
'mock_devices/scale.json'
)
def test_pick_pack_ship_with_mock_scanner(self):
"""Full picking flow using simulated barcode scanner."""
# Create a delivery order
picking = self.env['stock.picking'].create({
'picking_type_id': self.env.ref(
'stock.picking_type_out'
).id,
'location_id': self.env.ref(
'stock.stock_location_stock'
).id,
'location_dest_id': self.env.ref(
'stock.stock_location_customers'
).id,
})
# Simulate scanning the picking barcode
self.scanner.trigger('scan', index=2)
# → Emits "WH/OUT/00042"
# Simulate scanning product barcode
self.scanner.trigger('scan', index=0)
# → Emits "5901234123457"
# Simulate weighing the package
weight = self.scale.trigger('read_weight')
self.assertEqual(weight['value'], 2.450)
self.assertTrue(weight['stable'])
# Validate the picking
picking.button_validate()
self.assertEqual(picking.state, 'done')Step 5: CI/CD Integration
Add IoT tests to your CI pipeline. Since mock drivers require no hardware, they run on any Linux CI runner—GitHub Actions, GitLab CI, Jenkins—without special configuration.
name: IoT Integration Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_PASSWORD: odoo
steps:
- uses: actions/checkout@v4
- name: Run IoT mock tests
run: |
./odoo-bin --iot-mock \
--test-tags /module.test_warehouse_iot \
--stop-after-init \
-d test_db Create fixture files per warehouse layout. If your client has 3 warehouses with different scale brands and label printer models, create mock_devices/wh_east/, mock_devices/wh_west/, etc. Your test suite can then validate each warehouse's specific hardware configuration independently.
IoT Testing: Odoo 18 vs. Odoo 19 Mock Framework
Here's what changes concretely for your development and QA workflows:
| Aspect | Odoo 18 (Old Way) | Odoo 19 (Mock Framework) |
|---|---|---|
| Hardware required | IoT Box + physical devices | None — JSON fixtures only |
| Setup cost per developer | $1,500–$3,000 (scanner + scale + IoT Box) | $0 |
| Test environment | On-site or hardware-shipped-to-dev | Any laptop (Linux/macOS) |
| CI/CD compatibility | Impossible without physical setup | Fully supported |
| Feedback loop | Days (ship code → test on-site) | Seconds (local test run) |
| Multi-device simulation | Buy each device model | One JSON file per device |
| Edge case testing | Extremely difficult (e.g., scale drift) | Trivial — edit fixture values |
| Remote team support | Ship hardware globally | Git clone and run |
3 Gotchas That Burn Implementation Teams (and How We Handle Them)
1. Mock Timing ≠ Real Timing
Mock barcode scans complete in milliseconds. Real scanners introduce 200–800ms latency depending on connection quality, Bluetooth pairing, and the IoT Box's processing load. If your UI code doesn't account for this, it will pass every mock test and fail spectacularly in the warehouse.
How we handle it: We configure delay_ms values in our fixture files to match measured latencies from the actual hardware the client will use. We also add a "stress test" fixture with 1,500ms delays and random timeouts to validate error handling paths.
2. Forgetting to Test the "Unhappy Path"
It's tempting to only simulate perfect scans and stable scale readings. But in a real warehouse, scanners misread barcodes, scales fluctuate before stabilizing, and printers jam mid-label. Mock fixtures make it trivially easy to simulate failure scenarios—but only if you actually write them.
How we handle it: Every fixture set at Octura includes three profiles: happy_path.json, error_path.json (bad reads, unstable weights, printer offline), and edge_case.json (very long barcodes, zero-weight items, special characters in lot numbers). Our test suites run against all three.
3. Mock-to-Production Config Drift
The biggest gotcha: your mock environment works perfectly, but the production IoT Box has different firmware, different serial port settings, or a different python-escpos version. The mock framework can't catch infrastructure-level mismatches.
How we handle it: We maintain a device_manifest.json per client that records exact firmware versions, serial port configurations, and driver versions for every physical device. Before go-live, we run a "manifest validation" script on the actual IoT Box that compares its real configuration against the manifest. Any drift gets flagged and resolved before it becomes a production incident.
What This Means for Your Budget and Timeline
For the CTO or project sponsor reading this, here's the translation from technical improvement to business impact:
A 5-person implementation team no longer needs duplicate hardware sets. At $2,000–$3,000 per developer kit (scanner + scale + IoT Box + label printer), that's $10,000–$15,000 saved per project—immediately.
IoT integration testing used to be a serial bottleneck—code had to wait for hardware access. With mock drivers, IoT tests run in parallel with the rest of development. Based on our implementations, this cuts 2–3 weeks from typical warehouse project timelines.
The #1 source of warehouse go-live issues? Untested IoT edge cases. With comprehensive mock tests, our clients see 60–70% fewer IoT-related support tickets in the first 30 days post go-live.
Your Odoo developers in Montreal, Bangalore, or Nairobi can now test warehouse flows from their laptops. No hardware shipping. No timezone-dependent lab access. No blocked sprints.
For a mid-size warehouse implementation ($80,000–$150,000 project value), the mock framework typically saves $15,000–$25,000 in hardware costs, developer idle time, and reduced on-site debugging visits. That's a 15–20% reduction in total project cost for IoT-heavy deployments.