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)*
							 |