Ceedling icon indicating copy to clipboard operation
Ceedling copied to clipboard

Specify extra headers to include in runner

Open austinglaser opened this issue 7 years ago • 3 comments

When using parametrized tests with Ceedling, I often run into situations something like the following:

//error.h

typedef enum {
    NO_ERROR = 0,
    ERROR_FOO,
    ERROR_BAR,
} error_t;
// module.h

#include "error.h"

error_t module_func(int val);
// test_module.c

#include "unity.h"
#include "module.h"
#include "error.h"

TEST_CASE(0, NO_ERROR)
TEST_CASE(5, ERROR_FOO)
TEST_CASE(8, ERROR_BAR)
void test_module_func(int val, error_t error)
{
    TEST_ASSERT_EQUAL(error, module_func(val));
}

Ceedling will generate a runner something like this:

/* AUTOGENERATED FILE. DO NOT EDIT. */

/*=======Test Runner Used To Run Each Test Below=====*/
#define RUN_TEST_NO_ARGS
#define RUN_TEST(TestFunc, TestLineNum, ...) \
{ \
  Unity.CurrentTestName = #TestFunc "(" #__VA_ARGS__ ")"; \
  Unity.CurrentTestLineNumber = TestLineNum; \
  Unity.NumberOfTests++; \
  if (TEST_PROTECT()) \
  { \
      setUp(); \
      TestFunc(__VA_ARGS__); \
  } \
  if (TEST_PROTECT()) \
  { \
    tearDown(); \
  } \
  UnityConcludeTest(); \
}

/*=======Automagically Detected Files To Include=====*/
#include "unity.h"
#include <setjmp.h>
#include <stdio.h>

int GlobalExpectCount;
int GlobalVerifyOrder;
char* GlobalOrderError;

/*=======External Functions This Runner Calls=====*/
extern void setUp(void);
extern void tearDown(void);
extern void test_module_func(int val, error_t error);


/*=======Test Reset Option=====*/
void resetTest(void);
void resetTest(void)
{
  tearDown();
  setUp();
}


/*=======MAIN=====*/
int main(void)
{
  UnityBegin("test_module.c");
  RUN_TEST(test_module_func, 8, 0, NO_ERROR);
  RUN_TEST(test_module_func, 8, 5, ERROR_FOO);
  RUN_TEST(test_module_func, 8, 8, ERROR_BAR);

  return (UnityEnd());
}

This lacks an inclusion of error.h, and so error_t and associated constants are missing.

I think asking Ceedling to figure out this dependency is a little much. However, providing a mechanism to hint this information (maybe a TEST_HEADER macro, like the TEST_FILE hint) would increase the utility of parameter testing a great deal.

Is there an existing way to cause Ceedling to do this? I haven't found it yet. If not, would you be open to a PR to add this functionality?

Versions and config

Versions

Welcome to Ceedling!
  Ceedling::   0.28.1
  CMock::      2.4.4
  Unity::      2.4.1
  CException:: 1.3.1

Config

---

# Notes:
# Sample project C code is not presently written to produce a release artifact.
# As such, release build options are disabled.
# This sample, therefore, only demonstrates running a collection of unit tests.

:project:
  :use_exceptions: FALSE
  :use_test_preprocessor: TRUE
  :use_auxiliary_dependencies: TRUE
  :build_root: build
#  :release_build: TRUE
  :test_file_prefix: test_
  :which_ceedling: vendor/ceedling
  :default_tasks:
    - test:all

#:release_build:
#  :output: MyApp.out
#  :use_assembly: FALSE

:environment:

:extension:
  :executable: .out

:paths:
  :test:
    - +:test/**
    - -:test/support
  :source:
    - src/**
  :support:
    - test/support

:defines:
  # in order to add common defines:
  #  1) remove the trailing [] from the :common: section
  #  2) add entries to the :common: section (e.g. :test: has TEST defined)
  :commmon: &common_defines []
  :test:
    - *common_defines
    - TEST
  :test_preprocess:
    - *common_defines
    - TEST

:unity:
  :use_param_tests: TRUE

:cmock:
  :mock_prefix: mock_
  :when_no_prototypes: :warn
  :enforce_strict_ordering: TRUE
  :plugins:
    - :ignore
    - :callback
  :treat_as:
    uint8:    HEX8
    uint16:   HEX16
    uint32:   UINT32
    int8:     INT8
    bool:     UINT8

:gcov:
    :html_report_type: basic

#:tools:
# Ceedling defaults to using gcc for compiling, linking, etc.
# As [:tools] is blank, gcc will be used (so long as it's in your system path)
# See documentation to configure a given toolchain for use

# LIBRARIES
# These libraries are automatically injected into the build process. Those specified as
# common will be used in all types of builds. Otherwise, libraries can be injected in just
# tests or releases. These options are MERGED with the options in supplemental yaml files.
:libraries:
  :placement: :end
  :flag: "${1}"  # or "-L ${1}" for example
  :common: &common_libraries []
  :test:
    - *common_libraries
  :release:
    - *common_libraries

:plugins:
  :load_paths:
    - vendor/ceedling/plugins
  :enabled:
    - stdout_pretty_tests_report
    - module_generator
...

austinglaser avatar May 30 '18 22:05 austinglaser

The test runners have their own config. Add this to your project.yml:

:test_runner:
  :includes:
    - error.h

By the way, I've personally been fighting parameterized testing in my repo but, keep running into small problems. So I'm curious how you solved the issue of TEST_CASE not being defined anywhere. I can hack around it by defining it in the test file, but only AFTER the runner is created. If it is defined before the runner creates the wrong function calls for the parameterized testing.

dpostorivo avatar Jun 10 '18 21:06 dpostorivo

is there also the possibility to include files only for specific runners? if i add this option, the header is included in all testrunners...

greets peter

pez3 avatar Apr 07 '22 10:04 pez3

Would also really appreciate the possibility of having an include file for just a specific runner. Having generic headers like an "error.h" included in the project.yml is fine. But having headers specific to a single runner defined there is rather ugly when using parameterised testing and wanting to use defines for test parameters.

jonyscathe avatar Nov 02 '22 20:11 jonyscathe