Blame test/CuTest-README.txt

Packit 3adb1e
Originally obtained from "http://cutest.sourceforge.net/" version 1.4.
Packit 3adb1e
Packit 3adb1e
HOW TO USE
Packit 3adb1e
Packit 3adb1e
You can use CuTest to create unit tests to drive your development
Packit 3adb1e
in the style of Extreme Programming. You can also add unit tests to
Packit 3adb1e
existing code to ensure that it works as you suspect.
Packit 3adb1e
Packit 3adb1e
Your unit tests are an investment. They let you to change your
Packit 3adb1e
code and add new features confidently without worrying about
Packit 3adb1e
accidentally breaking earlier features.
Packit 3adb1e
Packit 3adb1e
Packit 3adb1e
LICENSING
Packit 3adb1e
Packit 3adb1e
Copyright (c) 2003 Asim Jalis
Packit 3adb1e
Packit 3adb1e
This software is provided 'as-is', without any express or implied
Packit 3adb1e
warranty. In no event will the authors be held liable for any damages
Packit 3adb1e
arising from the use of this software.
Packit 3adb1e
Packit 3adb1e
Permission is granted to anyone to use this software for any purpose,
Packit 3adb1e
including commercial applications, and to alter it and redistribute it
Packit 3adb1e
freely, subject to the following restrictions:
Packit 3adb1e
Packit 3adb1e
1. The origin of this software must not be misrepresented; you must not
Packit 3adb1e
claim that you wrote the original software. If you use this software in
Packit 3adb1e
a product, an acknowledgment in the product documentation would be
Packit 3adb1e
appreciated but is not required.
Packit 3adb1e
Packit 3adb1e
2. Altered source versions must be plainly marked as such, and must not
Packit 3adb1e
be misrepresented as being the original software.
Packit 3adb1e
Packit 3adb1e
3. This notice may not be removed or altered from any source
Packit 3adb1e
distribution.
Packit 3adb1e
Packit 3adb1e
Packit 3adb1e
GETTING STARTED
Packit 3adb1e
Packit 3adb1e
To add unit testing to your C code the only files you need are
Packit 3adb1e
CuTest.c and CuTest.h. 
Packit 3adb1e
Packit 3adb1e
CuTestTest.c and AllTests.c have been included to provide an
Packit 3adb1e
example of how to write unit tests and then how to aggregate them
Packit 3adb1e
into suites and into a single AllTests.c file. Suites allow you
Packit 3adb1e
to put group tests into logical sets. AllTests.c combines all the
Packit 3adb1e
suites and runs them. 
Packit 3adb1e
Packit 3adb1e
You should not have to look inside CuTest.c. Looking in
Packit 3adb1e
CuTestTest.c and AllTests.c (for example usage) should be
Packit 3adb1e
sufficient. 
Packit 3adb1e
Packit 3adb1e
After downloading the sources, run your compiler to create an
Packit 3adb1e
executable called AllTests.exe. For example, if you are using
Packit 3adb1e
Windows with the cl.exe compiler you would type: 
Packit 3adb1e
Packit 3adb1e
    cl.exe AllTests.c CuTest.c CuTestTest.c
Packit 3adb1e
    AllTests.exe
Packit 3adb1e
Packit 3adb1e
This will run all the unit tests associated with CuTest and print
Packit 3adb1e
the output on the console. You can replace cl.exe with gcc or
Packit 3adb1e
your favorite compiler in the command above.
Packit 3adb1e
Packit 3adb1e
Packit 3adb1e
DETAILED EXAMPLE
Packit 3adb1e
Packit 3adb1e
Here is a more detailed example. We will work through a simple
Packit 3adb1e
test first exercise. The goal is to create a library of string
Packit 3adb1e
utilities. First, lets write a function that converts a
Packit 3adb1e
null-terminated string to all upper case.
Packit 3adb1e
Packit 3adb1e
Ensure that CuTest.c and CuTest.h are accessible from your C
Packit 3adb1e
project. Next, create a file called StrUtil.c with these
Packit 3adb1e
contents:
Packit 3adb1e
Packit 3adb1e
    #include "CuTest.h"
Packit 3adb1e
    
