-
Notifications
You must be signed in to change notification settings - Fork 17
Description
Currently I am unaware of any intended/documented functionality enabling the ability to call other pre-existing tests to in order to reuse existing test behavior and/or to validate chained functionality. For example, it may be easy or useful to validate the output of a function by passing it to the output of another existing test. If the output of one function that's being tested can be validated using another existing this would make developing tests much easier. This is trivial to implement using pytest's base Class methodology, but doesn't quite seem to align with describe-blocks.
For example:
Class TestFoo:
test_foo(self, fixture1, arg1):
foo_result = foo(fixture1, arg1)
assert foo_result
Class TestBar:
test_bar(self, fixture1, fixture2, arg1, arg2):
bar_result = bar(fixture2, arg1, arg2)
assert bar_result
TestFoo().test_foo(fixture1, bar_result)
However using pytest-describe it isn't clear how to achieve similar functionality, if preservation of this feature has been intentionally designed in at all.
I recognize that this edge-case could be resolved by extracting the shared functionality out into a globally accessible function, but I find this to be a deeply inelegant solution and go against the essence of describe-blocks and test groups.
E.g.,
# Extracting functionality to test `foo` here is very clunky and defeats the entire point of describe-blocks / test groups
def shared_test_foo(fixture1, arg1):
foo_result = foo(fixture1, arg1)
assert foo_result
Class TestFoo:
test_foo(self, fixture1, arg1):
shared_test_foo(fixture1, arg1)
Class TestBar:
test_bar(self, fixture1, fixture2, arg1, arg2):
bar_result = bar(fixture2, arg1, arg2)
assert bar_result
shared_test_foo(fixture1, bar_result)
make_module_from_function
?
The make_module_from_function
function in plugin.py
kind of makes this possible, but is not documented anywhere publicly. Additionally, when called statically from another test I am unaware of how it interacts with the behaves_like
functionality and other features like fixtures applied to the enclosing block via pytest.mark.usefixtures
and what behavior is preserved or breaks.
For example:
from pytest_describe.plugin import make_module_from_function
def describe_foo():
test_foo(fixture1, arg1):
foo_result = foo(fixture1, arg1)
assert foo_result
def describe_bar():
test_bar(fixture1, fixture2, arg1, arg2):
bar_result = bar(fixture2, arg1, arg2)
assert bar_result
make_module_from_function(describe_foo).test_foo(fixture1, bar_result)
This works from my testing, but I don't entirely understand its potential repercussions.
Potential solutions:
I think make_module_from_function
gets most of the way to a functional solution to this problem. However, it is currently not listed in pytest_describe.__all__
thus requiring manual import from plugin.py
, and there is no documentation about it so it is unclear how it behaves when called inside another test. This may be an easy workaround to get similar functionality with minimal effort, but it needs analysis and documentation.
Alternatively, it would be convenient if it were possible for describe-blocks to be automatically evaluated to accessible modules at runtime somehow, potentially through a fixture? This would be a much cleaner solution if it enabled the ability to reference tests via something like describe_foo.test_foo(...)
, but I recognize this may be a much more difficult solution to implement.