Are there design patterns for a project’s unit tests and integration tests, which let some of those tests be re-used easily to test distribution packages as well?
I am asking for myself. I write some simple little utility command-line programs in Python. I write lots of unittest
test fixtures, even for the little programs. Some are truly “unit tests”. They exercise a single function or class within the program. But some are better called “integration tests” or “end-to-end tests”. They run the entire command-line program via subprocess.run()
, or they call the a high-level entry point to which a [project.scripts]
declaration refers.
After a long time jury-rigging ways to run these programs, e.g. by linking to their software development directory, I am learning how to package these applications. I am reading the Python Packaging Guide. I am writing pyproject.toml
. I am invoking setuptools to make wheels. I am generating application files with shiv
.
Did I get the packaging right? It seems to me that the integration tests ought to be able to test the source distribution or wheel installed to a temporary location, or the application file created by a tool like shiv
or pex
. It might be just a matter of abstracting the invocation in the correct way, or of putting the right decorator on the test classes and test methods.
I’m sure I could figure out, by myself, a way to do this which works for me. But I would much rather learn from someone who has already figured it out. Are others reusing their integration tests this way? What design pattern do you apply to your testing code to make it easier to do?
I did a little reading, and found these threads, which are almost but not quite what I want:
The thread Should sdists include docs and tests?, here on Discuss, talks a bit about people who distribute packages maybe wanting to do integration testing on the distribution packages in their new environment. They might want to re-use the integration tests and unit tests in a source distribution in the new environment.
The Conda-Forge note on testing Python packages seems to talk about a way to declare test invocations in a conda recipe file. Some of the ideas seem applicable. It does not seem to be a reusable design pattern.
Anything else you would recommend that I read?