## Cutter Cutter — A Unit Testing Framework for C and C++. |

## Synopsis

    void                setup                               (void);
    void                cut_setup                           (void);
    void                teardown                            (void);
    void                cut_teardown                        (void);
    void                cut_startup                         (void);
    void                cut_shutdown                        (void);
    #define             cut_add_data                        (first_data_name,
                                                             ...)
    #define             cut_add_data_backward_compatibility (context,
                                                             ...)
    #define             cut_set_attributes                  (first_attribute_name,
                                                             ...)
    #define             cut_get_current_test_context
    #define             cut_set_current_test_context        (test_context)
    void                cut_set_message                     (const char *format,
                                                             ...);
    void                cut_set_message_va_list             (const char *format,
                                                             va_list args);
    void                cut_keep_message                    (void);
    void                cut_message                         (const char *format,
                                                             ...);
    #define             CUT_EXPORT

## Description

Cutter is a Unit Testing Framework for C and C++ and has the following features:

- Easy to use. Cutter doesn't introduce any magic macros like CUTTER_DEFINE_TEST_START and CUTTER_DEFINE_TEST_END into your test program. You can write your test program like normal program. You only use `cut_assert_XXX()` to check that your program works as you expect.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      #include <cutter.h>
      #include "my-stack.h"

      void
      test_my_stack (void)
      {
          MyStack *stack = my_stack_new();

          cut_assert_not_null(stack);
          cut_assert(my_stack_is_empty(stack));
          cut_assert_equal_int(0, my_stack_get_size(stack));

          my_stack_push(stack, 10);
          cut_assert(!my_stack_is_empty(stack));
          cut_assert_equal_int(1, my_stack_get_size(stack));

          my_stack_push(stack, 20);
          cut_assert_equal_int(2, my_stack_get_size(stack));

          cut_assert_equal(20, my_stack_pop(stack));
          cut_assert(!my_stack_is_empty(stack));
          cut_assert_equal_int(1, my_stack_get_size(stack));

          cut_assert_equal(10, my_stack_pop(stack));
          cut_assert(my_stack_is_empty(stack));
          cut_assert_equal_int(0, my_stack_get_size(stack));
      }

