Open-source project
ThrowTheSwitch/Unity avatar
ThrowTheSwitch/Unity

ThrowTheSwitch/Unity: a C unit testing framework for embedded toolchains

Simple unit testing for C

5,394 stars1,135 forksCMIT

At a glance

What is it?
Unity ships as one C file and two headers, so it drops into an existing Make or CMake build without a package manager. It is aimed at microcontroller code, and its assertion set is built around fixed-width integers, bit masks and floats.
Who is it for?
Adopt Unity if you write C for microcontrollers and want assertions that already understand int8 through int64, bit masks and float deltas without pulling in a test runner dependency. Do not adopt it if you expect the framework to generate mocks, manage your build or produce reports on its own; the README points to Ceedling for that work.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 20 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What problem Unity solves for C code on microcontrollers

C projects that target microcontrollers usually cannot borrow the test harnesses that desktop languages take for granted. The test binary has to cross-compile, the runner has to fit in the same build system as the firmware, and the assertions have to talk about types the hardware actually uses: 8-bit counters, 32-bit registers, bit fields, floats.

Unity is built for that situation. The README describes it as "a unit testing framework built for C, with a focus on working with embedded toolchains" and says it is "made to test code targetting microcontrollers big and small". The intended reader is an embedded engineer who already has a Makefile or CMakeLists.txt and does not want a dependency manager in the loop.

The design decision that follows from that audience is size. The README states that "the core project is a single C file and a pair of headers", which is why the repository has a src/ directory rather than a package manifest at its centre. You add the files, you compile them, you are testing.

How the single-file framework and its assertion macros work

There is no daemon, no plugin host and no test discovery service. A test file includes the Unity header, calls assertion macros, and the runner executes the test functions you registered. The framework lives in src/, and the repository layout shows a test/ directory for Unity's own tests, an auto/ directory, and examples/example_1 through examples/example_5 alongside examples/unity_config.h.

The assertion set is where the embedded focus shows. Integer comparisons come in sized variants: TEST_ASSERT_EQUAL_INT8 through TEST_ASSERT_EQUAL_INT64 and the matching UINT family, plus HEX variants where the size controls how many nibbles are printed. Bitwise assertions (TEST_ASSERT_BITS, TEST_ASSERT_BITS_HIGH, TEST_ASSERT_BITS_LOW, TEST_ASSERT_BIT_HIGH, TEST_ASSERT_BIT_LOW) let you test a register against a mask instead of against a whole value, and the README notes the bit index is specified 0-31 for a 32-bit integer.

Floats get delta-based comparisons rather than exact equality: TEST_ASSERT_FLOAT_WITHIN and TEST_ASSERT_DOUBLE_WITHIN take a delta, and TEST_ASSERT_EQUAL_FLOAT passes when the two values are within a small percentage of the expected value. Arrays are handled by appending _ARRAY to a macro and passing an element count, or by _EACH_EQUAL to check every element against one value. A custom unity_config.h, present in examples/, is the hook for project-specific configuration.

The README does not document the runner's internals, so treat the assertion reference as the contract and the source as the fallback.

Getting Unity into a build and writing a first test

The README gives no package manager command. It says the core is a C file and a pair of headers that you add "to your existing build setup", and that you "may use any compiler you wish, and may use most existing build systems including Make, CMake, etc." The repository also carries meson.build, platformio-build.py, library.json and unityConfig.cmake, which tells you which build systems the project itself supports.

The practical install is a copy. Take the files from src/ into your project and compile them with your test file. The README's own example of a test macro is a comparison:

c
TEST_ASSERT_EQUAL_INT(expected, actual)

The array form is documented with an element count, and the README uses this example:

c
TEST_ASSERT_EQUAL_HEX8_ARRAY(expected, actual, elements)

What you should see when the runner executes is failures reported with the values involved; the HEX variants print in hexadecimal and the sized variants print at the width you chose. If your project needs custom configuration, examples/unity_config.h shows the file to copy and adjust. The README also points new users at the getting started guide in docs/.

Where Unity is the wrong tool, and what the README leaves open

Unity is a test framework, not a build tool. The README says so directly: "If you'd like to leave the hard work to us, you might be interested in Ceedling, a build tool also by ThrowTheSwitch.org." If your expectation is automatic test discovery, dependency injection, mock generation or coverage reporting from one command, Unity alone does not provide it, and the README routes you elsewhere rather than pretending otherwise.

