{"id":18240663,"url":"https://github.com/mcloughlan/ArduinoUnitPlatformIO","last_synced_at":"2025-10-29T15:31:25.841Z","repository":{"id":258183472,"uuid":"873509158","full_name":"Sandwich1699975/ArduinoUnitPlatformIO","owner":"Sandwich1699975","description":"My template for using ArduinoUnit unit tests with Platform IO","archived":false,"fork":false,"pushed_at":"2024-11-21T03:33:43.000Z","size":15618,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-22T06:40:56.736Z","etag":null,"topics":["arduino","embedded","platformio","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sandwich1699975.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-16T09:36:30.000Z","updated_at":"2024-11-21T03:33:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"2032f936-3b5b-4f2d-8816-2df6deb3695e","html_url":"https://github.com/Sandwich1699975/ArduinoUnitPlatformIO","commit_stats":null,"previous_names":["sandwich1699975/aunitpio","sandwich1699975/arduinounitplatformio"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sandwich1699975%2FArduinoUnitPlatformIO","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sandwich1699975%2FArduinoUnitPlatformIO/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sandwich1699975%2FArduinoUnitPlatformIO/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sandwich1699975%2FArduinoUnitPlatformIO/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sandwich1699975","download_url":"https://codeload.github.com/Sandwich1699975/ArduinoUnitPlatformIO/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238845389,"owners_count":19540330,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","embedded","platformio","unit-testing"],"created_at":"2024-11-05T05:04:14.175Z","updated_at":"2025-10-29T15:31:24.440Z","avatar_url":"https://github.com/Sandwich1699975.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ArduinoUnit PlatformIO Integration\n\n![PlatformIO](https://img.shields.io/badge/PlatformIO-%23222.svg?style=for-the-badge\u0026logo=platformio\u0026logoColor=%23f5822a)\n![Python](https://img.shields.io/badge/python-3670A0?style=for-the-badge\u0026logo=python\u0026logoColor=ffdd54)\n![Espressif](https://img.shields.io/badge/espressif-E7352C.svg?style=for-the-badge\u0026logo=espressif\u0026logoColor=white)\n\n**My template** for using [`arduinounit`](https://github.com/mmurdoch/arduinounit) in [PlatformIO](https://platformio.org/) with a [logic analyser](https://core-electronics.com.au/usb-logic-analyzer-24mhz-8-channel.html) and with a custom ESP-32S2 based board.\n\n\u003e [!NOTE]  \n\u003e This repo was originally for [`AUnit`](https://github.com/bxparks/AUnit) but I needed the `MockStream` object so I converted to ArdunioUnit.\n\u003e **If you want to use `AUnit`, you see see their tutorial on migrating from ArduinoUnit [here](https://github.com/bxparks/AUnit?tab=readme-ov-file#ArduinoUnitCompatible)** or see the minimal changes I made myself in [#1](https://github.com/Sandwich1699975/AUnitPlatformIO/pull/1)\n\n\u003cdiv align=\"center\"\u003e\n    \u003ctable style=\"margin: 0 auto;\"\u003e\n        \u003ctr\u003e\n            \u003ctd style=\"text-align: center;\"\u003e\n                \u003cimg src=\"assets/setup.png\" alt=\"Annotated hardware setup\" width=\"300\"\u003e\n                \u003cbr\u003e\n                Annotated hardware setup\n            \u003c/td\u003e\n            \u003ctd style=\"text-align: center;\"\u003e\n                \u003cimg src=\"assets/flowchart.png\" alt=\"System flowchart\" width=\"500\"\u003e\n                \u003cbr\u003e\n                System flowchart\n            \u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/table\u003e\n\u003c/div\u003e\n\n\n\nFor those looking to implement their own version of ArduinoUnit with PlatformIO, I wish you the best of luck. This was incredibly complex to get working. My method also uses a [physical logic analyser](https://core-electronics.com.au/usb-logic-analyzer-24mhz-8-channel.html) and [Saleae's Logic2 application](https://www.saleae.com/pages/downloads?srsltid=AfmBOop1eoIiGSyJggODsT0lgRuMeX46d3sEPPDvJscgZumQkeUSdmga) to make this work well with: physical testing, software compatibility and development. If you don't have a logic analyser, you will need some sort of way to read the serial data from the board and pipe it into the the [custom test runner](https://docs.platformio.org/en/latest/advanced/unit-testing/frameworks/custom/runner.html) which is located in `test/**/test_custom_runner.py`.\n\n## Summary\n\nTo run a test, use the provided [PIO test hierarchy](https://docs.platformio.org/en/stable/advanced/unit-testing/structure/hierarchy.html#test-hierarchy) and try to minimise the amount of separate test files. Each test file `*.cpp` will be compiled and flashed inividually which takes a while. So make sure you can fit in as much as you can in the one flash to avoid 10 minute test runs. \n\nIn each test, you are using **just** [ArduinoUnit](https://github.com/mmurdoch/arduinounit). This is the methodology and [hierarchy](https://docs.platformio.org/en/latest/advanced/unit-testing/structure/hierarchy.html) for creating tests:\n\n0. Install python test dependencies\n    - `source ~/.platformio/penv/bin/activate` then  `pip install logic2-automation`\n1. Create a test in a folder prefixed with `test_`\n    - This requires a `.cpp` file with the ArduinoUnit software that runs all tests in that file with the `Test::run` command.\n2. Run the PIO test\n\n### Python Runner\n\nThis implementation uses a [python handler/runner](https://docs.platformio.org/en/latest/advanced/unit-testing/frameworks/custom/runner.html) which must be called `test_custom_runner.py`. \n\nThis file is a generic bridge to parse the results of each test. PIO will search each directory and parent directory until it has reached the root of `test_dir`. This means each test can have custom handlers with precedence. At the moment, only a generic one is needed in the `embedded/` folder to handle all those test cases.\n\nThis Python file will then connect to your logic analyser software ([Logic2](https://saleae.github.io/logic2-automation/index.html)) and create raw and high-level ASCII CSV analysis files. After those files are created by the logic analyser, the PIO `test_custom_runner.py` file will then scrape that output for the ArduinoUnit success and failure messages. That data is then formatted with the PIO test cases class and presented in the rich report. \n\n## Known Limitations \n\n- This method with the Logic2 API does not run concurrently. The Unity test system and the Logic API are totally disjointed. The recording starts then begins a race condition with the Unity scraper (which sucks). This seems to require a rebuild of the API or some sort of custom local hosted server to fix this (the logic recording is not written to a file until it's finished). It's currently not a big issue and does not warrant a change this big. A simple delay on the Python or hardware side can account for timing issues if needed.\n    - Due to the race condition, ESP boot messages over serial are not accounted for because they are consistently skipped by timeout anyway\n- Some `TestCase` attributes are not printing. I can't see `message` or `TestCaseSource` for some reason\n\n## Troubleshooting\n\n**Getting import errors**\n\n- Make sure you have installed the python dependencies as listed in the summary section above. \n- Make sure your python interpreter is selected as `~/.platformio/penv/bin/python`.\n\n**No test cases or no summary file**\n\n- Make sure baud rate is correct\n\n## Todo List\n\n- Stop the recording once the tests have finished [link](https://saleae.github.io/logic2-automation/automation.html#saleae.automation.CaptureConfiguration) and [method to use](https://saleae.github.io/logic2-automation/automation.html#manualcapturemode). This will have to be done by stopping it manually while parsing when the summary line is detected\n    - This may be impossible with current API\n- Test if this works on another computer\n- Note: Continuous capturing is only available with a [HLA](https://github.com/saleae/logic2-automation/issues/4) it seems. This would also require another system to export back and fourth from logic and unity. Probably not worth it. \n- Test with more complex ArduinoUnit test outputs\n\nExample **ArduinoUnit** output for reference:\n\n```\nDummy test 1\nTest exampleTest1 passed.\nMOCK_OUTPUT: value? 10*10=100\nTest exampleTest2 passed.\nSerial output prefixed with no newlineTest exampleTest3 passed.\nTest summary: 3 passed, 0 failed, and 0 skipped, out of 3 test(s).\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcloughlan%2FArduinoUnitPlatformIO","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcloughlan%2FArduinoUnitPlatformIO","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcloughlan%2FArduinoUnitPlatformIO/lists"}