- Simple but useful output. Cutter works quietly if tests are running without any problems by default. The following is an output of self test:

      1
      2
      3
      4
      5
      ...........................................................

      Finished in 0.213021 seconds

      59 test(s), 246 assertion(s), 0 failure(s), 0 error(s), 0 pending(s), 0 notification(s)

  Cutter just outputs "." for a passed test and a summary at the end. Cutter doesn't output each test name, how many assertions are used for a test and so because we don't need the information on success.

  Cutter outputs many information on failure:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      .....................F.....................................

      1) Failure: test_error
      <"Strange" == cut_test_result_get_test_name(result)>
      expected: <Strange!!!>
       but was: <dummy-error-test>
      test/test-cut-assertions.c:240: cut_assert_test_result()

      Finished in 0.223657 seconds

      59 test(s), 242 assertion(s), 1 failure(s), 0 error(s), 0 pending(s), 0 notification(s)

  The above result is happened because I add a strange expected staring in Cutter's self test:

      1
      cut_assert_equal_string("Strange!!!", cut_test_result_get_test_name(result));

  The strange assertion is written in the 240th line in test/test-cut-assertions.c and the line is in the `cut_assert_test_result()` function. The function is called in test_error test. We expected cut_test_result_get_test_name(result) should return "Strange!!!" but got "dummy-error-name". We can get the above information from Cutter output. This will help your debug.

  Cutter's output format is pragmatic. ' but was:' is indented and aligned with the above 'expected:'. This helps that you find difference between expected value and actual value by your eyes easily. The problem line is formated as 'FILENAME:LINE: FUNCTION' to integrate Emacs. In Emacs's compilation-mode, if the format is appeared in *compilation* buffer, we can jump to FILENAME at LINE with next-error command. (C-x `) This helps that you find the problem line rapidly.

  Cutter supports not only easy test writing but also easy debugging.

## Details

### setup ()

    void                setup                               (void);

### Warning

`setup` has been deprecated since version 1.0.7 and should not be used in newly-written code. Use `cut_setup()` instead.

If you define `setup()` in your test program, cutter will call your `setup()` before each your test is run. If you define `cut_setup()`, `setup()` is ignored.

### cut_setup ()

    void                cut_setup                           (void);

If you define `cut_setup()` in your test program, cutter will call your `cut_setup()` before each your test is run. `cut_setup()` has priority over `setup()`.

Since 1.0.6

### teardown ()

    void                teardown                            (void);

### Warning

`teardown` has been deprecated since version 1.0.7 and should not be used in newly-written code. Use `cut_teardown()` instead.

If you define `teardown()` in your test program, cutter will call your `teardown()` after each your test is run even if a test is failed. If you define `cut_teardown()`, `teardown()` is ignored.

### cut_teardown ()

    void                cut_teardown                        (void);

If you define `cut_teardown()` in your test program, cutter will call your `cut_teardown()` after each your test is run even if a test is failed. `cut_teardown()` has priority over `teardown()`.

Since 1.0.6

### cut_startup ()

    void                cut_startup                         (void);

If you define `cut_startup()` in your test program, cutter will call your `cut_startup()` before each your test case is run. `cut_startup()` has priority over `startup()`.

Since 1.0.6

### cut_shutdown ()

    void                cut_shutdown                        (void);

If you define `shutdown()` in your test program, cutter will call your `shutdown()` after each your test case is run. `cut_shutdown()` has priority over `shutdown()`.

Since 1.0.6

### cut_add_data()

    #define             cut_add_data(first_data_name, ...)

Adds data to use data driven test.

e.g.:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #include <cutter.h>

    void data_translate (void);
    void test_translate (const void *data);

    static const char*
    translate (int input)
    {
       switch(input) {
       case 1:
           return "first";
       case 111:
           return "a hundred eleven";
       default:
           return "unsupported";
       }
    }

    typedef struct _TranslateTestData
    {
        char *translated;
        int input;
    } TranslateTestData;

    static TranslateTestData *
    translate_test_data_new (char *translated, int input)
    {
        TranslateTestData *data;

        data = malloc(sizeof(TranslateTestData));
        data->translated = strdup(translated);
        data->input = input;

        return data;
    }

    static void
    translate_test_data_free (TranslateTestData *data)
    {
        free(data->translated);
        free(data);
    }

    void
    data_translate(void)
    {
        cut_add_data("simple data",
                     translate_test_data_new("first", 1),
                     translate_test_data_free,
                     "complex data",
                     translate_test_data_new("a hundred eleven", 111),
                     translate_test_data_free,
                     NULL);
    }

    void
    test_translate(const void *data)
    {
         const TranslateTestData *test_data = data;

         cut_assert_equal_string(test_data->translated,
                                 translate(test_data->input));
    }

`first_data_name` : | The first data name.
`...` : | The data and destroy function of the first data, followed optionally by more name/data/destroy_function(CutDestroyFunction) triples. The variable arguments should be terminated by `NULL` since 1.0.6.

Since 1.0.3

### cut_add_data_backward_compatibility()

    #define             cut_add_data_backward_compatibility(context, ...)

### Warning

`cut_add_data_backward_compatibility` is deprecated and should not be used in newly-written code.

`context` : |
`...` : |

### cut_set_attributes()

    #define             cut_set_attributes(first_attribute_name, ...)

Sets attributes of the test.

e.g.:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #include <cutter.h>

    void attributes_repeat (void);
    void test_repeat (void);

    void
    attributes_repeat(void)
    {
        cut_set_attributes("description", "a test for repeat function",
                           "bug", "111",
                           "priority", "high",
                           NULL);
    }

    void
    test_repeat(void)
    {
         cut_assert_equal_string_with_free("XXX", repeat("X", 3));
    }

`first_attribute_name` : | The first attribute name.
`...` : | The value of the first attribute, followed optionally by more name/value pairs. `NULL`-terminate is required since 1.0.7.

Since 1.0.4

### cut_get_current_test_context

    #define             cut_get_current_test_context()

Returns the current test context. The current test context is a thread local object. It means that you don't need to care this if you don't create a new thread in your test. This is only needed to care if you create a new thread. You need to pass the current test context in your test thread to the current test context in a created thread.

e.g.:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    int
    your_thread_function(void *data)
    {
        CutTestContext *test_context = data;
        cut_set_current_test_context(test_context);
        ...
    }

    void
    run_your_thread(void)
    {
        int result;
        pthread_t your_thread;

        result = pthread_create(&your_thread, NULL,
                                your_thread_function,
                                cut_get_current_test_context());
        ...
    }

Returns : | a CutTestContext.

Since 1.0.4

### cut_set_current_test_context()

    #define             cut_set_current_test_context(test_context)

Set `test_context` as the current test context. See `cut_get_current_test_context()` for more details.

`test_context` : | the CutTestContext to be the current test context.

Since 1.0.4

### cut_set_message ()

    void                cut_set_message                     (const char *format,
                                                             ...);

### Warning

`cut_set_message` has been deprecated since version 1.1.0 and should not be used in newly-written code. Use `cut_message()` instead.

Sets a message to be used by the next assertion.

`format` : | the message format. See the `printf()` documentation.
`...` : | the parameters to insert into the format string.

Since 1.0.6

### cut_set_message_va_list ()

    void                cut_set_message_va_list             (const char *format,
                                                             va_list args);

### Warning

`cut_set_message_va_list` has been deprecated since version 1.1.0 and should not be used in newly-written code. Use `cut_message()` instead.

Sets a message to be used by the next assertion.

`format` : | the message format. See the `printf()` documentation.
`args` : | the parameters to insert into the format string.

Since 1.0.6

### cut_keep_message ()

    void                cut_keep_message                    (void);

### Warning

`cut_keep_message` has been deprecated since version 1.1.0 and should not be used in newly-written code. Use `cut_message()` instead.

Keeps the current message set by `cut_set_message()` or `cut_set_message_va_list()` after the next assertion.

Since 1.0.6

### cut_message ()

    void                cut_message                         (const char *format,
                                                             ...);

Specifies optional assertion message.

e.g.:

    1
    2
    cut_assert_equal_string("abc", "def",
                            cut_message("should fail!"));

`format` : | the message format. See the `printf()` documentation.
`...` : | the parameters to insert into the format string.

Since 1.1.0

### CUT_EXPORT

    #define             CUT_EXPORT

Marks a function as a exported function. This is needed for just Windows environment. If you want to run your tests on Windows, you need to use this. Otherwise, you don't need to use this.

e.g.:

    1
    2
    3
    4
    5
    CUT_EXPORT void
    test_add (void)
    {
      ...
    }

Since 1.1.2

## See Also

Assertions