The second boundary is the assertion model. There is no mention of a mocking facility in the README. Testing a function that calls into hardware means you supply your own stubs or link against a fake; the framework will not generate them. The same applies to anything that needs a host process, a network listener or a database: Unity's assertions are about values in C, and the README's examples stay inside that world.

One more thing to notice is what the documentation does not cover. The README summarises assertions and links to docs/UnityAssertionsReference.md for "the full list", and mentions a change log and known issues in the documentation. It does not document a rollback procedure, a versioning policy, or what changed between v2.6.0, v2.6.1 and v2.7.0. If you need that, the release notes and the change log are the places to look, not this README.

Unity compared with a general-purpose C test runner

The obvious alternative for C is a general-purpose test framework that expects a hosted operating system, a package manager and a discovery mechanism. The difference in approach is not the assertion vocabulary; it is where the framework assumes it is running.

Unity's assumption is the one the README states: microcontrollers, any compiler, most existing build systems, and a core that is a single C file plus headers. A hosted test framework typically assumes it can allocate, fork, write files and be installed as a dependency. On a target with kilobytes of RAM those assumptions are the problem, not the feature set. That is why the sized integer macros and the bitwise assertions matter here: they match the widths the target actually uses, and a HEX8 comparison prints four nibbles because that is the size you asked for.

The trade-off runs the other way too. A hosted framework usually brings richer reporting and fixture management out of the box. Unity's answer to that is Ceedling, a separate project, which means the convenience is not in this repository.

Maintenance, releases and the MIT licence

The repository is not archived and the last push was on 2026-09-10, so the project is being touched. Releases are infrequent rather than continuous: v2.6.0 on 2024-03-10, v2.6.1 on 2025-01-01, and v2.7.0 on 2026-07-16. That cadence matters for upgrade planning. If you vendor src/ into your tree, you control when you move; if you track tags, expect long gaps between them and read the change log before jumping.

The upgrade cost itself is low by construction. Because the core is one C file and two headers, an upgrade is a file replacement plus a recompile, and any local edits to a copied unity_config.h are the thing most likely to conflict. That is a real risk worth tracking in your own repository.

Unity is MIT licensed. For most commercial firmware that is a permissive arrangement, but the licence text is in LICENSE.txt and the obligations it states are the ones that apply; this article is not legal advice, and if your organisation has a policy on vendored third-party source, the file to read is that one.

Editorial conclusion

Adopt Unity if you write C for microcontrollers and want assertions that already understand int8 through int64, bit masks and float deltas without pulling in a test runner dependency. Do not adopt it if you expect the framework to generate mocks, manage your build or produce reports on its own; the README points to Ceedling for that work. Before committing, verify that your toolchain compiles src/ unchanged, decide whether you need a custom unity_config.h, and read docs/UnityAssertionsReference.md for the full macro list, since the README only summarises it.

Frequently asked questions

How do I install Unity for a C project?

There is no package manager step in the README. You add the core C file and the pair of headers from src/ to your existing build setup, and the README states you may use any compiler and most existing build systems including Make and CMake.

Does Unity work with embedded toolchains and microcontrollers?

Yes, that is the stated focus. The README describes Unity as built for C "with a focus on working with embedded toolchains" and says it is made to test code targeting microcontrollers big and small.

What assertion macros does Unity provide for integers and floats?

Integers have sized variants from TEST_ASSERT_EQUAL_INT8 to TEST_ASSERT_EQUAL_INT64 and the matching UINT and HEX families, plus bitwise macros such as TEST_ASSERT_BITS and TEST_ASSERT_BIT_HIGH. Floats use delta-based comparisons like TEST_ASSERT_FLOAT_WITHIN and TEST_ASSERT_EQUAL_FLOAT, which passes within a small percentage of the expected value.

Does Unity generate mocks or manage the build for me?

The README does not describe a mocking facility, and it points readers who want the build work handled to Ceedling, a separate build tool by ThrowTheSwitch.org.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. ThrowTheSwitch/Unity on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/throwtheswitch-unity.svg)](https://hysenlabs.com/projects/throwtheswitch-unity)