@@ -360,15 +360,155 @@ mic.stop()
360360level = mic.sound_level(samples) # Sound level in dB
361361```
362362
363+ ## Testing
364+
365+ The project includes a test framework that supports both mock tests (without hardware) and hardware tests (with a STeaMi board connected).
366+
367+ ### Install test dependencies
368+
369+ ``` bash
370+ pip install pytest pyyaml
371+ ```
372+
373+ ### Run mock tests (no hardware needed)
374+
375+ ``` bash
376+ python -m pytest tests/ -v -k mock
377+ ```
378+
379+ ### Run hardware tests (STeaMi board connected)
380+
381+ ``` bash
382+ python -m pytest tests/ -v --port /dev/ttyACM0
383+ ```
384+
385+ ### Run tests for a specific driver
386+
387+ ``` bash
388+ python -m pytest tests/ -v --driver hts221 --port /dev/ttyACM0
389+ ```
390+
391+ ### Run interactive tests (with manual validation)
392+
393+ ``` bash
394+ python -m pytest tests/ -v --port /dev/ttyACM0 -s
395+ ```
396+
397+ ### Generate a test report
398+
399+ Reports are saved as Markdown files in the ` reports/ ` directory, with a summary and a detailed sub-report per driver.
400+
401+ ``` bash
402+ # Timestamped report
403+ python -m pytest tests/ -v --port /dev/ttyACM0 --report auto
404+
405+ # Named report (e.g. before a release)
406+ python -m pytest tests/ -v --port /dev/ttyACM0 --report v1.0-validation
407+ ```
408+
409+ ### Add tests for a new driver
410+
411+ Create a YAML scenario file in ` tests/scenarios/<driver>.yaml ` :
412+
413+ ``` yaml
414+ driver : hts221
415+ driver_class : HTS221
416+ i2c_address : 0x5F
417+
418+ i2c :
419+ id : 1
420+
421+ mock_registers :
422+ 0x0F : 0xBC
423+
424+ tests :
425+ - name : " Verify device ID"
426+ action : read_register
427+ register : 0x0F
428+ expect : 0xBC
429+ mode : [mock, hardware]
430+
431+ - name : " Temperature in plausible range"
432+ action : call
433+ method : temperature
434+ expect_range : [10.0, 45.0]
435+ mode : [hardware]
436+ ` ` `
437+
438+ The test runner automatically discovers new YAML files.
439+
363440## Contributing
364441
365- Contributions are welcome! Here's how you can contribute:
442+ Contributions are welcome! Please follow the guidelines below.
443+
444+ ### Driver structure
445+
446+ Each driver must follow this structure:
447+
448+ ` ` `
449+ lib/<component>/
450+ ├── README.md
451+ ├── manifest.py # metadata() + package("<module_name>")
452+ ├── <module_name>/
453+ │ ├── __init__.py # exports main class
454+ │ ├── const.py # register constants using micropython.const()
455+ │ └── device.py # main driver class
456+ └── examples/
457+ └── *.py
458+ ```
459+
460+ ### Coding conventions
461+
462+ - ** Constants** : use ` from micropython import const ` in ` const.py ` files.
463+ - ** Naming** : ` snake_case ` for new methods. Legacy ` camelCase ` is acceptable for I2C helpers to stay consistent with existing drivers.
464+ - ** Class inheritance** : ` class Foo(object): ` is the existing convention.
465+ - ** Time** : use ` from time import sleep_ms ` (not ` utime ` ).
466+ - ** No debug ` print() ` ** in production driver code.
467+
468+ ### Linting
469+
470+ The project uses [ ruff] ( https://docs.astral.sh/ruff/ ) (config in ` pyproject.toml ` ).
471+
472+ ``` bash
473+ # Check for linting errors
474+ ruff check
475+
476+ # Auto-format code
477+ ruff format
478+ ```
479+
480+ ### Commit messages
481+
482+ Commit messages are validated by CI with the following pattern:
483+
484+ ```
485+ <scope>: <Description starting with a capital letter ending with a period.>
486+ ```
487+
488+ - Max 78 characters.
489+ - Examples:
490+ - ` hts221: Fix missing self parameter in getAv method. `
491+ - ` docs: Fix typos in README files. `
492+ - ` bq27441: Remove debug print statements from driver. `
493+
494+ ### CI checks
495+
496+ All pull requests must pass these checks:
497+
498+ | Check | Workflow | Description |
499+ | -------| ----------| -------------|
500+ | Commit messages | ` check-commits.yml ` | Validates commit message format |
501+ | Linting | ` python-linter.yml ` | Runs ` ruff check ` |
502+ | Mock tests | ` tests.yml ` | Runs mock driver tests |
503+
504+ ### Workflow
366505
3675061 . Fork the repository
368- 2 . Create a branch for your feature (` git checkout -b my-new-feature ` )
369- 3 . Commit your changes (` git commit -am 'Add a new feature' ` )
370- 4 . Push to the branch (` git push origin my-new-feature ` )
371- 5 . Create a new Pull Request
507+ 2 . Create a branch for your feature (` git checkout -b feat/my-new-feature ` )
508+ 3 . Write your code and add tests in ` tests/scenarios/<driver>.yaml `
509+ 4 . Run ` ruff check ` and ` python -m pytest tests/ -v -k mock ` locally
510+ 5 . Commit your changes following the commit message format
511+ 6 . Push to the branch and create a Pull Request
372512
373513## License
374514
0 commit comments