Sunday, June 29, 2014

Writing (very) simple tests in C

A couple of weeks ago I was trying to write some small tests for a toy C program I'm working on

Although there are some nice frameworks for writing units tests in C, I wanted something minimal. So I wrote some functions that let me do that:


void run_test(char* testname, void (*testfunc)()) {
  printf("Running %s\n", testname);
  testfunc();
}

#define RUN_TEST(testname) run_test(#testname, testname);

void tassert(int result, const char* testName, char* formatString, ...) {

  va_list args;
  va_start(args, formatString);
  if (!result) {
    printf("ASSERT FAILED in test \"%s\": ", testName);
    vprintf(formatString, args);
    printf("\n");
  }
  va_end(args);
}

void tassert_equal_ints(int expectedValue,int actualValue, const char* testName) {
  int comparisonResult;
  comparisonResult = expectedValue == actualValue;
  tassert(comparisonResult,
          testName,
          "expected: %d, actual %d", 
          expectedValue, 
          actualValue);
}

These very simple functions allowed me to write small tests. For example:

void testTreeFormation1() {
   Expr* expr;
   OutStream stringOut;
   
   stringOut = createStringOutStream(15);
   expr =
      createAddition(
            createAddition(
               createNumLiteral(10.2),
               createNumLiteral(-13)),
            createNumLiteral(13));

   printExpr(expr, &stringOut);

   tassert_equal_strings("<<11.2 + -13> + 13>",
                        getStringFromStringOutStream(&stringOut),
                        __FUNCTION__);
   
   deepReleaseExpr(expr);
   destroyOutStream(&stringOut);
}

This test is verifies that an expression tree is created as expected.

The main method to execute the tests looks like this:

int main(int argc, char* argv[]) {
  
  printf("Running tests\n");
  
  RUN_TEST(testStrBuffer1);
  RUN_TEST(testStrBuffer2);
  RUN_TEST(testStrBuffer3);
  RUN_TEST(testStrBuffer4);
  RUN_TEST(test1);
  RUN_TEST(testTreeFormation1);
  ...
}