Live data from Hacker News

MinUnit – A minimal unit testing framework for C (2002)

jera.com

31–40 of 56 posts

Re: MinUnit – A minimal unit testing framework for C (2002)

#31
post #12

One thing I'm pretty doctrinaire about when it comes to this sort of thing is printing out more than just a simple message. Quite often, this makes the problem obvious with no need for deeper investigation. To do this I have a bunch of macros like this: /* check A and B are equal. */ #define EQ_II(A,B,M) (CheckEQII((A),(B),M,#A,#B,__FILE__,__LINE__)) You use it like this: EQ_II(i,3,"blah blah blah"); CheckEQII looks…

That's why I love pytest.

You just `assert` an expression, and on failure it'll break down each sub-expression and show whatever it yielded, plus by default it captures all output (stdout and stderr) and prints it out only on failure (so logging and other console output is not painfully annoying while testing) and the fixtures systems is just fantastic and parameterised tests make for much clearer data-driven (/table-driven) tests and the tests selection at the CLI is awesome.

And all the complexity is in the test framework and runner, all you do is write

    def test_thing(a_fixture):
        assert foo(bar) == a_fixture.some_thing()
or whatever.

Re: MinUnit – A minimal unit testing framework for C (2002)

#33
post #24
post #10

Earlier quoted context omitted.

It always really bothered me that there had to be so much syntactical sugar on top of testing frameworks. Unit testing should be written in exactly the syntax of the language you are working with. I don't want to have to carry that additional crap in my working memory while writing code. I can't stand having to look up Gherkin syntax just to write a few dumb tests. The only reason I see the usefulness of additional s…

OTOH never rule out how KISS is the enemy of billable hours and don't underestimate CDD's ability (consultability driven development) to come up with solutions to non problems. YMMV, the BDD implementations I've seen so far did not convince me of its value to put it mildly.

I never understood the value of Gherkin/Cucumber style testing until I worked with a QA engineer. The engineer started writing the tests (in Cucumber format) as a way to write __manual__ tests: they allow you to write 'do this, then that, verify this' in a structured manner. Automating this was a secondary goal: once you have (relatively) structured manual tests, it's nice if you can automate them, while still retaining the possibility to run them manually. This is actually important, and they would typically be end-to-end UI tests, which can be quite fragile when completely automated. Having them in a human-friendly format allows you to have a manual fallback if e.g. a changed identifier blocks you from running the automated test.

Re: MinUnit – A minimal unit testing framework for C (2002)

#35

And then in D it's built-in to the compiler so it's a 1 liner of sorts: unittest { ... } and they all run during compilation. https://dlang.org/spec/unittest.html

I'm surprised that isn't used in other languages, having the test right next to the code seems such a good idea.

Re: MinUnit – A minimal unit testing framework for C (2002)

#36
Why stick to three lines? With only a couple more you could reduce the boiler-plate needed to use it.

I wrote a minimal C test framework too: https://github.com/codeplea/minctest It's got some real-world usage. Still only just one header file, but it'll time each test and if an equal assertion fails it'll print the variable values.

Re: MinUnit – A minimal unit testing framework for C (2002)

#37

And then in D it's built-in to the compiler so it's a 1 liner of sorts: unittest { ... } and they all run during compilation. https://dlang.org/spec/unittest.html

what happens if you write a really slow test? is there some way to take advantage of the inbuilt console reporting, etc. without running them after every compile?

Re: MinUnit – A minimal unit testing framework for C (2002)

#38
post #22
post #9

Why not just 1 line? Of course, the application will halt after one test fails, but some people like it this way. #include Usage: void test_foo() { assert(foo() == 4 /* foo should be 4 */); } Output would be something like Assertion failed at "foo() == 4 /* foo should be 4 */" If you run the application in a debugger like GDB, you can see the frame when the abort trap is called.

I actually implemented a basic unit test framework in C yesterday and started with basic asserts like you point out, however once I got it working I switched to return values not unlike TFA. The obvious problem with assertions in that they kill your test program immediately at the first failure instead of doing additional tests and potentially give a clearer picture of what's broken exactly. They're also not very fle…

I mostly agree with you, but I would like to make something clear.

>I'm also tempted to say that if you need to use GDB to figure out where your tests have failed exactly your framework is not particularly user friendly.

Am I missing something?

  #include 
  
  int main(void)
  {
  	assert(0);
  	return 0;
  }
When using clang I get a clear message that includes the filename, the line, and the function:

  assert.bin: assert.c:5: int main(void): Assertion `0' failed.

Re: MinUnit – A minimal unit testing framework for C (2002)

#39
post #12

One thing I'm pretty doctrinaire about when it comes to this sort of thing is printing out more than just a simple message. Quite often, this makes the problem obvious with no need for deeper investigation. To do this I have a bunch of macros like this: /* check A and B are equal. */ #define EQ_II(A,B,M) (CheckEQII((A),(B),M,#A,#B,__FILE__,__LINE__)) You use it like this: EQ_II(i,3,"blah blah blah"); CheckEQII looks…

That's why I love pytest. You just `assert` an expression, and on failure it'll break down each sub-expression and show whatever it yielded, plus by default it captures all output (stdout and stderr) and prints it out only on failure (so logging and other console output is not painfully annoying while testing) and the fixtures systems is just fantastic and parameterised tests make for much clearer data-driven (/table…

On top of that, it'll compare complex structures to each other, so you could have a very large list of dicts that contain a custom data structure and it'll show you a diff and exactly where the mismatch is. Then it can auto-drop to the debugger and you can inspect previous variables to inspect the root cause, if not immediately apparent. Going back to C land, as much as I enjoy it, the tooling feels like the stone ages. I get that it's a lot harder for a language that compiles down to machine code, but dang.

Re: MinUnit – A minimal unit testing framework for C (2002)

#40
post #37

And then in D it's built-in to the compiler so it's a 1 liner of sorts: unittest { ... } and they all run during compilation. https://dlang.org/spec/unittest.html

what happens if you write a really slow test? is there some way to take advantage of the inbuilt console reporting, etc. without running them after every compile?

It's not compiled into your binary unless you want it to be. It's ran at compile time every time you compile, though I'm sure there's a flag to not run unit testing, and maybe with version() you might be able to block out the time ocnsuming tests. Not sure what you'd do in D that'd be so time consuming though.

Edit:

URL to version() docs:

https://dlang.org/spec/version.html

Post reply on HN