Packit 3adb1e
    char* StrToUpper(char* str) {
Packit 3adb1e
        return str;
Packit 3adb1e
    }
Packit 3adb1e
    
Packit 3adb1e
    void TestStrToUpper(CuTest *tc) {
Packit 3adb1e
        char* input = strdup("hello world");
Packit 3adb1e
        char* actual = StrToUpper(input);
Packit 3adb1e
        char* expected = "HELLO WORLD";
Packit 3adb1e
        CuAssertStrEquals(tc, expected, actual);
Packit 3adb1e
    }
Packit 3adb1e
   
Packit 3adb1e
    CuSuite* StrUtilGetSuite() {
Packit 3adb1e
        CuSuite* suite = CuSuiteNew();
Packit 3adb1e
        SUITE_ADD_TEST(suite, TestStrToUpper);
Packit 3adb1e
        return suite;
Packit 3adb1e
    }
Packit 3adb1e
    
Packit 3adb1e
Create another file called AllTests.c with these contents:
Packit 3adb1e
Packit 3adb1e
    #include "CuTest.h"
Packit 3adb1e
    
Packit 3adb1e
    CuSuite* StrUtilGetSuite();
Packit 3adb1e
    
Packit 3adb1e
    void RunAllTests(void) {
Packit 3adb1e
        CuString *output = CuStringNew();
Packit 3adb1e
        CuSuite* suite = CuSuiteNew();
Packit 3adb1e
        
Packit 3adb1e
        CuSuiteAddSuite(suite, StrUtilGetSuite());
Packit 3adb1e
    
Packit 3adb1e
        CuSuiteRun(suite);
Packit 3adb1e
        CuSuiteSummary(suite, output);
Packit 3adb1e
        CuSuiteDetails(suite, output);
Packit 3adb1e
        printf("%s\n", output->buffer);
Packit 3adb1e
    }
Packit 3adb1e
    
Packit 3adb1e
    int main(void) {
Packit 3adb1e
        RunAllTests();
Packit 3adb1e
    }
Packit 3adb1e
Packit 3adb1e
Then type this on the command line:
Packit 3adb1e
Packit 3adb1e
    gcc AllTests.c CuTest.c StrUtil.c
Packit 3adb1e
Packit 3adb1e
to compile. You can replace gcc with your favorite compiler.
Packit 3adb1e
CuTest should be portable enough to handle all Windows and Unix
Packit 3adb1e
compilers. Then to run the tests type:
Packit 3adb1e
Packit 3adb1e
    a.out
Packit 3adb1e
Packit 3adb1e
This will print an error because we haven't implemented the
Packit 3adb1e
StrToUpper function correctly. We are just returning the string
Packit 3adb1e
without changing it to upper case. 
Packit 3adb1e
Packit 3adb1e
    char* StrToUpper(char* str) {
Packit 3adb1e
        return str;
Packit 3adb1e
    }
Packit 3adb1e
Packit 3adb1e
Rewrite this as follows:
Packit 3adb1e
Packit 3adb1e
    char* StrToUpper(char* str) {
Packit 3adb1e
        char* p;
Packit 3adb1e
        for (p = str ; *p ; ++p) *p = toupper(*p);
Packit 3adb1e
        return str;
Packit 3adb1e
    }
