I've just come up with a better answer to this question. If I was a
C/C++ programmer this would have been obvious to me before, and it
solves a bunch of annoyances for me at once.
#ifndef UTIL_H
#define UTIL_H
#include <string>
#include <stdio.h>
#include <stdarg.h>
std::string stringf(const char * format_str, ...) {
va_list arg_list;
char * c_string;
va_start(arg_list, format_str);
vasprintf(&c_string, format_str, arg_list);
std::string answer = std::string(c_string);
free(c_string);
va_end(arg_list);
return answer;
}
namespace {
int tests = 0;
int next_test () {
return ++tests;
}
int current_test () {
return tests;
}
}
void ok (bool is_ok, const char * description, ...) {
std::string status
= stringf("%s %d", is_ok ? "ok" : "not ok", next_test());
va_list arg_list;
char * c_string;
va_start(arg_list, description);
vasprintf(&c_string, description, arg_list);
va_end(arg_list);
printf("%s: %s\n", status.c_str(), c_string);
free(c_string);
}
void all_done () {
printf("1..%d\n", current_test());
}
#endif
On Tue, Apr 16, 2013 at 6:36 AM, Ben Tilly <[email protected]> wrote:
> On Tue, Apr 16, 2013 at 4:02 AM, David Cantrell <[email protected]> wrote:
>> On 15/04/2013 19:35, Ben Tilly wrote:
>>
>>> I'm writing some C++ at the moment that fits into the first group
>>> (performance-critical code). For unit testing I've been emitting TAP
>>> protocol and testing it with prove, but are there better approaches?
>>>
>>> I get a test file with a lot of code that looks like this:
>>>
>>> printf(
>>> "%s %d: Some useful description and maybe a number %d\n",
>>> (expected_value == test_value) ? "ok" : "not ok", ++tests,
>>> some_useful_debugging_info
>>> );
>>
>>
>> How about abusing the pre-processor to build a strangely familiar-looking
>> mini-language for testing:
>>
>> #define OK(result, text) printf("%s %d %s\n", (result ? "ok" : "not ok"),
>> test_number++, text); if(!(result)) { all_gone_buggerup = 1; }
>> #define DONE_TESTING() printf("%s\n", all_gone_buggerup ? "FAILED" :
>> "PASSED"); if(all_gone_buggerup) { return 1; } else { return 0; }
>>
>> obviously you also need to declare and initialise test_number and
>> all_gone_buggerup too.
>>
>> You can then write:
>>
>> int main(void) {
>> int test_number = 0;
>> int all_gone_buggerup = 0;
>> OK(1 == 1, "it works!");
>> OK(2 == 1, "oh no it doesn't");
>>
>> DONE_TESTING();
>> }
>
> You missed the significant fact that I am passing information into the
> description in further parameters. That's essential for me, not a
> nice to have. It allows me to do things like have potentially dubious
> values appear directly in my test output. (I caught a subtle bug due
> to seeing that output just last night!)
_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm