@@ -349,7 +349,7 @@ def gather_conftest_functions(conftest_path, target):
349349 conftest_path = str (conftest_path )
350350 if os .path .exists (conftest_path ):
351351 print (
352- f"Using \033 [1m{ conftest_path } \033 [0m for global setup and teardown in \033 [1m{ target } \033 [0m."
352+ f"Using \033 [1m{ conftest_path } \033 [0m for setup and teardown for tests in \033 [1m{ target } \033 [0m."
353353 )
354354 conftest = import_module (conftest_path )
355355 setup = conftest .setup if hasattr (conftest , "setup" ) else None
@@ -378,24 +378,57 @@ def discover(targets, pattern, setup=None, teardown=None):
378378 setup and teardown functions can be overridden in the individual test
379379 modules.
380380 """
381+ # To contain the various conftest.py modules for subdirectories. The key
382+ # will be the directory path, and the value will be a tuple containing the
383+ # setup and teardown functions.
384+ conftests = {}
385+ # To contain the TestModule instances.
381386 result = []
382387 for target in targets :
383388 if "::" in target :
384389 conftest_path = Path (target .split ("::" )[0 ]).parent / "conftest.py"
385- setup , teardown = gather_conftest_functions (conftest_path , target )
390+ if str (conftest_path ) not in conftests :
391+ conftests [str (conftest_path )] = gather_conftest_functions (
392+ conftest_path , target
393+ )
394+ setup , teardown = conftests [str (conftest_path )]
386395 module_path , test_names = target .split ("::" )
387396 module_instance = import_module (module_path )
388397 module = TestModule (module_path , module_instance , setup , teardown )
389398 module .limit_tests_to (test_names .split ("," ))
390399 result .append (module )
391400 elif os .path .isdir (target ):
392401 conftest_path = Path (target ) / "conftest.py"
393- setup , teardown = gather_conftest_functions (conftest_path , target )
402+ if str (conftest_path ) not in conftests :
403+ conftests [str (conftest_path )] = gather_conftest_functions (
404+ conftest_path , target
405+ )
406+ setup , teardown = conftests [str (conftest_path )]
394407 for module_path in Path (target ).rglob (pattern ):
395408 module_instance = import_module (module_path )
396- module = TestModule (
397- module_path , module_instance , setup , teardown
398- )
409+ parent_dir = "/" .join (str (module_path ).split ("/" )[:- 1 ])
410+ if parent_dir != target :
411+ # This is a module in a subdirectory of the target
412+ # directory, so ensure any conftest.py in the sub directory
413+ # is imported for setup and teardown.
414+ conftest_path = Path (parent_dir ) / "conftest.py"
415+ if str (conftest_path ) not in conftests :
416+ conftests [str (conftest_path )] = (
417+ gather_conftest_functions (
418+ conftest_path , parent_dir
419+ )
420+ )
421+ local_setup , local_teardown = conftests [str (conftest_path )]
422+ module = TestModule (
423+ module_path ,
424+ module_instance ,
425+ local_setup ,
426+ local_teardown ,
427+ )
428+ else :
429+ module = TestModule (
430+ module_path , module_instance , setup , teardown
431+ )
399432 result .append (module )
400433 else :
401434 conftest_path = Path (target ).parent / "conftest.py"
0 commit comments