ThrowTheSwitch / Ceedling

Ruby-based unit testing and build system for C projects
http://throwtheswitch.org
Other
586 stars 246 forks source link

Order of "include's" does not allow to redefine some defines into "under-tested header file". #220

Open m-chichikalov opened 6 years ago

m-chichikalov commented 6 years ago

Hi. I'm trying to test some simple library under different conditions. The way to do that is define some constant in header file test_xxxx_1.h and use different test files. However, the order of includes in generated file does not allow me to do that.
Example:

my_library.c

#include <stdlib.h>
#include <stdio.h>
#include "my_library.h"
// static functions
...

my_library.h

#ifndef TYPE_OF_ELEMENT_OF_BUFFER
    #define TYPE_OF_ELEMENT_OF_BUFFER     char
#endif /* TYPE_OF_ELEMENT_OF_BUFFER */
...

test_my_library_1_condition.c

/*******************************************************************************
 *    INCLUDED FILES
//-- unity: unit test framework
#include "test_my_library_1_condition.h"
#include "unity.h"
//-- module being tested
#include "my_library.h"
//-- other modules that need to be compiled
//-- mocked modules
 /*******************************************************************************
 *    SETUP, TEARDOWN
void setUp(void)       {}
void tearDown(void) {}
/*******************************************************************************
 *    TESTS
...

test_my_library_1_condition.h

#ifndef TEST_TEST_CIRCULAR_BUFFER_CHAR_H_
#define TEST_TEST_CIRCULAR_BUFFER_CHAR_H_

#define TYPE_OF_ELEMENT_OF_BUFFER     char

#endif /* TEST_TEST_CIRCULAR_BUFFER_CHAR_H_ */

Generated c file looks like

#include "build/temp/_test_my_library_1_condition.c"
#include "my_library.h"
#include "unity.h"
#include "test_my_library_1_condition.h"
...

What if swop "my_library.h" and "test_my_library_1_condition.h" up?

I'm going to write "test_my_library_2_condition.c" and "test_my_library_2_condition.h" and define TYPE_OF_ELEMENT_OF_BUFFER as integer. Maybe I just don't know another way and it's simple and easy? Thank you in advance!

mvandervoord commented 6 years ago

I'm sorry, I'm not clear on which generated file you are discussing. A mock? A runner? Something generated with module:create?

m-chichikalov commented 6 years ago

Ok, sorry for that. Generated source file into folder \ceedling\build\test\preprocess\files It has first included "under-tested header file" and after that a header file of a test file.

mvandervoord commented 6 years ago

That's strange.

I can double-check, but I'm pretty sure that Ceedling has nothing to do with this problem. That file is created by your preprocessor (likely gcc, unless you've specified something else) and it's just the output of your course code when run through the preprocessor. It should resemble your original source file, but without the #ifdefs and whatnot because they have already been preprocessed.

m-chichikalov commented 6 years ago

Thank you. Maybe you could advise some way? How can I set individual preprocessing parameters for each UT file. Now we can set the defines like below:

:defines:
  :test:
    - UNIT_TESTING  
    - OFF=0
    - ON=1
    - FEATURE_X=ON
  :source:
    - FEATURE_X=ON 

What if add feature to have opportunity to do like below?

:defines:
  :test:
       :test_file_1:
           - UNIT_TESTING  
           - OFF=0
           - FEATURE_X=ON
       :test_file_2:
           - UNIT_TESTING 
           - OFF=1
           - FEATURE_X=OFF
  :source:
    - FEATURE_X=ON 
mvandervoord commented 6 years ago

I haven't used it much recently, but I believe you can place a yaml file in the same directory with the same name as your file and it will override the defines. For example, if you have test_file_1.c, you could place test_file_1.yml and have it include its own set of defines.

It's been a long time since anyone has talked about this feature... which either means it is just working, or it's not there at all. ;)

Miv13 commented 5 years ago

@mvandervoord I don't think it's there (or at least the alternate YAML isn't used by default) - and I would REALLY appreciate if it was. I believe it would help me with https://github.com/ThrowTheSwitch/Ceedling/issues/304#issuecomment-431794297 where I need to run some tests with a different define and an additional compiler flag (-flto, which is impractical for other tests, as it significantly slows down the linker).

EDIT: unless you meant the :options_paths: bit, which allows specifying additional YAML file on the command line?

laurensmiers commented 5 years ago

@Miv13 I think I found a way, I have the following in my main project.yml :

:defines: :test:

ceedling test:ui_ctrl will now have TEST_CONFIG defined, none of the other tests will (atleast in my case). it's this line that takes care of it: https://github.com/ThrowTheSwitch/Ceedling/blob/master/lib/ceedling/test_invoker.rb#L90

But I haven't found a way to include different compiler flags, and I couldn't find any place where the alternate yaml (with the test file name) is taken into account. This would be a great feature imo, I think I'll make a separate issue for this.

Miv13 commented 5 years ago

@laurensmiers Thanks for the reply (and a part of the solution), but I'm afraid that without the compiler flag this won't do much for me. I found a different workaround for now (setting the compiler flag for specific files rather than specific tests), which allows me to do my thing without making the process that much longer. I'm currently struggling to make it work with gcov, but there doesn't seem to be any analogous option for it.