views:

142

answers:

5

Hi,

I was told by my boss to write unit tests for the little c file (foo.c) I wrote. I read a lot about the background of unit testing online, like testing only one function and making tests fully automated, but I did not find any tutorial about how to implement an actual unit test. I tried the following approach, but failed.

    /*foo.c*/
    #include foo.h
    #if UNIT_TESTING
    #define main example_main
    #endif

    int foo1(...){...}
    int foo2(...){...}

    int main(int argc,char **argv) {
        foo1(...);
        foo2(...);
    }



    /*test_foo.c*/
    #include "foo.h"

    void main(int argc,char **argv) {

        int i = example_main(argc,argv);
        return;
    }



    /*foo.h*/
    int example_main(int argc,char **argv);

As cmd I use:

gcc -Wall -pedantic foo.c test_foo.c -DUNIT_TEST=1 -o test_foo.out

I get following erros:

test_foo.c: warning: return type of ‘main’ is not ‘int’
test_foo.c: In function ‘main’:
test_foo.c warning: unused variable ‘i’
/tmp/ccbnW95J.o: In function `main':
test_foo.c: multiple definition of `main'
/tmp/ccIeuSor.o:foo.c:(.text+0x538b): first defined here
/tmp/ccbnW95J.o: In function `main':
test_foo.c:(.text+0x17): undefined reference to `example_main'
collect2: ld returned 1 exit status

What did I do wrong? Or would you recommend another approach to unit testing.

Thank you!

[update] corrected typos in my code and posted the updated error messages

[update/clarification] I am supposed to use cmockery so I tried the 'calculator.c' example from the cmockery website, but could not get it to run. In my reading I got the impression that unit tests don't rely on a framework. So I wanted to start with a very simple example to play around. The "#if UNIT_TESTING #define main example_main" came from the cmockry 'manual'.

+1  A: 

Maybe it's about missing ';' in the last string of main() func:

int main(int argc,char **argv) {
        foo1(...);
        foo2(...)
    }
Pmod
thanks I updated the code and gave the new error messages
Framester
+3  A: 

I think you should really use a unit testing framework rather then writing your own tests in plain C. Have a look at this list.

muksie
+7  A: 

Unit testing is not only writing and running test cases but also reporting. I would strongly advice you to use a framework like cunit. Beside this, unit tests are best run after build in a continuous integration process, to get warned about breaking changes as early as possible during the development process. With cunit you can generate XML reports that can be analyzed and displayed in a web server (most of the time with the help of XSLT). Doing own quirks will work, but as you add more and more functionality for your tests, you'll be reinventing the wheel unless you use some established framework.

Another comment: I would never mix productive code and test code. Use separated projects, otherwise you'll have difficulties to track the real product changes in your source code repository and have littered your history with a big bunch of test changes.

jdehaan
+1 hurray for unit tests. I used to be reluctant to write a lot of them (too much rush for deadlines), but when I saw it being applied with continuous integration, I never wanted to go back.
I am supposed to use cmockery, but as I understood unit tests don't rely on a framework. So I wanted to start with a very simple example to play around.
Framester
+1  A: 

I think you want a semicolon here...

/*foo.h*/
int example_main(int argc,char **argv);
Brian Hooper
thanks I updated the code and gave the new error messages
Framester
A: 

This question looks like it's really about building test code along with an existing library.

Did the example you followed try to test a program with a main function in it? Why doesn't that example have the error "multiple definition of `main'"?

One solution is to separate the main function in the software under test (SUT) from the rest of the program, and don't include the SUT's main function in the test project build. (Of course, that means the original main function is no longer part of the SUT, meaning you're not testing the original main function.)

apollodude217