{"id":44289230,"url":"https://github.com/covemountainsoftware/cpputest-for-qpcpp","last_synced_at":"2026-02-10T23:10:22.186Z","repository":{"id":228617794,"uuid":"484180552","full_name":"covemountainsoftware/cpputest-for-qpcpp","owner":"covemountainsoftware","description":"CppUTest For QP/C++ implements a CppUTest port of the QP Framework, with supporting utilities, enabling easy host based unit testing of active objects.","archived":false,"fork":false,"pushed_at":"2025-06-14T13:35:24.000Z","size":112,"stargazers_count":17,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-14T13:42:27.586Z","etag":null,"topics":["active-object","cpputest","event-driven","hierarchical-state-machine","qactive","qp","qpcpp","state-machine","tdd","tdd-framework","unit-testing"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/covemountainsoftware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-04-21T19:31:51.000Z","updated_at":"2025-06-14T13:35:28.000Z","dependencies_parsed_at":"2024-03-19T17:49:23.594Z","dependency_job_id":"b02c1d30-310e-42ea-87e7-6431ef86d578","html_url":"https://github.com/covemountainsoftware/cpputest-for-qpcpp","commit_stats":null,"previous_names":["covemountainsoftware/cpputest-for-qpcpp"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/covemountainsoftware/cpputest-for-qpcpp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/covemountainsoftware%2Fcpputest-for-qpcpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/covemountainsoftware%2Fcpputest-for-qpcpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/covemountainsoftware%2Fcpputest-for-qpcpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/covemountainsoftware%2Fcpputest-for-qpcpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/covemountainsoftware","download_url":"https://codeload.github.com/covemountainsoftware/cpputest-for-qpcpp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/covemountainsoftware%2Fcpputest-for-qpcpp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29321280,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-10T20:44:44.282Z","status":"ssl_error","status_checked_at":"2026-02-10T20:44:43.393Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["active-object","cpputest","event-driven","hierarchical-state-machine","qactive","qp","qpcpp","state-machine","tdd","tdd-framework","unit-testing"],"created_at":"2026-02-10T23:10:21.575Z","updated_at":"2026-02-10T23:10:22.164Z","avatar_url":"https://github.com/covemountainsoftware.png","language":"C++","readme":"# CppUTest for the QP/C++ Real-Time Embedded Framework\n\nBuild and Test status: ![Build and Tests](https://github.com/covemountainsoftware/cpputest-for-qpcpp/actions/workflows/cmake.yml/badge.svg)\n\nCopyright Matthew Eshleman\n\nIf this project inspires your team to select the QP/C++ (qpcpp)\nframework for commercial use, please note \n\"Matthew Eshleman\" or \"Cove Mountain Software\" in the referral \nfield when acquiring a commercial license from Quantum Leaps. Referrals \nencourage and support efforts like this. Thank you!\n\n# Introduction\n\nThe `cpputest-for-qpcpp` library project enables CppUTest for the \nQP/C++ Real-Time Embedded Framework. This project provides for the \nfollowing capabilities:\n\n* A CppUTest compatible port of the QP/C++ (qpcpp) framework, \n  enabling host based unit and integration testing of QP active \n  objects (QActive). \n* Supporting utilities to simplify unit testing of qpcpp \n  based active objects. Provided classes may also be useful in \n  the final target software. \n* An example active object under test.\n\nBenefits of this approach to unit testing active objects include:\n* Tests are written in C++, the native language of the target\n  framework. This also happens to be my preferred language for \n  writing firmware too.\n* No surprises. The active object under test interacts with the \n  qpcpp framework, ensuring tested behavior will match target \n  behavior. The test support code provided in this project \n  enables precise control of when an active object executes within \n  the framework.\n* No surprises (again). There are no threads. Each test explicitly \n  'gives' CPU time to the active objects under test as needed by \n  each test.\n* Accelerated timer related testing. Seconds of 'time' can be \n  tested in microseconds.\n* Host based testing is fast. TDD (Test Driven Development) demands\n  fast execution of tests.\n* Host based testing is easier to use in a continuous integration (CI) \n  system. Run all the tests with every commit. No surprises when \n  it is time to generate a target release.\n\n# Tutorial Video\n\nA tutorial video on each of the features of this library is now available. This\nparticular video is on the QP/C version, however the lessons apply to this \nversion too: See https://youtu.be/hr1qkNH1wSA.\n\n# Environment\n\nThis project was developed and proven in Ubuntu, now 24.04. In theory any \nbuild or host operating system environment supported by CppUTest will \nbe compatible with this code.\n\n## Prerequisites\n\n* CMake and associated build tools were used to develop\n  and prove out this project.\n* QP/C++\n  * You can override the QP/C++ to another directory with your project's exact QP/C++ source code. \n    Define the cmake variable CMS_QPCPP_TOP_DIR before including the internal CMakeLists.txt. \n  * or:\n    * Do not define CMS_QPCPP_TOP_DIR, and the internal cmake will fetch the appropriate QP/C++ repo.\n* CppUTest (version 4.0, may still work with 3.8, but no longer being confirmed) \n* This project requires support for C++17.\n\n## Continuous Integration\n\nThis project has configured GitHub Actions to build and execute all\nunit tests found in this project. This is an example\nof one of the key benefits of host-based testing of embedded software.\n\nSee the configuration at: `.github/workflows/cmake.yml`\n\n# Testing Support\n\n## Restrictions\n\nThe CppUTest test support implemented in this project assumes host based \ntesting. Therefore, code found in these support files may use standard \nlibrary features requiring heap access, such as `std::vector`. Heap usage is \noftentimes avoided in firmware or embedded software. Such use is \nrestricted to the `cms::test` namespace.\n\nAdditionally, the CppUTest environment expects and requires C++ exceptions \nfor some test features. Again, these are restricted to the host based testing \nenvironment, as exceptions are frequently disabled in firmware build targets.\n\nCare was taken to avoid the above in any source code that may ultimately be \nre-used in an embedded project's target build.\n\n## Active object interfaces\n\nA typical active object within the QP/C++ framework may expose the following\ninterfaces:\n\n* May subscribe to known events published into the framework and react\n  to those events.\n* May react to events that are posted directly to the active object.\n* May expose a direct API, however such APIs traditionally provide only for\n  asynchronous behavior (i.e. the API creates an event and posts the event \n  to self.)\n* Time: the active object may repeat certain behavior using framework provided\n  timers, or may contain timeout related behavior, etc.\n\nUltimately, the active object is controlling something such\nas an external sensor, network device, LED, etc. The following\nprovides for some illustration.\n\n          Pub/Sub      Direct POST\n          Events         Events\n            +             +\n            |             |\n          +--+--------+-----+\n          |                 |\n          |  Active Object  |\n          |                 |\n          +-------+---------+\n                  |\n                  | Direct API calls\n                  |\n        +------------+-----------------+\n        |                              |\n        |  Some API / Module / Driver  |\n        |                              |\n        +------------------------------+\n\nThis project provides for methods enabling unit testing of event publish\nand subscribing behavior of the active object as well as timer related\nbehavior, using the exact same interfaces the active object would use\nin the production target. CppUTest provides for the mocking capabilities to \nensure that the active object under test is calling the expected APIs.\n\nWithin the associated examples project, please see the tests for `examples/hwLockCtrlService` which\nprovides examples of:\n* Testing for reaction to a published event, where the reaction is observed\n  through a CppUTest `mock()`.\n* Testing to ensure the active object published an expected event. This project\n  provides for functionality (`cms::test::PublishedEventRecorder`) to record all\n  events published during a test. The recorded events can be retrieved and verified \n  by the test.\n* Testing of time related behavior. This project provides for the ability to\n  `MoveTimeForward` within a test.\n* Direct POST of events and testing of direct POST responses. See\n  the example and search for the Ping/Pong related test, using the\n  support class `cms::test::DummyActiveObject`.\n\n## Testing Active Objects using CppUTest\n\nCppUTest support for testing active objects is provided by various files\nin the `test_support` subdirectory, especially `test_support/cpputest-qpcpp-port.`\n\nOf particular interest is the `cms::test:qf_ctrl` module, which \nprovides for convenience and helper methods such as:\n\n* `cms::test::qf_ctrl::Setup(...)` - call this from a test's `setup()` method \n  to prepare for active object testing.\n* `cms::test::qf_ctrl::Teardown()` - call this from a test's `teardown()` method \n  to perform various actions, including testing for memory pool leaks.\n* `cms::test::qf_ctrl::ProcessEvents()` - call this to 'give' some CPU time to \n  any active objects under test. This is a critical feature of this testing\n  approach.\n* `cms::test::qf_ctrl::MoveTimeForward(...)` - call this to advance 'time',\n  potentially activating any internal active object timers. Many seconds,\n  minutes, or hours, of time may be tested with this approach in a few \n  milliseconds of host CPU time.\n* `cms::test::qf_ctrl::PublishEvent(...)` - convenience method enabling \n  publishing of events from a test.\n* `cms::test::qf_ctrl::PublishAndProcess(...)` - additional convenience methods,\n  combining publish and process steps. These functions also help to automatically\n  ignore a test published event when using a published event recorder.\n* `class cms::test::PublishedEventRecorder` - an active object that records\n  events published into the framework. Useful when a test expects an\n  active object under test to publish an event.\n\n## The basic active object test pattern\n\nTo create tests for an active object, the following outline is considered:\n\n1. Implement the `setup()` handler for the test. Initialize the QF framework as \n   desired using `cms::test::qf_ctrl::Setup(...)`.\n2. Instantiate or otherwise initialize the active object under test.\n3. `start` the active object under test, perhaps as part of the `setup`\n   or as a separate step.\n4. Prep a single test.\n5. Prepare a CppUTest mock() or other resources as needed for the test.\n6. Stimulate the unit under test as appropriate. For example, publish an \n   event into the framework that the active object is expected to be subscribed to \n   and expected to respond to in some manner.\n7. Give the unit under test some CPU time via `cms::test::qf_ctrl::ProcessEvents()` or\n   the equivalent. See also `cms::test::qf_ctrl::MoveTimeForward(...)`.\n8. Confirm how the unit under test responded. Did it call the `mock()` as expected? Did\n   it publish a response into the framework? What data do I need to inspect for changes?\n\nThat is it! That is the basic pattern for testing an active object. See  \nexamples at: `examples/hwLockCtrlService/test/hwLockCtrlServiceTests.cpp` to\nlearn more.\n\nOther tips:\n* Avoid internal state knowledge as much as possible. This allows for internal\n  state machine refactoring without impacting the tests. \n* Follow best practices in your test code, especially follow the DRY principle.\n\n# Other Utilities\n\nThis project provides for various utility classes that may be useful \nwithin a project's final target build as well. Notable classes include:\n\n* `class cms::QEvtUniquePtr` is a template class enabling a std::unique_ptr RAII like \n  behavior for QP::QEvt events, ensuring such events are garbage collected per the \n  framework's requirements. This class is used by the `PublishedEventRecorder`.\n* `class cms::OrthogonalComponent` provides a base class pattern to help implement\n  this common Orthogonal Component pattern in qpcpp. I hope to add concrete examples\n  of using this class in a future revision of this project.\n* `class cms::OrthogonalContainer` provides a template class to create an active object\n  container with one or more OrthogonalComponent objects, standardizing \n  what is frequently a manually created pattern. I hope to add concrete examples\n  of using this class in a future revision of this project, however the tests for \n  this class should guide anyone wanting to make use of this useful pattern in \n  their product.\n\n# Acknowledgements\n\nI must take a moment to thank key influences that inspired or helped\nenable this project:\n\n* Miro Samek and his book and frameworks. \n    Learn more at: https://www.state-machine.com/\n* James Grenning and his book on TDD. \n    Learn more at: https://wingman-sw.com/\n* The CppUTest project: https://cpputest.github.io/\n\n# License\n\nAll code in this project found in the `cms` namespace follows a dual-license approach.\nPlease see LICENSE.txt for details.\n\nAll licenses for external source code and libraries relied upon by this project \nremain fully owned by their respective owners. In particular, please\nsee the licensing details for qpcpp at: https://www.state-machine.com/licensing.\n\nIf this project inspires your team to select the qpcpp framework for commercial \nuse, please note \"Matthew Eshleman\" or \"Cove Mountain Software\" in the referral\nfield when acquiring a commercial license from Quantum Leaps. Referrals encourage \nand support this effort. Thank you!\n\n# References\n\nA top level example project using this library is maintained here:\nhttps://github.com/covemountainsoftware/cpputest-for-qpcpp-examples\n\nThis project started from a non-qpcpp example, see this blog post:\nhttps://covemountainsoftware.com/2020/04/17/unit-testing-active-objects-and-state-machines/\n\nAdditionally, please see that post's associated github repo:\nhttps://github.com/covemountainsoftware/activeObjectUnitTestingDemo\n\nOther references:\n* Sutter, Herb. Prefer Using Active Objects Instead of Naked Threads. Dr. Dobbs, June 2010.\n* Grenning, James. Test Driven Development for Embedded C.\n* Samek, Miro. Practical UML Statecharts in C/C++: Event-Driven Programming for Embedded Systems.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcovemountainsoftware%2Fcpputest-for-qpcpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcovemountainsoftware%2Fcpputest-for-qpcpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcovemountainsoftware%2Fcpputest-for-qpcpp/lists"}