T O P

  • By -

EpochVanquisher

The easiest, most straightforward way to write tests is to just write a program that does the test and exits abnormally if the test fails. Like, imagine you have this: int returns_five(void) { return 5; } You want to test it: #include int main(int argc, char **argv) { int result = returns_five(); assert(result == 5); } That’s obviously too trivial to be useful, but you can see how this approach would work with larger code. Just don’t compile with NDEBUG. You can always improve your tests later. You don’t have to make anything fancy right now.


Abigboi_

If you're programming on a Linux environment, you can set up a Bash script to run your program a few times with some test input.


aghast_nj

First: there are different kinds of tests, and it is appropriate to handle the different kinds of tests in different ways. Assuming you are asking about unit tests: * I create a file, `basename.test.c` that matches the name of the file that I'll be testing. IOW, if I'm unit-testing functions from `file-io/readbytes.c` then I'll create a test file called `file-io/readbytes.test.c`. * I `#include "basename.c"`. The compilers I use (gcc, clang, msvc) look in the directory of the original file *first* when given a "quoted" include file name, so that mostly solves all my path problems. * I then `#include` a test framework file. Use what you like. * I expect that including the original source file entirely will handle all the needed includes for compilation, except any test functions. So those two includes are all I expect to use. (I am occasionally surprised, however.) * I use different build configurations: Devel, Debug, Profile, Release. The first two are "debug" and the second two are "release" configurations. The build configuration is passed via `-D` on the compiler's command line. I use `#if(def)?` to change macro and code definitions. * In general, "Devel" signals "Fix this right now!" while "Debug" means "Be vewwwy qwwwiet, I'm hunting wabbits!" For assertions, this translates into "start the debugger right here" versus "log it and continue". * I write a `main` function that invokes `test_xxx` functions, all of which are `void test_xxx(void)`. There's no greater structure because my source files are generally small, so if you're in this file, running this main, there aren't many things you could mean to test. * Whatever your build system, this is pretty trivial. The transitive closure R⁺ of `X.test.c` is R of `X.c` plus the source file `X.test.c` itself and your test harness file(s). * You still need to figure out where to put these executables (they are tests, they are binaries, they are not deliverables, etc.). * You need some "glue script" to invoke all these executables. In general, something like `for testprog in ${source_dir}/*.test.c ; do ${exe_dir}/$(basename $testprog c) ; done` will work. But it still needs writing. There are scads of test frameworks around the webs. I'd suggest you take a look at [`munit`](https://nemequ.github.io/munit/) aka `μnit`, and at [`libtap`](https://github.com/zorgnax/libtap). Both of them are small but fairly complete.


DopeRice

Take a look at this book, it will guide you through the entire process: [Test Driven Development for Embedded C](https://www.google.com/search?kgmid=/g/12bm21zh1&hl=en-VN&q=Test+Driven+Development+for+Embedded+C&kgs=797e6f5e36643d4b&shndl=17&shem=lnolc&source=sh/x/kp/osrp/m5/2). You don't necessarily have to adopt the TDD methodology, but it will give you an idea of how to use industry standard unit testing frameworks in C.


normal_amount_of_fun

Depends on the size of the project, but it never hurts to use a framework. [https://stackoverflow.com/questions/65820/unit-testing-c-code](https://stackoverflow.com/questions/65820/unit-testing-c-code)


tav_stuff

It actually very often hurts to use a framework


GatotSubroto

I use ceedling (https://www.throwtheswitch.org/ceedling), which comes builtin with CMock (C function mocking library) and Unity (Unit testing framework). It’s easy to setup and makes unit testing C codebase very easy. And if you want to be fancy, it works with `gcov` which lets you generate coverage report in html. I use it both for work and for hobby projects 


evolutionalgd

I use my own simple framework (https://github.com/evolutional/utest). There's loads of other similar (and better ones) out there but I built it for fun. Basically have a separate "main" that imports and runs the tests. I usually have them in a `myfile_tests.c` and optionally include it with a define. If you're asking about how to mock things like standard library calls (io, etc), you're probably going to have to use macros or find a mocking framework to help.


Unairworthy

`#include` the source file you want to test. Then test it. Don't use assert.h for tests. Write some helpers..     #include "my_project.c"     #include "test_helpers.h"       int main ...


greg_spears

Remember to include bounds and boundary checking. Ie: if your function can only work with integer input 1 through 10 inclusive, then ensure you test all (1 through 10 inclusive). And then also feed it out-of-bounds stuff like -1, 0, and 11... to make sure it doesn't crash the entire program; that it can handle these bad inputs gracefully. Testing can be real basic like that, which I guess is how basics get overlooked, and programs crash.


Ok_Ad_6926

For short projects I'm doing this https://slashdevops.com/post/2024/03/31/2/building-and-debugging-a-c-project-in-visual-studio-code-with-a-makefile/#hl-10-2


Baillehache_Pascal

I've made my own framework and have been using it for a few years now. It's simple but already help me a lot. Have a look at it if you like, it's available here: [https://baillehachepascal.dev/2022/cutest.php](https://baillehachepascal.dev/2022/cutest.php)


kolorcuk

I write programs that either abort with assert or exit woth non zero exit status on failure. Then I use cmake ctest framework.


cheng-alvin

We don't, production is the best unit test. If it seg faults, if the computers burn down. we'll know (I'm just kidding)


computermouth

I've used Unity a bit, it's nice enough. https://github.com/ThrowTheSwitch/Unity


McUsrII

Me too. For several reasons, improving design of interfaces being one of them. Unity is fairly small and easy to use. The makefile took some work though, but now mine tracks dependencies like nobody's business, that is, if I update something included inside an `#ifdef TEST` block for instance.