Easiest way of unit testing C code with Python
Question:
I’ve got a pile of C code that I’d like to unit test using Python’s unittest library (in Windows), but I’m trying to work out the best way of interfacing the C code so that Python can execute it (and get the results back). Does anybody have any experience in the easiest way to do it?
Some ideas include:
- Wrapping the code as a Python C extension using the Python API
- Wrap the C code using SWIG
- Add a DLL wrapper to the C code and load it into Python using ctypes
- Add a small XML-RPC server to the c-code and call it using xmlrpclib (yes, I know this seems a bit far-out!)
Is there a canonical way of doing this? I’m going to be doing this quite a lot, with different C modules, so I’d like to find a way which is least effort.
Answers:
Using ctypes would be my first instinct, though I must admit that if I was testing C code that was not going to be interfaced from Python in the first place, I would just use check. Check has the strong advantage of being able to properly report test cases that segfault. This is because it runs each test case in a separate process.
Now if you are going to create a python wrapper for the C code anyway, I would simply unittest the wrapper. In addition to the methods you listed above, you could also use Cython to write such a wrapper with python-like code and then unittest it from Python.
I think that the exact solution depends on your code. Not all libraries are easily suitable for wrapping as a DLL. If your is, then ctypes
is certainly the easiest way – just make a DLL out of your library and then test it with ctypes
. An added bonus is that you now have your library conveniently wrapped as a standalone DLL which helps to decouple your application.
Sometimes, however, a more thorough interaction will be required between your C code and the testing Python code. Then, it’s probably best to hook it as an extension, for which SWIG is a pretty good tool that will automate away most things you’ll find boring about the process.
I’ve got a pile of C code that I’d like to unit test using Python’s unittest library (in Windows), but I’m trying to work out the best way of interfacing the C code so that Python can execute it (and get the results back). Does anybody have any experience in the easiest way to do it?
Some ideas include:
- Wrapping the code as a Python C extension using the Python API
- Wrap the C code using SWIG
- Add a DLL wrapper to the C code and load it into Python using ctypes
- Add a small XML-RPC server to the c-code and call it using xmlrpclib (yes, I know this seems a bit far-out!)
Is there a canonical way of doing this? I’m going to be doing this quite a lot, with different C modules, so I’d like to find a way which is least effort.
Using ctypes would be my first instinct, though I must admit that if I was testing C code that was not going to be interfaced from Python in the first place, I would just use check. Check has the strong advantage of being able to properly report test cases that segfault. This is because it runs each test case in a separate process.
Now if you are going to create a python wrapper for the C code anyway, I would simply unittest the wrapper. In addition to the methods you listed above, you could also use Cython to write such a wrapper with python-like code and then unittest it from Python.
I think that the exact solution depends on your code. Not all libraries are easily suitable for wrapping as a DLL. If your is, then ctypes
is certainly the easiest way – just make a DLL out of your library and then test it with ctypes
. An added bonus is that you now have your library conveniently wrapped as a standalone DLL which helps to decouple your application.
Sometimes, however, a more thorough interaction will be required between your C code and the testing Python code. Then, it’s probably best to hook it as an extension, for which SWIG is a pretty good tool that will automate away most things you’ll find boring about the process.