HOW UNITY WORKS
Unity is most obviously about assertions. Assertions are statements of what we expect to be true about our embedded system. At their most basic, they are things like this:
int a = 1;
TEST_ASSERT( a == 1 ); //this one will pass
TEST_ASSERT( a == 2 ); //this one will fail
You could use nothing but the TEST_ASSERT above, and you could test almost anything that your C code can handle... but when something went wrong, you'd see something like this:
TestMyModule.c:15:test_One:FAIL
While correct, it's not terribly informative. There are two ways to fix this. The brute force method (good for your non-standard corner cases):
TEST_ASSERT_MESSAGE( a == 2 , "a isn't 2, end of the world!");
which results in:
TestMyModule.c:15:test_one:FAIL:a isn't 2, end of the world!
And then there is the elegant solution, using Unity's multitude of pretty assertions:
TEST_ASSERT_EQUAL_INT(2, a);
TEST_ASSERT_EQUAL_HEX8(5, a);
TEST_ASSERT_EQUAL_UINT16(0x8000, a);
Which, if run in separate tests, would lead to the following failures:
TestMyModule.c:15:test_One:FAIL:Expected 2 was 1
TestMyModule.c:23:test_Two:FAIL:Expected 0x05 was 0x01
TestMyModule.c:31:test_Three:FAIL:Expected 32768 was 1
Isn't that nice? The first argument is the expected value. The second argument is the value you are testing. It's printed clearly in a format that is most convenient to you, the test writer. In fact, Unity can handle all sorts of types, not just integers.
TEST_ASSERT_EQUAL_FLOAT( 3.45, pi );
TEST_ASSERT_EQUAL_STRING( "Attention, Dr. Surly", greeting );
It can even handle situations where you want a custom message added, where you want to check a full array, or both!
TEST_ASSERT_EQUAL_INT_ARRAY( expArray, actualArray, numElements );
TEST_ASSERT_EQUAL_INT_MESSAGE( 5, val, "Not five? Not alive!" );
TEST_ASSERT_EQUAL_INT_ARRAY_MESSAGE( e, a, 20, "Oh snap!" );
One or more of these lovely assertions go into each test. A test is just a C function that takes no arguments and returns nothing. By convention, it starts with the word "test" or "spec":
void test_FunctionUnderTest_should_ReturnFive(void) {
TEST_ASSERT_EQUAL_INT( 5, FunctionUnderTest() );
TEST_ASSERT_EQUAL_INT( 5, FunctionUnderTest() ); //twice even!
}
A single test file will usually have multiple tests. Most often, one test file is used to test all aspects of a corresponding C source file. This can be made most clear with a simple naming convention: Where do you find the tests for MadScience.c? In TestMadScience.c, of course!