While working on some functional test refactors in pulpcore and pulp_file I’ve learned several of the tests depend on other tests being run before them. This was done with good intentions to reduce the amount of setup and arrangement for every tests, but it creates problems like:
- you can’t run individual tests
- Some tests leave data over which interfere unexpectedly with other tests if you don’t run the right ones after also ← what I ran into
So after some discussion and input during the pulpcore meeting, I like to propose we do two things:
- All tests (function and units) should be 100% independent
- It’s ok to leave behind orphans, but not ok to leave behind any other objects your tests created
The test dependence issue can be a bit tricky to spot, so how do we do this easily? What I came up with was to consider adding code like this to your_plugin/tests/conftest.py For example, I’m in the progress of adding this to pulpcore and pulp_file. Here’s the example for pulp_file:
@pytest.hookimpl(trylast=True)
def pytest_runtest_teardown(item):
file_client = gen_file_client()
pulpcore_client = gen_pulpcore_client()
# This part just makes sure all tasks are finished because some tests don't properly wait after calling delete on things that generate tasks
tasks_api_client = TasksApi(pulpcore_client)
while True:
for task in tasks_api_client.list().results:
if task.state in ["running", "waiting"]:
time.sleep(0.2)
break
else:
break
# All the possible types your plugin could leave behind
types_to_check = [
RepositoriesFileApi(file_client),
# ContentFilesApi(file_client), <--- not checking for content because it's ok to leave behind orphans
RemotesFileApi(file_client),
PublicationsFileApi(file_client),
DistributionsFileApi(file_client),
]
for type_to_check in types_to_check:
if type_to_check.list().count > 0:
raise Exception(f"This test left over a {type_to_check}.")
This will be run at the teardown portion of every test (when run with pytest). By adding this to my PR, I was able to easily refactor the non-independent tests to be independent.