<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Made of Bugs &#187; macros</title>
	<atom:link href="http://blog.nelhage.com/tag/macros/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nelhage.com</link>
	<description>It's software. It's made of bugs.</description>
	<lastBuildDate>Thu, 18 Aug 2011 21:57:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Check Plus: An EDSL for writing unit tests in C</title>
		<link>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/</link>
		<comments>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/#comments</comments>
		<pubDate>Sat, 26 Jun 2010 19:54:53 +0000</pubDate>
		<dc:creator>nelhage</dc:creator>
				<category><![CDATA[Software Engineering]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[check]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.nelhage.com/?p=263</guid>
		<description><![CDATA[Check is an excellent unit-testing framework for C code, used by a number of relatively well-known projects. It includes features such as running all tests in separate address spaces (using fork(2)), which means that the test suite can properly report segfaults or similar crashes without the test runner crashes. My main complaint about Check is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://check.sourceforge.net/">Check</a> is an excellent unit-testing framework for C code, used
by a number of relatively well-known projects. It includes features
such as running all tests in separate address spaces (using
<code>fork(2)</code>), which means that the test suite can properly report
segfaults or similar crashes without the test runner crashes.</p>

<p>My main complaint about Check is that (unsurprisingly for a framework
written in C), it&#8217;s not very declarative. After you define all your
tests as separate functions, you need to write code to manually
collect them into &#8220;test cases&#8221;, which you then collect into &#8220;test
suites&#8221;, which you can then run. While this is an understandable
interface for a C library to provide, as a user I found that it
rapidly annoyed me, and so I wrote Check Plus.</p>

<p><a href="http://github.com/nelhage/check-plus">Check Plus</a> is a simple library I wrote that uses some preprocessor
tricks and GNU C extensions to provide a declarative EDSL within C for
declaring and collecting your test cases. Check-Plus is a single
self-contained header file distributed under the LGPL (like Check), so
it should be easy to pull into your project.</p>

<h2>Example</h2>

<p>Check-Plus lets you declare your Check suites and test cases in a
declarative manner. A simple example, shipped with Check-Plus, would
look like:</p>

<pre><code>#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;

#include "check-plus.h"

#define SUITE_NAME example
BEGIN_SUITE("Example test suite");

#define TEST_CASE core
BEGIN_TEST_CASE("Core tests");

TEST(strcmp)
{
    fail_unless(strcmp("hello", "HELLO") != 0);
    fail_unless(strcasecmp("hello", "HELLO") == 0);
}
END_TEST

TEST(strcat)
{
    char buf[1024] = {0};
    strcat(buf, "Hello, ");
    strcat(buf, "World.");
    fail_unless(strcmp(buf, "Hello, World.") == 0);
}
END_TEST

END_TEST_CASE;
#undef TEST_CASE
END_SUITE;
#undef SUITE_NAME
</code></pre>

<p>Having done that, you can extract the declared test suite using
<code>construct_test_suite(example)</code>, and run it using the standard Check
test runner tools.</p>

<p>You can, of course, define multiple test cases within a single suite,
and you can even define test fixtures using</p>

<pre><code>DEFINE_FIXTURE(setup, teardown);
</code></pre>

<p>within the <code>BEGIN_TEST_CASE</code> &#8230; <code>END_TEST_CASE</code> block.</p>

<p>The equivalent code, without Check-Plus, would look similar, but
instead of the <code>BEGIN_</code> and <code>END_</code> blocks to define the suite and test case, you&#8217;d have to write
something like:</p>

<pre><code>Suite *
example_suite (void)
{
  Suite *s = suite_create ("Example test suite");

  /* Core test case */
  TCase *tc_core = tcase_create ("Core tests");
  tcase_add_test (tc_core, test_strcmp);
  tcase_add_test (tc_core, test_strcat);
  suite_add_tcase (s, tc_core);

  return s;
}
</code></pre>

<p>It&#8217;s not a huge difference, but it&#8217;s big enough that I really
appreciate it once the test suite gets large. For more documentation on Check, check out <a href="http://check.sourceforge.net/doc/check_html/index.html">its manual</a>.</p>

<p>Let me know if you find this useful for anything. Next week, I&#8217;ll do a
writeup on the tricks behind the implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nelhage.com/2010/06/check-plus-an-edsl-for-writing-unit-tests-in-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

