261 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			261 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Unity Helper Scripts
 | |
| 
 | |
| ## With a Little Help From Our Friends
 | |
| 
 | |
| Sometimes what it takes to be a really efficient C programmer is a little non-C.
 | |
| The Unity project includes a couple of Ruby scripts for making your life just a tad
 | |
| easier. They are completely optional. If you choose to use them, you'll need a
 | |
| copy of Ruby, of course. Just install whatever the latest version is, and it is
 | |
| likely to work. You can find Ruby at [ruby-lang.org](https://ruby-labg.org/).
 | |
| 
 | |
| 
 | |
| ### `generate_test_runner.rb`
 | |
| 
 | |
| Are you tired of creating your own `main` function in your test file? Do you
 | |
| keep forgetting to add a `RUN_TEST` call when you add a new test case to your
 | |
| suite? Do you want to use CMock or other fancy add-ons but don't want to figure
 | |
| out how to create your own `RUN_TEST` macro?
 | |
| 
 | |
| Well then we have the perfect script for you!
 | |
| 
 | |
| The `generate_test_runner` script processes a given test file and automatically
 | |
| creates a separate test runner file that includes ?main?to execute the test
 | |
| cases within the scanned test file. All you do then is add the generated runner
 | |
| to your list of files to be compiled and linked, and presto you're done!
 | |
| 
 | |
| This script searches your test file for void function signatures having a
 | |
| function name beginning with "test" or "spec". It treats each of these
 | |
| functions as a test case and builds up a test suite of them. For example, the
 | |
| following includes three test cases:
 | |
| 
 | |
| ```C
 | |
| void testVerifyThatUnityIsAwesomeAndWillMakeYourLifeEasier(void)
 | |
| {
 | |
|   ASSERT_TRUE(1);
 | |
| }
 | |
| void test_FunctionName_should_WorkProperlyAndReturn8(void) {
 | |
|   ASSERT_EQUAL_INT(8, FunctionName());
 | |
| }
 | |
| void spec_Function_should_DoWhatItIsSupposedToDo(void) {
 | |
|   ASSERT_NOT_NULL(Function(5));
 | |
| }
 | |
| ```
 | |
| 
 | |
| You can run this script a couple of ways. The first is from the command line:
 | |
| 
 | |
| ```Shell
 | |
| ruby generate_test_runner.rb TestFile.c NameOfRunner.c
 | |
| ```
 | |
| 
 | |
| Alternatively, if you include only the test file parameter, the script will copy
 | |
| the name of the test file and automatically append "_Runner" to the name of the
 | |
| generated file. The example immediately below will create TestFile_Runner.c.
 | |
| 
 | |
| ```Shell
 | |
| ruby generate_test_runner.rb TestFile.c
 | |
| ```
 | |
| 
 | |
| You can also add a [YAML](http://www.yaml.org/) file to configure extra options.
 | |
| Conveniently, this YAML file is of the same format as that used by Unity and
 | |
| CMock. So if you are using YAML files already, you can simply pass the very same
 | |
| file into the generator script.
 | |
| 
 | |
| ```Shell
 | |
| ruby generate_test_runner.rb TestFile.c my_config.yml
 | |
| ```
 | |
| 
 | |
| The contents of the YAML file `my_config.yml` could look something like the
 | |
| example below. If you're wondering what some of these options do, you're going
 | |
| to love the next section of this document.
 | |
| 
 | |
| ```YAML
 | |
| :unity:
 | |
|   :includes:
 | |
|     - stdio.h
 | |
|     - microdefs.h
 | |
|   :cexception: 1
 | |
|   :suit_setup: "blah = malloc(1024);"
 | |
|   :suite_teardown: "free(blah);"
 | |
| ```
 | |
| 
 | |
| If you would like to force your generated test runner to include one or more
 | |
| header files, you can just include those at the command line too. Just make sure
 | |
| these are _after_ the YAML file, if you are using one:
 | |
| 
 | |
| ```Shell
 | |
| ruby generate_test_runner.rb TestFile.c my_config.yml extras.h
 | |
| ```
 | |
| 
 | |
| Another option, particularly if you are already using Ruby to orchestrate your
 | |
| builds - or more likely the Ruby-based build tool Rake - is requiring this
 | |
| script directly. Anything that you would have specified in a YAML file can be
 | |
| passed to the script as part of a hash. Let's push the exact same requirement
 | |
| set as we did above but this time through Ruby code directly:
 | |
| 
 | |
| ```Ruby
 | |
| require "generate_test_runner.rb"
 | |
| options = {
 | |
|   :includes => ["stdio.h", "microdefs.h"],
 | |
|   :cexception => 1,
 | |
|   :suite_setup => "blah = malloc(1024);",
 | |
|   :suite_teardown => "free(blah);"
 | |
| }
 | |
| UnityTestRunnerGenerator.new.run(testfile, runner_name, options)
 | |
| ```
 | |
| 
 | |
| If you have multiple files to generate in a build script (such as a Rakefile),
 | |
| you might want to instantiate a generator object with your options and call it
 | |
| to generate each runner afterwards. Like thus:
 | |
| 
 | |
| ```Ruby
 | |
| gen = UnityTestRunnerGenerator.new(options)
 | |
| test_files.each do |f|
 | |
|   gen.run(f, File.basename(f,'.c')+"Runner.c"
 | |
| end
 | |
| ```
 | |
| 
 | |
| #### Options accepted by generate_test_runner.rb:
 | |
| 
 | |
| The following options are available when executing `generate_test_runner`. You
 | |
| may pass these as a Ruby hash directly or specify them in a YAML file, both of
 | |
| which are described above. In the `examples` directory, Example 3's Rakefile
 | |
| demonstrates using a Ruby hash.
 | |
| 
 | |
| 
 | |
| ##### `:includes`
 | |
| 
 | |
| This option specifies an array of file names to be `#include`'d at the top of
 | |
| your runner C file. You might use it to reference custom types or anything else
 | |
| universally needed in your generated runners.
 | |
| 
 | |
| 
 | |
| ##### `:suite_setup`
 | |
| 
 | |
| Define this option with C code to be executed _before any_ test cases are run.
 | |
| 
 | |
| Alternatively, if your C compiler supports weak symbols, you can leave this
 | |
| option unset and instead provide a `void suiteSetUp(void)` function in your test
 | |
| suite.  The linker will look for this symbol and fall back to a Unity-provided
 | |
| stub if it is not found.
 | |
| 
 | |
| 
 | |
| ##### `:suite_teardown`
 | |
| 
 | |
| Define this option with C code to be executed _after all_ test cases have
 | |
| finished.  An integer variable `num_failures` is available for diagnostics.
 | |
| The code should end with a `return` statement; the value returned will become
 | |
| the exit code of `main`.  You can normally just return `num_failures`.
 | |
| 
 | |
| Alternatively, if your C compiler supports weak symbols, you can leave this
 | |
| option unset and instead provide a `int suiteTearDown(int num_failures)`
 | |
| function in your test suite.  The linker will look for this symbol and fall
 | |
| back to a Unity-provided stub if it is not found.
 | |
| 
 | |
| 
 | |
| ##### `:enforce_strict_ordering`
 | |
| 
 | |
| This option should be defined if you have the strict order feature enabled in
 | |
| CMock (see CMock documentation). This generates extra variables required for
 | |
| everything to run smoothly. If you provide the same YAML to the generator as
 | |
| used in CMock's configuration, you've already configured the generator properly.
 | |
| 
 | |
| ##### `:mock_prefix` and `:mock_suffix`
 | |
| 
 | |
| Unity automatically generates calls to Init, Verify and Destroy for every file
 | |
| included in the main test file that starts with the given mock prefix and ends
 | |
| with the given mock suffix, file extension not included. By default, Unity
 | |
| assumes a `Mock` prefix and no suffix.
 | |
| 
 | |
| ##### `:plugins`
 | |
| 
 | |
| This option specifies an array of plugins to be used (of course, the array can
 | |
| contain only a single plugin). This is your opportunity to enable support for
 | |
| CException support, which will add a check for unhandled exceptions in each
 | |
| test, reporting a failure if one is detected. To enable this feature using Ruby:
 | |
| 
 | |
| ```Ruby
 | |
| :plugins => [ :cexception ]
 | |
| ```
 | |
| 
 | |
| Or as a yaml file:
 | |
| 
 | |
| ```YAML
 | |
| :plugins:
 | |
|   -:cexception
 | |
| ```
 | |
| 
 | |
| If you are using CMock, it is very likely that you are already passing an array
 | |
| of plugins to CMock. You can just use the same array here. This script will just
 | |
| ignore the plugins that don't require additional support.
 | |
| 
 | |
| 
 | |
| ### `unity_test_summary.rb`
 | |
| 
 | |
| A Unity test file contains one or more test case functions. Each test case can
 | |
| pass, fail, or be ignored. Each test file is run individually producing results
 | |
| for its collection of test cases. A given project will almost certainly be
 | |
| composed of multiple test files. Therefore, the suite of tests is comprised of
 | |
| one or more test cases spread across one or more test files. This script
 | |
| aggregates individual test file results to generate a summary of all executed
 | |
| test cases. The output includes how many tests were run, how many were ignored,
 | |
| and how many failed. In addition, the output includes a listing of which
 | |
| specific tests were ignored and failed. A good example of the breadth and
 | |
| details of these results can be found in the `examples` directory. Intentionally
 | |
| ignored and failing tests in this project generate corresponding entries in the
 | |
| summary report.
 | |
| 
 | |
| If you're interested in other (prettier?) output formats, check into the
 | |
| Ceedling build tool project (ceedling.sourceforge.net) that works with Unity and
 | |
| CMock and supports xunit-style xml as well as other goodies.
 | |
| 
 | |
| This script assumes the existence of files ending with the extensions
 | |
| `.testpass` and `.testfail`.The contents of these files includes the test
 | |
| results summary corresponding to each test file executed with the extension set
 | |
| according to the presence or absence of failures for that test file. The script
 | |
| searches a specified path for these files, opens each one it finds, parses the
 | |
| results, and aggregates and prints a summary. Calling it from the command line
 | |
| looks like this:
 | |
| 
 | |
| ```Shell
 | |
| ruby unity_test_summary.rb build/test/
 | |
| ```
 | |
| 
 | |
| You can optionally specify a root path as well. This is really helpful when you
 | |
| are using relative paths in your tools' setup, but you want to pull the summary
 | |
| into an IDE like Eclipse for clickable shortcuts.
 | |
| 
 | |
| ```Shell
 | |
| ruby unity_test_summary.rb build/test/ ~/projects/myproject/
 | |
| ```
 | |
| 
 | |
| Or, if you're more of a Windows sort of person:
 | |
| 
 | |
| ```Shell
 | |
| ruby unity_test_summary.rb build\teat\ C:\projects\myproject\
 | |
| ```
 | |
| 
 | |
| When configured correctly, you'll see a final summary, like so:
 | |
| 
 | |
| ```Shell
 | |
| --------------------------
 | |
| UNITY IGNORED TEST SUMMARY
 | |
| --------------------------
 | |
| blah.c:22:test_sandwiches_should_HaveBreadOnTwoSides:IGNORE
 | |
| 
 | |
| -------------------------
 | |
| UNITY FAILED TEST SUMMARY
 | |
| -------------------------
 | |
| blah.c:87:test_sandwiches_should_HaveCondiments:FAIL:Expected 1 was 0
 | |
| meh.c:38:test_soda_should_BeCalledPop:FAIL:Expected "pop" was "coke"
 | |
| 
 | |
| --------------------------
 | |
| OVERALL UNITY TEST SUMMARY
 | |
| --------------------------
 | |
| 45 TOTAL TESTS 2 TOTAL FAILURES 1 IGNORED
 | |
| ```
 | |
| 
 | |
| How convenient is that?
 | |
| 
 | |
| 
 | |
| *Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)*
 | 
