提交 e2cc6791 编写于 作者: T toby

Add newlines after headings for best practice, trim trailing spaces & convert...

Add newlines after headings for best practice, trim trailing spaces & convert sneaky incorrectly coded chars

blank newline after headins is apparently best practice according to http://stackoverflow.com/q/42953462/1292918
上级 192d5176
# ThrowTheSwitch.org Coding Standard # ThrowTheSwitch.org Coding Standard
Hi. Welcome to the coding standard for ThrowTheSwitch.org. For the most part,
we try to follow these standards to unify our contributors' code into a cohesive Hi. Welcome to the coding standard for ThrowTheSwitch.org. For the most part,
unit (puns intended). You might find places where these standards aren't we try to follow these standards to unify our contributors' code into a cohesive
unit (puns intended). You might find places where these standards aren't
followed. We're not perfect. Please be polite where followed. We're not perfect. Please be polite where
you notice these discrepancies and we'll try to be polite when we notice yours. you notice these discrepancies and we'll try to be polite when we notice yours.
;) ;)
## Why Have A Coding Standard? ## Why Have A Coding Standard?
Being consistent makes code easier to understand. We've made an attempt to keep
our standard simple because we also believe that we can only expect someone to Being consistent makes code easier to understand. We've made an attempt to keep
our standard simple because we also believe that we can only expect someone to
follow something that is understandable. Please do your best. follow something that is understandable. Please do your best.
## Our Philosophy ## Our Philosophy
Before we get into details on syntax, let's take a moment to talk about our
vision for these tools. We're C developers and embedded software developers. Before we get into details on syntax, let's take a moment to talk about our
These tools are great to test any C code, but catering to embedded software has vision for these tools. We're C developers and embedded software developers.
made us more tolerant of compiler quirks. There are a LOT of quirky compilers These tools are great to test any C code, but catering to embedded software has
out there. By quirky I mean "doesn't follow standards because they feel like made us more tolerant of compiler quirks. There are a LOT of quirky compilers
out there. By quirky I mean "doesn't follow standards because they feel like
they have a license to do as they wish." they have a license to do as they wish."
Our philosophy is "support every compiler we can". Most often, this means that Our philosophy is "support every compiler we can". Most often, this means that
we aim for writing C code that is standards compliant (often C89... that seems we aim for writing C code that is standards compliant (often C89... that seems
to be a sweet spot that is almost always compatible). But it also means these to be a sweet spot that is almost always compatible). But it also means these
tools are tolerant of things that aren't common. Some that aren't even tools are tolerant of things that aren't common. Some that aren't even
compliant. There are configuration options to override the size of standard compliant. There are configuration options to override the size of standard
types. There are configuration options to force Unity to not use certain types. There are configuration options to force Unity to not use certain
standard library functions. A lot of Unity is configurable and we have worked standard library functions. A lot of Unity is configurable and we have worked
hard to make it not TOO ugly in the process. hard to make it not TOO ugly in the process.
Similarly, our tools that parse C do their best. They aren't full C parsers Similarly, our tools that parse C do their best. They aren't full C parsers
(yet) and, even if they were, they would still have to accept non-standard (yet) and, even if they were, they would still have to accept non-standard
additions like gcc extensions or specifying `@0x1000` to force a variable to additions like gcc extensions or specifying `@0x1000` to force a variable to
compile to a particular location. It's just what we do, because we like compile to a particular location. It's just what we do, because we like
everything to Just Work™. everything to Just Work™.
Speaking of having things Just Work™, that's our second philosophy. By that, we Speaking of having things Just Work™, that's our second philosophy. By that, we
mean that we do our best to have EVERY configuration option have a logical mean that we do our best to have EVERY configuration option have a logical
default. We believe that if you're working with a simple compiler and target, default. We believe that if you're working with a simple compiler and target,
you shouldn't need to configure very much... we try to make the tools guess as you shouldn't need to configure very much... we try to make the tools guess as
much as they can, but give the user the power to override it when it's wrong. much as they can, but give the user the power to override it when it's wrong.
## Naming Things ## Naming Things
Let's talk about naming things. Programming is all about naming things. We name
files, functions, variables, and so much more. While we're not always going to Let's talk about naming things. Programming is all about naming things. We name
find the best name for something, we actually put quite a bit of effort into files, functions, variables, and so much more. While we're not always going to
find the best name for something, we actually put quite a bit of effort into
finding *What Something WANTS to be Called*™. finding *What Something WANTS to be Called*™.
When naming things, we more or less follow this hierarchy, the first being the When naming things, we more or less follow this hierarchy, the first being the
most important to us (but we do all four whenever possible): most important to us (but we do all four whenever possible):
1. Readable 1. Readable
2. Descriptive 2. Descriptive
3. Consistent 3. Consistent
4. Memorable 4. Memorable
#### Readable #### Readable
We want to read our code. This means we like names and flow that are more
naturally read. We try to avoid double negatives. We try to avoid cryptic We want to read our code. This means we like names and flow that are more
naturally read. We try to avoid double negatives. We try to avoid cryptic
abbreviations (sticking to ones we feel are common). abbreviations (sticking to ones we feel are common).
#### Descriptive #### Descriptive
We like descriptive names for things, especially functions and variables.
Finding the right name for something is an important endeavor. You might notice We like descriptive names for things, especially functions and variables.
from poking around our code that this often results in names that are a little Finding the right name for something is an important endeavor. You might notice
longer than the average. Guilty. We're okay with a tiny bit more typing if it from poking around our code that this often results in names that are a little
longer than the average. Guilty. We're okay with a tiny bit more typing if it
means our code is easier to understand. means our code is easier to understand.
There are two exceptions to this rule that we also stick to as religiously as There are two exceptions to this rule that we also stick to as religiously as
possible: possible:
First, while we realize hungarian notation (and similar systems for encoding First, while we realize hungarian notation (and similar systems for encoding
type information into variable names) is providing a more descriptive name, we type information into variable names) is providing a more descriptive name, we
feel that (for the average developer) it takes away from readability and feel that (for the average developer) it takes away from readability and
therefore is to be avoided. therefore is to be avoided.
Second, loop counters and other local throw-away variables often have a purpose Second, loop counters and other local throw-away variables often have a purpose
which is obvious. There's no need, therefore, to get carried away with complex which is obvious. There's no need, therefore, to get carried away with complex
naming. We find i, j, and k are better loop counters than loopCounterVar or naming. We find i, j, and k are better loop counters than loopCounterVar or
whatnot. We only break this rule when we see that more description could improve whatnot. We only break this rule when we see that more description could improve
understanding of an algorithm. understanding of an algorithm.
#### Consistent #### Consistent
We like consistency, but we're not really obsessed with it. We try to name our
configuration macros in a consistent fashion... you'll notice a repeated use of We like consistency, but we're not really obsessed with it. We try to name our
UNITY_EXCLUDE_BLAH or UNITY_USES_BLAH macros. This helps users avoid having to configuration macros in a consistent fashion... you'll notice a repeated use of
remember each macro's details. UNITY_EXCLUDE_BLAH or UNITY_USES_BLAH macros. This helps users avoid having to
remember each macro's details.
#### Memorable #### Memorable
Where ever it doesn't violate the above principles, we try to apply memorable
names. Sometimes this means using something that is simply descriptive, but Where ever it doesn't violate the above principles, we try to apply memorable
often we strive for descriptive AND unique... we like quirky names that stand names. Sometimes this means using something that is simply descriptive, but
out in our memory and are easier to search for. Take a look through the file often we strive for descriptive AND unique... we like quirky names that stand
names in Ceedling and you'll get a good idea of what we are talking about here. out in our memory and are easier to search for. Take a look through the file
Why use preprocess when you can use preprocessinator? Or what better describes a names in Ceedling and you'll get a good idea of what we are talking about here.
module in charge of invoking tasks during releases than release_invoker? Don't Why use preprocess when you can use preprocessinator? Or what better describes a
get carried away. The names are still descriptive and fulfill the above module in charge of invoking tasks during releases than release_invoker? Don't
get carried away. The names are still descriptive and fulfill the above
requirements, but they don't feel stale. requirements, but they don't feel stale.
## C and C++ Details ## C and C++ Details
We don't really want to add to the style battles out there. Tabs or spaces?
How many spaces? Where do the braces go? These are age-old questions that will We don't really want to add to the style battles out there. Tabs or spaces?
never be answered... or at least not answered in a way that will make everyone How many spaces? Where do the braces go? These are age-old questions that will
never be answered... or at least not answered in a way that will make everyone
happy. happy.
We've decided on our own style preferences. If you'd like to contribute to these We've decided on our own style preferences. If you'd like to contribute to these
projects (and we hope that you do), then we ask if you do your best to follow projects (and we hope that you do), then we ask if you do your best to follow
the same. It will only hurt a little. We promise. the same. It will only hurt a little. We promise.
#### Whitespace #### Whitespace
Our C-style is to use spaces and to use 4 of them per indent level. It's a nice
power-of-2 number that looks decent on a wide screen. We have no more reason Our C-style is to use spaces and to use 4 of them per indent level. It's a nice
than that. We break that rule when we have lines that wrap (macros or function power-of-2 number that looks decent on a wide screen. We have no more reason
arguments or whatnot). When that happens, we like to indent further to line than that. We break that rule when we have lines that wrap (macros or function
arguments or whatnot). When that happens, we like to indent further to line
things up in nice tidy columns. things up in nice tidy columns.
```C ```C
...@@ -120,7 +139,9 @@ things up in nice tidy columns. ...@@ -120,7 +139,9 @@ things up in nice tidy columns.
} }
``` ```
#### Case #### Case
- Files - all lower case with underscores. - Files - all lower case with underscores.
- Variables - all lower case with underscores - Variables - all lower case with underscores
- Macros - all caps with underscores. - Macros - all caps with underscores.
...@@ -128,9 +149,11 @@ things up in nice tidy columns. ...@@ -128,9 +149,11 @@ things up in nice tidy columns.
- Functions - camel cased. Usually named ModuleName_FuncName - Functions - camel cased. Usually named ModuleName_FuncName
- Constants and Globals - camel cased. - Constants and Globals - camel cased.
#### Braces #### Braces
The left brace is on the next line after the declaration. The right brace is
directly below that. Everything in between in indented one level. If you're The left brace is on the next line after the declaration. The right brace is
directly below that. Everything in between in indented one level. If you're
catching an error and you have a one-line, go ahead and to it on the same line. catching an error and you have a one-line, go ahead and to it on the same line.
```C ```C
...@@ -139,32 +162,42 @@ catching an error and you have a one-line, go ahead and to it on the same line. ...@@ -139,32 +162,42 @@ catching an error and you have a one-line, go ahead and to it on the same line.
//Like so. Even if only one line, we use braces. //Like so. Even if only one line, we use braces.
} }
``` ```
#### Comments #### Comments
Do you know what we hate? Old-school C block comments. BUT, we're using them
anyway. As we mentioned, our goal is to support every compiler we can, Do you know what we hate? Old-school C block comments. BUT, we're using them
especially embedded compilers. There are STILL C compilers out there that only anyway. As we mentioned, our goal is to support every compiler we can,
support old-school block comments. So that is what we're using. We apologize. We especially embedded compilers. There are STILL C compilers out there that only
support old-school block comments. So that is what we're using. We apologize. We
think they are ugly too. think they are ugly too.
## Ruby Details ## Ruby Details
Is there really such thing as a Ruby coding standard? Ruby is such a free form
language, it seems almost sacrilegious to suggest that people should comply to Is there really such thing as a Ruby coding standard? Ruby is such a free form
language, it seems almost sacrilegious to suggest that people should comply to
one method! We'll keep it really brief! one method! We'll keep it really brief!
#### Whitespace #### Whitespace
Our Ruby style is to use spaces and to use 2 of them per indent level. It's a
nice power-of-2 number that really grooves with Ruby's compact style. We have no Our Ruby style is to use spaces and to use 2 of them per indent level. It's a
more reason than that. We break that rule when we have lines that wrap. When nice power-of-2 number that really grooves with Ruby's compact style. We have no
more reason than that. We break that rule when we have lines that wrap. When
that happens, we like to indent further to line things up in nice tidy columns. that happens, we like to indent further to line things up in nice tidy columns.
#### Case #### Case
- Files - all lower case with underscores. - Files - all lower case with underscores.
- Variables - all lower case with underscores - Variables - all lower case with underscores
- Classes, Modules, etc - Camel cased. - Classes, Modules, etc - Camel cased.
- Functions - all lower case with underscores - Functions - all lower case with underscores
- Constants - all upper case with underscores - Constants - all upper case with underscores
## Documentation ## Documentation
Egad. Really? We use markdown and we like pdf files because they can be made to
Egad. Really? We use markdown and we like pdf files because they can be made to
look nice while still being portable. Good enough? look nice while still being portable. Good enough?
此差异已折叠。
此差异已折叠。
# Unity - Getting Started # Unity - Getting Started
## Welcome ## Welcome
Congratulations. You're now the proud owner of your very own pile of bits! What
are you going to do with all these ones and zeros? This document should be able Congratulations. You're now the proud owner of your very own pile of bits! What
are you going to do with all these ones and zeros? This document should be able
to help you decide just that. to help you decide just that.
Unity is a unit test framework. The goal has been to keep it small and Unity is a unit test framework. The goal has been to keep it small and
functional. The core Unity test framework is three files: a single C file and a functional. The core Unity test framework is three files: a single C file and a
couple header files. These team up to provide functions and macros to make couple header files. These team up to provide functions and macros to make
testing easier. testing easier.
Unity was designed to be cross platform. It works hard to stick with C standards Unity was designed to be cross platform. It works hard to stick with C standards
while still providing support for the many embedded C compilers that bend the while still providing support for the many embedded C compilers that bend the
rules. Unity has been used with many compilers, including GCC, IAR, Clang, rules. Unity has been used with many compilers, including GCC, IAR, Clang,
Green Hills, Microchip, and MS Visual Studio. It's not much work to get it to Green Hills, Microchip, and MS Visual Studio. It's not much work to get it to
work with a new target. work with a new target.
### Overview of the Documents ### Overview of the Documents
#### Unity Assertions reference #### Unity Assertions reference
This document will guide you through all the assertion options provided by
Unity. This is going to be your unit testing bread and butter. You'll spend more This document will guide you through all the assertion options provided by
Unity. This is going to be your unit testing bread and butter. You'll spend more
time with assertions than any other part of Unity. time with assertions than any other part of Unity.
#### Unity Assertions Cheat Sheet #### Unity Assertions Cheat Sheet
This document contains an abridged summary of the assertions described in the
previous document. It's perfect for printing and referencing while you This document contains an abridged summary of the assertions described in the
previous document. It's perfect for printing and referencing while you
familiarize yourself with Unity's options. familiarize yourself with Unity's options.
#### Unity Configuration Guide #### Unity Configuration Guide
This document is the one to reference when you are going to use Unity with a new
target or compiler. It'll guide you through the configuration options and will This document is the one to reference when you are going to use Unity with a new
target or compiler. It'll guide you through the configuration options and will
help you customize your testing experience to meet your needs. help you customize your testing experience to meet your needs.
#### Unity Helper Scripts #### Unity Helper Scripts
This document describes the helper scripts that are available for simplifying
your testing workflow. It describes the collection of optional Ruby scripts This document describes the helper scripts that are available for simplifying
included in the auto directory of your Unity installation. Neither Ruby nor your testing workflow. It describes the collection of optional Ruby scripts
these scripts are necessary for using Unity. They are provided as a convenience included in the auto directory of your Unity installation. Neither Ruby nor
these scripts are necessary for using Unity. They are provided as a convenience
for those who wish to use them. for those who wish to use them.
#### Unity License #### Unity License
What's an open source project without a license file? This brief document
describes the terms you're agreeing to when you use this software. Basically, we What's an open source project without a license file? This brief document
want it to be useful to you in whatever context you want to use it, but please describes the terms you're agreeing to when you use this software. Basically, we
want it to be useful to you in whatever context you want to use it, but please
don't blame us if you run into problems. don't blame us if you run into problems.
### Overview of the Folders ### Overview of the Folders
If you have obtained Unity through Github or something similar, you might be
If you have obtained Unity through Github or something similar, you might be
surprised by just how much stuff you suddenly have staring you in the face. surprised by just how much stuff you suddenly have staring you in the face.
Don't worry, Unity itself is very small. The rest of it is just there to make Don't worry, Unity itself is very small. The rest of it is just there to make
your life easier. You can ignore it or use it at your convenience. Here's an your life easier. You can ignore it or use it at your convenience. Here's an
overview of everything in the project. overview of everything in the project.
- `src` — This is the code you care about! This folder contains a C file and two - `src` - This is the code you care about! This folder contains a C file and two
header files. These three files _are_ Unity. header files. These three files _are_ Unity.
- `docs` — You're reading this document, so it's possible you have found your way - `docs` - You're reading this document, so it's possible you have found your way
into this folder already. This is where all the handy documentation can be into this folder already. This is where all the handy documentation can be
found. found.
- `examples` This contains a few examples of using Unity. - `examples` - This contains a few examples of using Unity.
- `extras` — These are optional add ons to Unity that are not part of the core - `extras` - These are optional add ons to Unity that are not part of the core
project. If you've reached us through James Grenning's book, you're going to project. If you've reached us through James Grenning's book, you're going to
want to look here. want to look here.
- `test` — This is how Unity and its scripts are all tested. If you're just using - `test` - This is how Unity and its scripts are all tested. If you're just using
Unity, you'll likely never need to go in here. If you are the lucky team member Unity, you'll likely never need to go in here. If you are the lucky team member
who gets to port Unity to a new toolchain, this is a good place to verify who gets to port Unity to a new toolchain, this is a good place to verify
everything is configured properly. everything is configured properly.
- `auto` — Here you will find helpful Ruby scripts for simplifying your test - `auto` - Here you will find helpful Ruby scripts for simplifying your test
workflow. They are purely optional and are not required to make use of Unity. workflow. They are purely optional and are not required to make use of Unity.
## How to Create A Test File
Test files are C files. Most often you will create a single test file for each C ## How to Create A Test File
module that you want to test. The test file should include unity.h and the
Test files are C files. Most often you will create a single test file for each C
module that you want to test. The test file should include unity.h and the
header for your C module to be tested. header for your C module to be tested.
Next, a test file will include a `setUp()` and `tearDown()` function. The setUp Next, a test file will include a `setUp()` and `tearDown()` function. The setUp
function can contain anything you would like to run before each test. The function can contain anything you would like to run before each test. The
tearDown function can contain anything you would like to run after each test. tearDown function can contain anything you would like to run after each test.
Both functions accept no arguments and return nothing. You may leave either or Both functions accept no arguments and return nothing. You may leave either or
both of these blank if you have no need for them. If you're using a compiler both of these blank if you have no need for them. If you're using a compiler
that is configured to make these functions optional, you may leave them off that is configured to make these functions optional, you may leave them off
completely. Not sure? Give it a try. If you compiler complains that it can't completely. Not sure? Give it a try. If you compiler complains that it can't
find setUp or tearDown when it links, you'll know you need to at least include find setUp or tearDown when it links, you'll know you need to at least include
an empty function for these. an empty function for these.
The majority of the file will be a series of test functions. Test functions The majority of the file will be a series of test functions. Test functions
follow the convention of starting with the word "test" or "spec". You don't HAVE follow the convention of starting with the word "test" or "spec". You don't HAVE
to name them this way, but it makes it clear what functions are tests for other to name them this way, but it makes it clear what functions are tests for other
developers. Test functions take no arguments and return nothing. All test developers. Test functions take no arguments and return nothing. All test
accounting is handled internally in Unity. accounting is handled internally in Unity.
Finally, at the bottom of your test file, you will write a `main()` function. Finally, at the bottom of your test file, you will write a `main()` function.
This function will call `UNITY_BEGIN()`, then `RUN_TEST` for each test, and This function will call `UNITY_BEGIN()`, then `RUN_TEST` for each test, and
finally `UNITY_END()`.This is what will actually trigger each of those test finally `UNITY_END()`.This is what will actually trigger each of those test
functions to run, so it is important that each function gets its own `RUN_TEST` functions to run, so it is important that each function gets its own `RUN_TEST`
call. call.
Remembering to add each test to the main function can get to be tedious. If you Remembering to add each test to the main function can get to be tedious. If you
enjoy using helper scripts in your build process, you might consider making use enjoy using helper scripts in your build process, you might consider making use
of our handy generate_test_runner.rb script. This will create the main function of our handy generate_test_runner.rb script. This will create the main function
and all the calls for you, assuming that you have followed the suggested naming and all the calls for you, assuming that you have followed the suggested naming
conventions. In this case, there is no need for you to include the main function conventions. In this case, there is no need for you to include the main function
in your test file at all. in your test file at all.
When you're done, your test file will look something like this: When you're done, your test file will look something like this:
```C ```C
#include "unity.h" #include "unity.h"
#include "file_to_test.h" #include "file_to_test.h"
void setUp(void) { void setUp(void) {
// set stuff up here // set stuff up here
} }
void tearDown(void) { void tearDown(void) {
// clean stuff up here // clean stuff up here
} }
void test_function_should_doBlahAndBlah(void) { void test_function_should_doBlahAndBlah(void) {
//test stuff //test stuff
} }
void test_function_should_doAlsoDoBlah(void) { void test_function_should_doAlsoDoBlah(void) {
//more test stuff //more test stuff
} }
int main(void) { int main(void) {
UNITY_BEGIN(); UNITY_BEGIN();
RUN_TEST(test_function_should_doBlahAndBlah); RUN_TEST(test_function_should_doBlahAndBlah);
RUN_TEST(test_function_should_doAlsoDoBlah); RUN_TEST(test_function_should_doAlsoDoBlah);
return UNITY_END(); return UNITY_END();
} }
``` ```
It's possible that you will require more customization than this, eventually. It's possible that you will require more customization than this, eventually.
For that sort of thing, you're going to want to look at the configuration guide. For that sort of thing, you're going to want to look at the configuration guide.
This should be enough to get you going, though. This should be enough to get you going, though.
## How to Build and Run A Test File ## How to Build and Run A Test File
This is the single biggest challenge to picking up a new unit testing framework,
at least in a language like C or C++. These languages are REALLY good at getting This is the single biggest challenge to picking up a new unit testing framework,
you "close to the metal" (why is the phrase metal? Wouldn't it be more accurate at least in a language like C or C++. These languages are REALLY good at getting
to say "close to the silicon"?). While this feature is usually a good thing, it you "close to the metal" (why is the phrase metal? Wouldn't it be more accurate
to say "close to the silicon"?). While this feature is usually a good thing, it
can make testing more challenging. can make testing more challenging.
You have two really good options for toolchains. Depending on where you're You have two really good options for toolchains. Depending on where you're
coming from, it might surprise you that neither of these options is running the coming from, it might surprise you that neither of these options is running the
unit tests on your hardware. unit tests on your hardware.
There are many reasons for this, but here's a short version: There are many reasons for this, but here's a short version:
- On hardware, you have too many constraints (processing power, memory, etc), - On hardware, you have too many constraints (processing power, memory, etc),
...@@ -153,19 +170,19 @@ There are many reasons for this, but here's a short version: ...@@ -153,19 +170,19 @@ There are many reasons for this, but here's a short version:
- On hardware, unit testing is more challenging, - On hardware, unit testing is more challenging,
- Unit testing isn't System testing. Keep them separate. - Unit testing isn't System testing. Keep them separate.
Instead of running your tests on your actual hardware, most developers choose to Instead of running your tests on your actual hardware, most developers choose to
develop them as native applications (using gcc or MSVC for example) or as develop them as native applications (using gcc or MSVC for example) or as
applications running on a simulator. Either is a good option. Native apps have applications running on a simulator. Either is a good option. Native apps have
the advantages of being faster and easier to set up. Simulator apps have the the advantages of being faster and easier to set up. Simulator apps have the
advantage of working with the same compiler as your target application. The advantage of working with the same compiler as your target application. The
options for configuring these are discussed in the configuration guide. options for configuring these are discussed in the configuration guide.
To get either to work, you might need to make a few changes to the file To get either to work, you might need to make a few changes to the file
containing your register set (discussed later). containing your register set (discussed later).
In either case, a test is built by linking unity, the test file, and the C In either case, a test is built by linking unity, the test file, and the C
file(s) being tested. These files create an executable which can be run as the file(s) being tested. These files create an executable which can be run as the
test set for that module. Then, this process is repeated for the next test file. test set for that module. Then, this process is repeated for the next test file.
This flexibility of separating tests into individual executables allows us to This flexibility of separating tests into individual executables allows us to
much more thoroughly unit test our system and it keeps all the test code out of much more thoroughly unit test our system and it keeps all the test code out of
our final release! our final release!
# Unity Helper Scripts # Unity Helper Scripts
## With a Little Help From Our Friends ## 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 Ruby scripts for making your life just a tad Sometimes what it takes to be a really efficient C programmer is a little non-C.
easier. They are completely optional. If you choose to use them, you'll need a The Unity project includes a couple Ruby scripts for making your life just a tad
copy of Ruby, of course. Just install whatever the latest version is, and it is 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/). likely to work. You can find Ruby at [ruby-lang.org](https://ruby-labg.org/).
### `generate_test_runner.rb` ### `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 Are you tired of creating your own `main` function in your test file? Do you
suite? Do you want to use CMock or other fancy add-ons but don't want to figure 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? out how to create your own `RUN_TEST` macro?
Well then we have the perfect script for you! Well then we have the perfect script for you!
The `generate_test_runner` script processes a given test file and automatically 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 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 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! 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 This script searches your test file for void function signatures having a
function name beginning with "test" or "spec". It treats each of these 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 functions as a test case and builds up a test suite of them. For example, the
following includes three test cases: following includes three test cases:
```C ```C
...@@ -43,25 +47,25 @@ You can run this script a couple of ways. The first is from the command line: ...@@ -43,25 +47,25 @@ You can run this script a couple of ways. The first is from the command line:
ruby generate_test_runner.rb TestFile.c NameOfRunner.c ruby generate_test_runner.rb TestFile.c NameOfRunner.c
``` ```
Alternatively, if you include only the test file parameter, the script will copy 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 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. generated file. The example immediately below will create TestFile_Runner.c.
```Shell ```Shell
ruby generate_test_runner.rb TestFile.c ruby generate_test_runner.rb TestFile.c
``` ```
You can also add a [YAML](http://www.yaml.org/) file to configure extra options. 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 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 CMock. So if you are using YAML files already, you can simply pass the very same
file into the generator script. file into the generator script.
```Shell ```Shell
ruby generate_test_runner.rb TestFile.c my_config.yml ruby generate_test_runner.rb TestFile.c my_config.yml
``` ```
The contents of the YAML file `my_config.yml` could look something like the 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 example below. If you're wondering what some of these options do, you're going
to love the next section of this document. to love the next section of this document.
```YAML ```YAML
...@@ -74,18 +78,18 @@ to love the next section of this document. ...@@ -74,18 +78,18 @@ to love the next section of this document.
:suite_teardown: "free(blah);" :suite_teardown: "free(blah);"
``` ```
If you would like to force your generated test runner to include one or more 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 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: these are _after_ the YAML file, if you are using one:
```Shell ```Shell
ruby generate_test_runner.rb TestFile.c my_config.yml extras.h ruby generate_test_runner.rb TestFile.c my_config.yml extras.h
``` ```
Another option, particularly if you are already using Ruby to orchestrate your 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 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 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 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: set as we did above but this time through Ruby code directly:
```Ruby ```Ruby
...@@ -99,8 +103,8 @@ options = { ...@@ -99,8 +103,8 @@ options = {
UnityTestRunnerGenerator.new.run(testfile, runner_name, options) UnityTestRunnerGenerator.new.run(testfile, runner_name, options)
``` ```
If you have multiple files to generate in a build script (such as a Rakefile), 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 you might want to instantiate a generator object with your options and call it
to generate each runner thereafter. Like thus: to generate each runner thereafter. Like thus:
```Ruby ```Ruby
...@@ -111,33 +115,44 @@ end ...@@ -111,33 +115,44 @@ end
``` ```
#### Options accepted by generate_test_runner.rb: #### 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 The following options are available when executing `generate_test_runner`. You
which are described above. In the `examples` directory, Example 3's Rakefile 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. demonstrates using a Ruby hash.
##### `:includes` ##### `: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 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. universally needed in your generated runners.
##### `:suite_setup` ##### `:suite_setup`
Define this option with C code to be executed _before any_ test cases are run. Define this option with C code to be executed _before any_ test cases are run.
##### `:suite_teardown` ##### `:suite_teardown`
Define this option with C code to be executed ?after all?test cases have
Define this option with C code to be executed ?after all?test cases have
finished. finished.
##### `:enforce_strict_ordering` ##### `: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 This option should be defined if you have the strict order feature enabled in
everything to run smoothly. If you provide the same YAML to the generator as 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. used in CMock's configuration, you've already configured the generator properly.
##### `:plugins` ##### `: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 This option specifies an array of plugins to be used (of course, the array can
CException support, which will add a check for unhandled exceptions in each 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: test, reporting a failure if one is detected. To enable this feature using Ruby:
```Ruby ```Ruby
...@@ -151,42 +166,44 @@ Or as a yaml file: ...@@ -151,42 +166,44 @@ Or as a yaml file:
-:cexception -:cexception
``` ```
If you are using CMock, it is very likely that you are already passing an array 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 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. ignore the plugins that don't require additional support.
### `unity_test_summary.rb` ### `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 A Unity test file contains one or more test case functions. Each test case can
for its collection of test cases. A given project will almost certainly be pass, fail, or be ignored. Each test file is run individually producing results
composed of multiple test files. Therefore, the suite of tests is comprised of for its collection of test cases. A given project will almost certainly be
one or more test cases spread across one or more test files. This script composed of multiple test files. Therefore, the suite of tests is comprised of
aggregates individual test file results to generate a summary of all executed one or more test cases spread across one or more test files. This script
test cases. The output includes how many tests were run, how many were ignored, aggregates individual test file results to generate a summary of all executed
and how many failed. In addition, the output includes a listing of which test cases. The output includes how many tests were run, how many were ignored,
specific tests were ignored and failed. A good example of the breadth and and how many failed. In addition, the output includes a listing of which
details of these results can be found in the `examples` directory. Intentionally specific tests were ignored and failed. A good example of the breadth and
ignored and failing tests in this project generate corresponding entries in the 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. summary report.
If you're interested in other (prettier?) output formats, check into the If you're interested in other (prettier?) output formats, check into the
Ceedling build tool project (ceedling.sourceforge.net) that works with Unity and Ceedling build tool project (ceedling.sourceforge.net) that works with Unity and
CMock and supports xunit-style xml as well as other goodies. CMock and supports xunit-style xml as well as other goodies.
This script assumes the existence of files ending with the extensions This script assumes the existence of files ending with the extensions
`.testpass` and `.testfail`.The contents of these files includes the test `.testpass` and `.testfail`.The contents of these files includes the test
results summary corresponding to each test file executed with the extension set 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 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 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 results, and aggregates and prints a summary. Calling it from the command line
looks like this: looks like this:
```Shell ```Shell
ruby unity_test_summary.rb build/test/ ruby unity_test_summary.rb build/test/
``` ```
You can optionally specify a root path as well. This is really helpful when you 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 are using relative paths in your tools' setup, but you want to pull the summary
into an IDE like Eclipse for clickable shortcuts. into an IDE like Eclipse for clickable shortcuts.
```Shell ```Shell
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册