Live data from Hacker News

Running C unit tests with Pytest

p403n1x87.github.io

11–20 of 44 posts

Re: Running C unit tests with Pytest

#11
This is brilliant.

pytest is by far the most productive testing framework I've ever tried, for any language. It's so good that it switched me from treating tests as a necessary chore to actively enjoying writing them.

Using ctypes to exercise a C module like this is brilliant - especially the mechanisms used here to work around segmentation faults.

Reminds me of SQLite, which is written in C but uses TCL for most of its test suite.

Re: Running C unit tests with Pytest

#13
post #3

@pytest.fixture def libfact(): yield CDLL("./fact.so") FWIW that's pretty confusing as it gives the impression the library is reloaded for every test, but iirc dlopen() will just return a handle to the existing one. I don't think ctypes has a good way to unload dlls so it should probably be `fixture(scope='session')`. That gets more relevant when on-the-fly compilation is added to the mix, spawning a compiler for eve…

That's a good observation. Towards the end the fixture is dropped in favour of a module-like object, which spaws the compiler once per test run. One could enhance this to skip compilation in the sandbox process to avoid unnecessary compilations.

Re: Running C unit tests with Pytest

#14

Shameless self-plug since I recently made a small header-only C testing "framework": https://github.com/rubenvannieuwpoort/c_unit_tests Feels a bit more in line with the spirit of C (small language, few dependencies).

Nice. Now how could I get this to work on a small embedded device compiker (gbdk using lcc), which likely doesn't have that constructor attitude.

Re: Running C unit tests with Pytest

#16

Shameless self-plug since I recently made a small header-only C testing "framework": https://github.com/rubenvannieuwpoort/c_unit_tests Feels a bit more in line with the spirit of C (small language, few dependencies).

This is really nice. I wonder if there is a way to make this work without constructors.

Re: Running C unit tests with Pytest

#17
post #12

We've had a lot of success combining that approach (cffi instead of ctypes) with property-based testing ( https://github.com/HypothesisWorks/hypothesis ) for the query engine at backtrace: https://engineering.backtrace.io/2020-03-11-how-hard-is-it-t... .

Have you exposed the C library to Python via ctypes as OP or have you taken a different approach?

Re: Running C unit tests with Pytest

#18
post #14

Shameless self-plug since I recently made a small header-only C testing "framework": https://github.com/rubenvannieuwpoort/c_unit_tests Feels a bit more in line with the spirit of C (small language, few dependencies).

Nice. Now how could I get this to work on a small embedded device compiker (gbdk using lcc), which likely doesn't have that constructor attitude.

...after some thinking, maybe it would be possible to do a manual preprocess using a simple python script that collects all the tests and inserts them in the test main.

Re: Running C unit tests with Pytest

#19

How would you go to do this for c++? Specifically for classes and templates, is there an easy way to call code without having to manually write the demangled names of the functions?

Not that I know of. If I were doing it I'd expose a library / interface with pybind11 to test, but really I find Googles unit testing framework or boosts to both be pretty effective.

Re: Running C unit tests with Pytest

#20
post #14

Shameless self-plug since I recently made a small header-only C testing "framework": https://github.com/rubenvannieuwpoort/c_unit_tests Feels a bit more in line with the spirit of C (small language, few dependencies).

Nice. Now how could I get this to work on a small embedded device compiker (gbdk using lcc), which likely doesn't have that constructor attitude.

One approach is to build test traversal machinery out of function static variables and have every TEST() macro turn into a function that takes a pointer to some state controlling which test to run next.

You don't need malloc if using local variables either, which is helpful when your target doesn't have malloc or when debugging memory problems on targets that do. It's nice to know the test framework cannot be leaking or use-after-free anything.

Post reply on HN