How can you control the test collection order in PyTest using the pytest_collect_file hook?
When using the pytest_collect_file hook to gather both manual and automation tests, PyTest runs this collector first, preventing access to automation test IDs needed to avoid duplicates.
The goal is to report manual test results alongside automation tests without redundancy. Is there a way to change the collection order or adjust pytest_collect_file behavior to achieve this?
I hit this same problem earlier. The key thing to understand is that pytest_collect_file fires the moment pytest sees a file, so it always runs early in the collection phase. That means you can’t really control or delay its execution order.
What does work is shifting the actual logic to a later hook. Instead of trying to make decisions inside pytest_collect_file, store whatever metadata you need there, and then do the real comparison or ordering inside pytest_collection_modifyitems, since that hook runs after all tests are collected:
def pytest_collection_modifyitems(session, config, items):
# You can reorder items or compare automation + manual test IDs here.
This way, you get access to the full list of items and can safely calculate ordering.
Exactly. Trying to do everything inside pytest_collect_file won’t work if your logic depends on other files or tests, because that hook runs too early and knows nothing about the rest of the suite.
What I usually do is let pytest_collect_file only do lightweight tagging or marking. Then, I push all the real processing filtering, deduplication, ordering into pytest_collection_modifyitems. Once that hook runs, pytest has a complete view of all tests, so you can merge your manual and automation lists cleanly and enforce whatever ordering rules you want.
To add to what @shashank_watak and @miro.vasil already explained, another effective trick is attaching metadata during collection and then sorting later in pytest_collection_modifyitems.
For example, inside a collector, you can flag manual tests like:
item.manual = True
Then reorder everything in pytest_collection_modifyitems:
items.sort(key=lambda x: getattr(x, "manual", False))
This lets you put manual tests before or after automation tests, and also compare IDs to prevent duplicates during the final ordering phase. You still keep all the logic centralized in the modify-items hook, which is where pytest actually allows you full control.