Packit 3adb1e
Packit 3adb1e
Recompile and run the tests again. The test should pass this
Packit 3adb1e
time.
Packit 3adb1e
Packit 3adb1e
Packit 3adb1e
WHAT TO DO NEXT
Packit 3adb1e
Packit 3adb1e
At this point you might want to write more tests for the
Packit 3adb1e
StrToUpper function. Here are some ideas:
Packit 3adb1e
Packit 3adb1e
TestStrToUpper_EmptyString :  pass in ""
Packit 3adb1e
TestStrToUpper_UpperCase   :  pass in "HELLO WORLD"
Packit 3adb1e
TestStrToUpper_MixedCase   :  pass in "HELLO world"
Packit 3adb1e
TestStrToUpper_Numbers     :  pass in "1234 hello"
Packit 3adb1e
Packit 3adb1e
As you write each one of these tests add it to StrUtilGetSuite
Packit 3adb1e
function. If you don't the tests won't be run. Later as you write
Packit 3adb1e
other functions and write tests for them be sure to include those
Packit 3adb1e
in StrUtilGetSuite also. The StrUtilGetSuite function should
Packit 3adb1e
include all the tests in StrUtil.c
Packit 3adb1e
Packit 3adb1e
Over time you will create another file called FunkyStuff.c
Packit 3adb1e
containing other functions unrelated to StrUtil. Follow the same
Packit 3adb1e
pattern. Create a FunkyStuffGetSuite function in FunkyStuff.c.
Packit 3adb1e
And add FunkyStuffGetSuite to AllTests.c.
Packit 3adb1e
Packit 3adb1e
The framework is designed in the way it is so that it is easy to
Packit 3adb1e
organize a lot of tests.
Packit 3adb1e
Packit 3adb1e
THE BIG PICTURE
Packit 3adb1e
Packit 3adb1e
Each individual test corresponds to a CuTest. These are grouped
Packit 3adb1e
to form a CuSuite. CuSuites can hold CuTests or other CuSuites.
Packit 3adb1e
AllTests.c collects all the CuSuites in the program into a single
Packit 3adb1e
CuSuite which it then runs as a single CuSuite.
Packit 3adb1e
Packit 3adb1e
The project is open source so feel free to take a peek under the
Packit 3adb1e
hood at the CuTest.c file to see how it works. CuTestTest.c
Packit 3adb1e
contains tests for CuTest.c. So CuTest tests itself.
Packit 3adb1e
Packit 3adb1e
Since AllTests.c has a main() you will need to exclude this when
Packit 3adb1e
you are building your product. Here is a nicer way to do this if
Packit 3adb1e
you want to avoid messing with multiple builds. Remove the main()
Packit 3adb1e
in AllTests.c. Note that it just calls RunAllTests(). Instead
Packit 3adb1e
we'll call this directly from the main program.
Packit 3adb1e
Packit 3adb1e
Now in the main() of the actual program check to see if the
Packit 3adb1e
command line option "--test" was passed. If it was then I call
Packit 3adb1e
RunAllTests() from AllTests.c. Otherwise run the real program.
Packit 3adb1e
Packit 3adb1e
Shipping the tests with the code can be useful. If you customers
Packit 3adb1e
complain about a problem you can ask them to run the unit tests
Packit 3adb1e
and send you the output. This can help you to quickly isolate the
Packit 3adb1e
piece of your system that is malfunctioning in the customer's
Packit 3adb1e
environment. 
Packit 3adb1e
Packit 3adb1e
CuTest offers a rich set of CuAssert functions. Here is a list:
Packit 3adb1e
Packit 3adb1e
void CuAssert(CuTest* tc, char* message, int condition);
Packit 3adb1e
void CuAssertTrue(CuTest* tc, int condition);
Packit 3adb1e
void CuAssertStrEquals(CuTest* tc, char* expected, char* actual);
Packit 3adb1e
void CuAssertIntEquals(CuTest* tc, int expected, int actual);
Packit 3adb1e
void CuAssertPtrEquals(CuTest* tc, void* expected, void* actual);
Packit 3adb1e
void CuAssertPtrNotNull(CuTest* tc, void* pointer);
Packit 3adb1e
Packit 3adb1e
The project is open source and so you can add other more powerful
Packit 3adb1e
asserts to make your tests easier to write and more concise.
Packit 3adb1e
Packit 3adb1e
Packit 3adb1e
AUTOMATING TEST SUITE GENERATION
Packit 3adb1e
Packit 3adb1e
make-tests.sh will grep through all the .c files in the current
Packit 3adb1e
directory and generate the code to run all the tests contained in
Packit 3adb1e
them. Using this script you don't have to worry about writing
Packit 3adb1e
AllTests.c or dealing with any of the other suite code.
Packit 3adb1e
Packit 3adb1e
Packit 3adb1e
CREDITS
Packit 3adb1e
Packit 3adb1e
[02.23.2003] Dave Glowacki has added
Packit 3adb1e
(1) file name and line numbers to the error messages, (2)
Packit 3adb1e
AssertDblEquals for doubles, (3) Assert<X>Equals_Msg version of
Packit 3adb1e
all the Assert<X>Equals to pass in optional message which is
Packit 3adb1e
printed out on assert failure.