19750e409Sopenharmony_ci# Unity Helper Scripts 29750e409Sopenharmony_ci 39750e409Sopenharmony_ci## With a Little Help From Our Friends 49750e409Sopenharmony_ci 59750e409Sopenharmony_ciSometimes what it takes to be a really efficient C programmer is a little non-C. 69750e409Sopenharmony_ciThe Unity project includes a couple Ruby scripts for making your life just a tad 79750e409Sopenharmony_cieasier. They are completely optional. If you choose to use them, you'll need a 89750e409Sopenharmony_cicopy of Ruby, of course. Just install whatever the latest version is, and it is 99750e409Sopenharmony_cilikely to work. You can find Ruby at [ruby-lang.org](https://ruby-labg.org/). 109750e409Sopenharmony_ci 119750e409Sopenharmony_ci 129750e409Sopenharmony_ci### `generate_test_runner.rb` 139750e409Sopenharmony_ci 149750e409Sopenharmony_ciAre you tired of creating your own `main` function in your test file? Do you 159750e409Sopenharmony_cikeep forgetting to add a `RUN_TEST` call when you add a new test case to your 169750e409Sopenharmony_cisuite? Do you want to use CMock or other fancy add-ons but don't want to figure 179750e409Sopenharmony_ciout how to create your own `RUN_TEST` macro? 189750e409Sopenharmony_ci 199750e409Sopenharmony_ciWell then we have the perfect script for you! 209750e409Sopenharmony_ci 219750e409Sopenharmony_ciThe `generate_test_runner` script processes a given test file and automatically 229750e409Sopenharmony_cicreates a separate test runner file that includes ?main?to execute the test 239750e409Sopenharmony_cicases within the scanned test file. All you do then is add the generated runner 249750e409Sopenharmony_cito your list of files to be compiled and linked, and presto you're done! 259750e409Sopenharmony_ci 269750e409Sopenharmony_ciThis script searches your test file for void function signatures having a 279750e409Sopenharmony_cifunction name beginning with "test" or "spec". It treats each of these 289750e409Sopenharmony_cifunctions as a test case and builds up a test suite of them. For example, the 299750e409Sopenharmony_cifollowing includes three test cases: 309750e409Sopenharmony_ci 319750e409Sopenharmony_ci```C 329750e409Sopenharmony_civoid testVerifyThatUnityIsAwesomeAndWillMakeYourLifeEasier(void) 339750e409Sopenharmony_ci{ 349750e409Sopenharmony_ci ASSERT_TRUE(1); 359750e409Sopenharmony_ci} 369750e409Sopenharmony_civoid test_FunctionName_should_WorkProperlyAndReturn8(void) { 379750e409Sopenharmony_ci ASSERT_EQUAL_INT(8, FunctionName()); 389750e409Sopenharmony_ci} 399750e409Sopenharmony_civoid spec_Function_should_DoWhatItIsSupposedToDo(void) { 409750e409Sopenharmony_ci ASSERT_NOT_NULL(Function(5)); 419750e409Sopenharmony_ci} 429750e409Sopenharmony_ci``` 439750e409Sopenharmony_ci 449750e409Sopenharmony_ciYou can run this script a couple of ways. The first is from the command line: 459750e409Sopenharmony_ci 469750e409Sopenharmony_ci```Shell 479750e409Sopenharmony_ciruby generate_test_runner.rb TestFile.c NameOfRunner.c 489750e409Sopenharmony_ci``` 499750e409Sopenharmony_ci 509750e409Sopenharmony_ciAlternatively, if you include only the test file parameter, the script will copy 519750e409Sopenharmony_cithe name of the test file and automatically append "_Runner" to the name of the 529750e409Sopenharmony_cigenerated file. The example immediately below will create TestFile_Runner.c. 539750e409Sopenharmony_ci 549750e409Sopenharmony_ci```Shell 559750e409Sopenharmony_ciruby generate_test_runner.rb TestFile.c 569750e409Sopenharmony_ci``` 579750e409Sopenharmony_ci 589750e409Sopenharmony_ciYou can also add a [YAML](http://www.yaml.org/) file to configure extra options. 599750e409Sopenharmony_ciConveniently, this YAML file is of the same format as that used by Unity and 609750e409Sopenharmony_ciCMock. So if you are using YAML files already, you can simply pass the very same 619750e409Sopenharmony_cifile into the generator script. 629750e409Sopenharmony_ci 639750e409Sopenharmony_ci```Shell 649750e409Sopenharmony_ciruby generate_test_runner.rb TestFile.c my_config.yml 659750e409Sopenharmony_ci``` 669750e409Sopenharmony_ci 679750e409Sopenharmony_ciThe contents of the YAML file `my_config.yml` could look something like the 689750e409Sopenharmony_ciexample below. If you're wondering what some of these options do, you're going 699750e409Sopenharmony_cito love the next section of this document. 709750e409Sopenharmony_ci 719750e409Sopenharmony_ci```YAML 729750e409Sopenharmony_ci:unity: 739750e409Sopenharmony_ci :includes: 749750e409Sopenharmony_ci - stdio.h 759750e409Sopenharmony_ci - microdefs.h 769750e409Sopenharmony_ci :cexception: 1 779750e409Sopenharmony_ci :suit_setup: "blah = malloc(1024);" 789750e409Sopenharmony_ci :suite_teardown: "free(blah);" 799750e409Sopenharmony_ci``` 809750e409Sopenharmony_ci 819750e409Sopenharmony_ciIf you would like to force your generated test runner to include one or more 829750e409Sopenharmony_ciheader files, you can just include those at the command line too. Just make sure 839750e409Sopenharmony_cithese are _after_ the YAML file, if you are using one: 849750e409Sopenharmony_ci 859750e409Sopenharmony_ci```Shell 869750e409Sopenharmony_ciruby generate_test_runner.rb TestFile.c my_config.yml extras.h 879750e409Sopenharmony_ci``` 889750e409Sopenharmony_ci 899750e409Sopenharmony_ciAnother option, particularly if you are already using Ruby to orchestrate your 909750e409Sopenharmony_cibuilds - or more likely the Ruby-based build tool Rake - is requiring this 919750e409Sopenharmony_ciscript directly. Anything that you would have specified in a YAML file can be 929750e409Sopenharmony_cipassed to the script as part of a hash. Let's push the exact same requirement 939750e409Sopenharmony_ciset as we did above but this time through Ruby code directly: 949750e409Sopenharmony_ci 959750e409Sopenharmony_ci```Ruby 969750e409Sopenharmony_cirequire "generate_test_runner.rb" 979750e409Sopenharmony_cioptions = { 989750e409Sopenharmony_ci :includes => ["stdio.h", "microdefs.h"], 999750e409Sopenharmony_ci :cexception => 1, 1009750e409Sopenharmony_ci :suite_setup => "blah = malloc(1024);", 1019750e409Sopenharmony_ci :suite_teardown => "free(blah);" 1029750e409Sopenharmony_ci} 1039750e409Sopenharmony_ciUnityTestRunnerGenerator.new.run(testfile, runner_name, options) 1049750e409Sopenharmony_ci``` 1059750e409Sopenharmony_ci 1069750e409Sopenharmony_ciIf you have multiple files to generate in a build script (such as a Rakefile), 1079750e409Sopenharmony_ciyou might want to instantiate a generator object with your options and call it 1089750e409Sopenharmony_cito generate each runner thereafter. Like thus: 1099750e409Sopenharmony_ci 1109750e409Sopenharmony_ci```Ruby 1119750e409Sopenharmony_cigen = UnityTestRunnerGenerator.new(options) 1129750e409Sopenharmony_citest_files.each do |f| 1139750e409Sopenharmony_ci gen.run(f, File.basename(f,'.c')+"Runner.c" 1149750e409Sopenharmony_ciend 1159750e409Sopenharmony_ci``` 1169750e409Sopenharmony_ci 1179750e409Sopenharmony_ci#### Options accepted by generate_test_runner.rb: 1189750e409Sopenharmony_ci 1199750e409Sopenharmony_ciThe following options are available when executing `generate_test_runner`. You 1209750e409Sopenharmony_cimay pass these as a Ruby hash directly or specify them in a YAML file, both of 1219750e409Sopenharmony_ciwhich are described above. In the `examples` directory, Example 3's Rakefile 1229750e409Sopenharmony_cidemonstrates using a Ruby hash. 1239750e409Sopenharmony_ci 1249750e409Sopenharmony_ci 1259750e409Sopenharmony_ci##### `:includes` 1269750e409Sopenharmony_ci 1279750e409Sopenharmony_ciThis option specifies an array of file names to be `#include`'d at the top of 1289750e409Sopenharmony_ciyour runner C file. You might use it to reference custom types or anything else 1299750e409Sopenharmony_ciuniversally needed in your generated runners. 1309750e409Sopenharmony_ci 1319750e409Sopenharmony_ci 1329750e409Sopenharmony_ci##### `:suite_setup` 1339750e409Sopenharmony_ci 1349750e409Sopenharmony_ciDefine this option with C code to be executed _before any_ test cases are run. 1359750e409Sopenharmony_ci 1369750e409Sopenharmony_ciAlternatively, if your C compiler supports weak symbols, you can leave this 1379750e409Sopenharmony_cioption unset and instead provide a `void suiteSetUp(void)` function in your test 1389750e409Sopenharmony_cisuite. The linker will look for this symbol and fall back to a Unity-provided 1399750e409Sopenharmony_cistub if it is not found. 1409750e409Sopenharmony_ci 1419750e409Sopenharmony_ci 1429750e409Sopenharmony_ci##### `:suite_teardown` 1439750e409Sopenharmony_ci 1449750e409Sopenharmony_ciDefine this option with C code to be executed _after all_ test cases have 1459750e409Sopenharmony_cifinished. An integer variable `num_failures` is available for diagnostics. 1469750e409Sopenharmony_ciThe code should end with a `return` statement; the value returned will become 1479750e409Sopenharmony_cithe exit code of `main`. You can normally just return `num_failures`. 1489750e409Sopenharmony_ci 1499750e409Sopenharmony_ciAlternatively, if your C compiler supports weak symbols, you can leave this 1509750e409Sopenharmony_cioption unset and instead provide a `int suiteTearDown(int num_failures)` 1519750e409Sopenharmony_cifunction in your test suite. The linker will look for this symbol and fall 1529750e409Sopenharmony_ciback to a Unity-provided stub if it is not found. 1539750e409Sopenharmony_ci 1549750e409Sopenharmony_ci 1559750e409Sopenharmony_ci##### `:enforce_strict_ordering` 1569750e409Sopenharmony_ci 1579750e409Sopenharmony_ciThis option should be defined if you have the strict order feature enabled in 1589750e409Sopenharmony_ciCMock (see CMock documentation). This generates extra variables required for 1599750e409Sopenharmony_cieverything to run smoothly. If you provide the same YAML to the generator as 1609750e409Sopenharmony_ciused in CMock's configuration, you've already configured the generator properly. 1619750e409Sopenharmony_ci 1629750e409Sopenharmony_ci 1639750e409Sopenharmony_ci##### `:plugins` 1649750e409Sopenharmony_ci 1659750e409Sopenharmony_ciThis option specifies an array of plugins to be used (of course, the array can 1669750e409Sopenharmony_cicontain only a single plugin). This is your opportunity to enable support for 1679750e409Sopenharmony_ciCException support, which will add a check for unhandled exceptions in each 1689750e409Sopenharmony_citest, reporting a failure if one is detected. To enable this feature using Ruby: 1699750e409Sopenharmony_ci 1709750e409Sopenharmony_ci```Ruby 1719750e409Sopenharmony_ci:plugins => [ :cexception ] 1729750e409Sopenharmony_ci``` 1739750e409Sopenharmony_ci 1749750e409Sopenharmony_ciOr as a yaml file: 1759750e409Sopenharmony_ci 1769750e409Sopenharmony_ci```YAML 1779750e409Sopenharmony_ci:plugins: 1789750e409Sopenharmony_ci -:cexception 1799750e409Sopenharmony_ci``` 1809750e409Sopenharmony_ci 1819750e409Sopenharmony_ciIf you are using CMock, it is very likely that you are already passing an array 1829750e409Sopenharmony_ciof plugins to CMock. You can just use the same array here. This script will just 1839750e409Sopenharmony_ciignore the plugins that don't require additional support. 1849750e409Sopenharmony_ci 1859750e409Sopenharmony_ci 1869750e409Sopenharmony_ci### `unity_test_summary.rb` 1879750e409Sopenharmony_ci 1889750e409Sopenharmony_ciA Unity test file contains one or more test case functions. Each test case can 1899750e409Sopenharmony_cipass, fail, or be ignored. Each test file is run individually producing results 1909750e409Sopenharmony_cifor its collection of test cases. A given project will almost certainly be 1919750e409Sopenharmony_cicomposed of multiple test files. Therefore, the suite of tests is comprised of 1929750e409Sopenharmony_cione or more test cases spread across one or more test files. This script 1939750e409Sopenharmony_ciaggregates individual test file results to generate a summary of all executed 1949750e409Sopenharmony_citest cases. The output includes how many tests were run, how many were ignored, 1959750e409Sopenharmony_ciand how many failed. In addition, the output includes a listing of which 1969750e409Sopenharmony_cispecific tests were ignored and failed. A good example of the breadth and 1979750e409Sopenharmony_cidetails of these results can be found in the `examples` directory. Intentionally 1989750e409Sopenharmony_ciignored and failing tests in this project generate corresponding entries in the 1999750e409Sopenharmony_cisummary report. 2009750e409Sopenharmony_ci 2019750e409Sopenharmony_ciIf you're interested in other (prettier?) output formats, check into the 2029750e409Sopenharmony_ciCeedling build tool project (ceedling.sourceforge.net) that works with Unity and 2039750e409Sopenharmony_ciCMock and supports xunit-style xml as well as other goodies. 2049750e409Sopenharmony_ci 2059750e409Sopenharmony_ciThis script assumes the existence of files ending with the extensions 2069750e409Sopenharmony_ci`.testpass` and `.testfail`.The contents of these files includes the test 2079750e409Sopenharmony_ciresults summary corresponding to each test file executed with the extension set 2089750e409Sopenharmony_ciaccording to the presence or absence of failures for that test file. The script 2099750e409Sopenharmony_cisearches a specified path for these files, opens each one it finds, parses the 2109750e409Sopenharmony_ciresults, and aggregates and prints a summary. Calling it from the command line 2119750e409Sopenharmony_cilooks like this: 2129750e409Sopenharmony_ci 2139750e409Sopenharmony_ci```Shell 2149750e409Sopenharmony_ciruby unity_test_summary.rb build/test/ 2159750e409Sopenharmony_ci``` 2169750e409Sopenharmony_ci 2179750e409Sopenharmony_ciYou can optionally specify a root path as well. This is really helpful when you 2189750e409Sopenharmony_ciare using relative paths in your tools' setup, but you want to pull the summary 2199750e409Sopenharmony_ciinto an IDE like Eclipse for clickable shortcuts. 2209750e409Sopenharmony_ci 2219750e409Sopenharmony_ci```Shell 2229750e409Sopenharmony_ciruby unity_test_summary.rb build/test/ ~/projects/myproject/ 2239750e409Sopenharmony_ci``` 2249750e409Sopenharmony_ci 2259750e409Sopenharmony_ciOr, if you're more of a Windows sort of person: 2269750e409Sopenharmony_ci 2279750e409Sopenharmony_ci```Shell 2289750e409Sopenharmony_ciruby unity_test_summary.rb build\teat\ C:\projects\myproject\ 2299750e409Sopenharmony_ci``` 2309750e409Sopenharmony_ci 2319750e409Sopenharmony_ciWhen configured correctly, you'll see a final summary, like so: 2329750e409Sopenharmony_ci 2339750e409Sopenharmony_ci```Shell 2349750e409Sopenharmony_ci-------------------------- 2359750e409Sopenharmony_ciUNITY IGNORED TEST SUMMARY 2369750e409Sopenharmony_ci-------------------------- 2379750e409Sopenharmony_ciblah.c:22:test_sandwiches_should_HaveBreadOnTwoSides:IGNORE 2389750e409Sopenharmony_ci 2399750e409Sopenharmony_ci------------------------- 2409750e409Sopenharmony_ciUNITY FAILED TEST SUMMARY 2419750e409Sopenharmony_ci------------------------- 2429750e409Sopenharmony_ciblah.c:87:test_sandwiches_should_HaveCondiments:FAIL:Expected 1 was 0 2439750e409Sopenharmony_cimeh.c:38:test_soda_should_BeCalledPop:FAIL:Expected "pop" was "coke" 2449750e409Sopenharmony_ci 2459750e409Sopenharmony_ci-------------------------- 2469750e409Sopenharmony_ciOVERALL UNITY TEST SUMMARY 2479750e409Sopenharmony_ci-------------------------- 2489750e409Sopenharmony_ci45 TOTAL TESTS 2 TOTAL FAILURES 1 IGNORED 2499750e409Sopenharmony_ci``` 2509750e409Sopenharmony_ci 2519750e409Sopenharmony_ciHow convenient is that? 2529750e409Sopenharmony_ci 2539750e409Sopenharmony_ci 2549750e409Sopenharmony_ci*Find The Latest of This And More at [ThrowTheSwitch.org](https://throwtheswitch.org)* 255