Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking the test session current test, stage, fixture and scope from a plugin function #3717

Open
samjl opened this issue Jul 26, 2018 · 1 comment
Labels
type: bug problem that needs to be addressed

Comments

@samjl
Copy link

samjl commented Jul 26, 2018

I am continuing to write a plugin for pytest that implements an alternative to assert adding some extra options (warning and error conditions, continue on failure etc.) and saving all results.

I save the results of my "alternative assert" function and track the current module, class, test function, fixture (inc scope) and test stage (to differntiate between results of setup, call and teardown) for each invocation of the function.

  • I currently do this by saving these as class attributes so they can be used by the plugin modules during a single test session.
    pytest_runtest_setup - start/end of setup stage for a specific test function
    pytest_fixture_setup - setup section of a specific fixture starting/completed - scope of fixture is known so all results for the fixture can be associated with all relavent tests
    pytest_fixture_post_finalizer - specific fixture teardown complete
    pytest_pyfunc_call - call stage started for specified function
    pytest_runtest_teardown - start/end of teardown stage for a specific test

  • The other possible implementation of this would be to add them to the pytest namespace but it is not recommended and deprecated!

  • All the information is inserted into a database as it is retrieved from the pytest hooks, so another possible solution is to retrieve the information from the database rather than keeping track of globals. This is not ideal however becuase I'd like to keep an option to run tests without logging to the database.

Is there a better way to do this?
Any pytest functions I am missing that I can call from my plugin to retrieve the current test, stage fixture, scope?

pytest: 3.6.3
python: 3.5.2

An example output of the plugin results for a test module containing 4 tests is shown below:

Message Status Class Module Phase Scope Source Fixture/Function Test Function Active Setups
module_phase_saved_pass-setup-1:pass PASS None test_class_scope.py setup module module_scoped_fix test_1_module_scope module_scoped_fix
module_phase_saved_pass-setup-2:pass PASS None test_class_scope.py setup module module_scoped_fix test_1_module_scope module_scoped_fix
function_phase_saved_pass-setup:pass PASS None test_class_scope.py setup function function_scoped_fix_1 test_1_module_scope module_scoped_fix,function_scoped_fix_1
setup_device_2:pass PASS None test_class_scope.py setup function function_scoped_fix_1 test_1_module_scope module_scoped_fix,function_scoped_fix_1
test_module_scope_1:call-1:pass PASS None test_class_scope.py call None test_1_module_scope test_1_module_scope module_scoped_fix,function_scoped_fix_1
test_module_scope_1:call-2:pass PASS None test_class_scope.py call None test_1_module_scope test_1_module_scope module_scoped_fix,function_scoped_fix_1
function_phase_saved_pass-teardown:pass PASS None test_class_scope.py teardown function function_scoped_fix_1 test_1_module_scope module_scoped_fix,function_scoped_fix_1
function_phase_saved_pass-setup:pass PASS None test_class_scope.py setup function function_scoped_fix_1 test_2_module_scope module_scoped_fix,function_scoped_fix_1
setup_device_2:pass PASS None test_class_scope.py setup function function_scoped_fix_1 test_2_module_scope module_scoped_fix,function_scoped_fix_1
function_phase_saved_pass-setup:pass PASS None test_class_scope.py setup function function_scoped_fix_2 test_2_module_scope module_scoped_fix,function_scoped_fix_1,function_scoped_fix_2
test_module_scope_2:call-1:pass PASS None test_class_scope.py call None test_2_module_scope test_2_module_scope module_scoped_fix,function_scoped_fix_1,function_scoped_fix_2
test_module_scope_2:call-2:pass PASS None test_class_scope.py call None test_2_module_scope test_2_module_scope module_scoped_fix,function_scoped_fix_1,function_scoped_fix_2
function_phase_saved_pass-teardown:pass PASS None test_class_scope.py teardown function function_scoped_fix_2 test_2_module_scope module_scoped_fix,function_scoped_fix_1,function_scoped_fix_2
function_phase_saved_pass-teardown:pass PASS None test_class_scope.py teardown function function_scoped_fix_1 test_2_module_scope module_scoped_fix,function_scoped_fix_1
class_scoped_fix-setup-1:pass PASS TestClass test_class_scope.py setup class class_scoped_fix test_3_class_scope module_scoped_fix,class_scoped_fix
class_scoped_fix-setup-2:pass PASS TestClass test_class_scope.py setup class class_scoped_fix test_3_class_scope module_scoped_fix,class_scoped_fix
test_3_class_scope:call-1:pass PASS TestClass test_class_scope.py call None test_3_class_scope test_3_class_scope module_scoped_fix,class_scoped_fix
test_3_class_scope:call-2:pass PASS TestClass test_class_scope.py call None test_3_class_scope test_3_class_scope module_scoped_fix,class_scoped_fix
test_4_class_scope:call-1:pass PASS TestClass test_class_scope.py call None test_4_class_scope test_4_class_scope module_scoped_fix,class_scoped_fix
test_4_class_scope:call-2:pass PASS TestClass test_class_scope.py call None test_4_class_scope test_4_class_scope module_scoped_fix,class_scoped_fix
class_scoped_fix-teardown-1:pass PASS TestClass test_class_scope.py teardown class class_scoped_fix test_4_class_scope module_scoped_fix,class_scoped_fix
class_scoped_fix-teardown-2:pass PASS TestClass test_class_scope.py teardown class class_scoped_fix test_4_class_scope module_scoped_fix,class_scoped_fix
module_phase_saved_pass-teardown-1:pass PASS TestClass test_class_scope.py teardown module module_scoped_fix test_4_class_scope module_scoped_fix
module_phase_saved_pass-teardown-2:pass PASS TestClass test_class_scope.py teardown module module_scoped_fix test_4_class_scope module_scoped_fix

Note that
test_1_module_scope and test_2_module_scope are module test functions
test_3_class_scope and test_4_class_scope are test methods of the TestClass class

@pytestbot
Copy link
Contributor

GitMate.io thinks possibly related issues are #538 (Fixture scope documentation), #768 (doctests appear to run before session scope fixtures), #2732 (Fixture scope mixing?), #948 (session scope fixtures can't run tests which does not start with test* or setup*), and #660 (Module scope fixture runs on function scope).

@pytestbot pytestbot added the type: bug problem that needs to be addressed label Jul 26, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug problem that needs to be addressed
Projects
None yet
Development

No branches or pull requests

2 participants