RFC: How to Test MicroPython
Posted: Fri May 13, 2022 11:06 pm
Hi All,
I decided to explore firmware, Micropython and the Pico MCU several months ago. Coming from a pure software background I wanted to have automated test coverage for as much as possible, so I started working with UnitTest. I further wanted: 1) to run tests in MP, not in CPython to minimize divergence 2) have tests run in Continuous Integration 3) Not have have to deploy to the Pico and do manual QA, or at least to do this only for final integration testing.
Right away I ran into the problem that the machine module was not defined on my Ubuntu dev environment, and so I stubbed out the main classes/methods. This seems like a common problem to anyone using UnitTest, for example in the PicoCat project which also emphasizes testing. Doing that much allows one to write unit tests around logic that doesn't do any IO. I wanted to take it further however and start validating that pins were being controlled in the correct way. That led me to mock out a sizeable chunk of the machine module in ways that would capture IO traffic on the pins and support test assertions.
Here's 'machine': https://github.com/djantzen/pico_book/b ... machine.py
Here's a simple example blinking an LED: https://github.com/djantzen/pico_book/b ... er_test.py
Here's a test of an LCD screen: https://github.com/djantzen/pico_book/b ... cd_test.py
Here's an I2C test for a temperature sensor: https://github.com/djantzen/pico_book/b ... x0_test.py
Here's an SPI test for a ESP32 wifi co-processor: https://github.com/djantzen/pico_book/b ... ol_test.py
All of the tests run now locally before I push code to the Pico, and in a GitHub Workflow after a commit and push.
My question is: does anyone else find this useful or is it just me wanting to do this kind of testing during development??
I'd love to hear some feedback from more seasoned firmware developers on this approach.
Thank you for your time,
David
I decided to explore firmware, Micropython and the Pico MCU several months ago. Coming from a pure software background I wanted to have automated test coverage for as much as possible, so I started working with UnitTest. I further wanted: 1) to run tests in MP, not in CPython to minimize divergence 2) have tests run in Continuous Integration 3) Not have have to deploy to the Pico and do manual QA, or at least to do this only for final integration testing.
Right away I ran into the problem that the machine module was not defined on my Ubuntu dev environment, and so I stubbed out the main classes/methods. This seems like a common problem to anyone using UnitTest, for example in the PicoCat project which also emphasizes testing. Doing that much allows one to write unit tests around logic that doesn't do any IO. I wanted to take it further however and start validating that pins were being controlled in the correct way. That led me to mock out a sizeable chunk of the machine module in ways that would capture IO traffic on the pins and support test assertions.
Here's 'machine': https://github.com/djantzen/pico_book/b ... machine.py
Here's a simple example blinking an LED: https://github.com/djantzen/pico_book/b ... er_test.py
Here's a test of an LCD screen: https://github.com/djantzen/pico_book/b ... cd_test.py
Here's an I2C test for a temperature sensor: https://github.com/djantzen/pico_book/b ... x0_test.py
Here's an SPI test for a ESP32 wifi co-processor: https://github.com/djantzen/pico_book/b ... ol_test.py
All of the tests run now locally before I push code to the Pico, and in a GitHub Workflow after a commit and push.
My question is: does anyone else find this useful or is it just me wanting to do this kind of testing during development??
I'd love to hear some feedback from more seasoned firmware developers on this approach.
Thank you for your time,
David