Avi*_*hen 6 python automation nose pytest
我的自动化框架使用 pytest 设置/拆卸类型的测试而不是固定装置。我也有几个级别的课程:
BaseClass- 最高,所有测试均从中继承
FeatureClass- 中等,所有与程序功能相关的测试都继承自它
TestClass- 进行实际测试
编辑,例如,我将数据库调用更改为简单的打印
我想在所有设置/拆卸中添加数据库报告。即我希望将军BaseClass setup_method将为测试创建一个数据库条目,并teardown_method用结果更改该条目。我已经尝试过,但我似乎无法摆脱运行时当前运行测试的值的方法。有可能吗?如果不是,我还能怎么做呢?
样本:(在base.py中)
class Base(object):
test_number = 0
def setup_method(self, method):
Base.test_number += 1
self.logger.info(color.Blue("STARTING TEST"))
self.logger.info(color.Blue("Current Test: {}".format(method.__name__)))
self.logger.info(color.Blue("Test Number: {}".format(self.test_number)))
# --->here i'd like to do something with the actual test parameters<---
self.logger.info("print parameters here")
def teardown_method(self, method):
self.logger.info(color.Blue("Current Test: {}".format(method.__name__)))
self.logger.info(color.Blue("Test Number: {}".format(self.test_number)))
self.logger.info(color.Blue("END OF TEST"))
Run Code Online (Sandbox Code Playgroud)
(在 my_feature.py 中)
class MyFeature(base.Base):
def setup_method(self, method):
# enable this feature in program
return True
Run Code Online (Sandbox Code Playgroud)
(在 test_my_feature.py 中)
class TestClass(my_feature.MyFeature):
@pytest.mark.parametrize("fragment_length", [1,5,10])
def test_my_first_test(self):
# do stuff that is changed based on fragment_length
assert verify_stuff(fragment_length)
Run Code Online (Sandbox Code Playgroud)
那么如何获取测试框架的基本父类setup_method中的参数呢?
简短的回答:不,你不能这样做。是的,你可以解决这个问题。
长一点:这些单元测试风格的设置和拆卸只是为了与单元测试风格的测试兼容。他们不支持 pytest 的固定装置,这使得 pytest 很好。
因此,pytest 和 pytest 的 unittest 插件都不提供这些设置/拆卸方法的上下文。如果您有request或function其他一些上下文对象,您可以通过 动态获取灯具的值request.getfuncargvalue('my_fixture_name')。
但是,您拥有的只是self/ cls,并且method作为测试方法对象本身(即不是 pytest 的节点)。
如果你查看插件内部_pytest/unittest.py,你会发现以下代码:
class TestCaseFunction(Function):
_excinfo = None
def setup(self):
self._testcase = self.parent.obj(self.name)
self._fix_unittest_skip_decorator()
self._obj = getattr(self._testcase, self.name)
if hasattr(self._testcase, 'setup_method'):
self._testcase.setup_method(self._obj)
if hasattr(self, "_request"):
self._request._fillfixtures()
Run Code Online (Sandbox Code Playgroud)
首先,请注意,它setup_method()的调用与 pytest 的对象完全隔离(例如self作为测试节点)。
其次,请注意,灯具是在setup_method()调用后准备的。因此,即使您可以访问它们,它们也不会准备好。
所以,一般来说,如果没有一些技巧,你就无法做到这一点。
对于诡计,你必须定义一个 pytest hook/hookwrapper 一次,并记住正在执行的 pytest 节点:
conftest.py或任何其他插件:
import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_protocol(item, nextitem):
item.cls._item = item
yield
Run Code Online (Sandbox Code Playgroud)
test_me.py:
import pytest
class Base(object):
def setup_method(self, method):
length = self._item.callspec.getparam('fragment_length')
print(length)
class MyFeature(Base):
def setup_method(self, method):
super().setup_method(method)
class TestClass(MyFeature):
@pytest.mark.parametrize("fragment_length", [1,5,10])
def test_my_first_test(self, fragment_length):
# do stuff that is changed based on fragment_length
assert True # verify_stuff(fragment_length)
Run Code Online (Sandbox Code Playgroud)
另请注意,出于显而易见的原因MyFeature.setup_method(),必须致电父母super(...).setup_method()。
将cls._item在每个调用规范(即带有每个参数的每个函数调用)上设置。如果您愿意,您还可以将项目或特定参数放入其他全局状态。
还要注意不要将该字段保存在item.instance. 稍后将创建该类的实例,您必须setup_instance/teardown_instance为此使用方法。否则,保存的实例的字段不会被保留并且不可用,如self._item中所示setup_method()。
这是执行过程:
============ test session starts ============
......
collected 3 items
test_me.py::TestClass::test_my_first_test[1] 1
PASSED
test_me.py::TestClass::test_my_first_test[5] 5
PASSED
test_me.py::TestClass::test_my_first_test[10] 10
PASSED
============ 3 passed in 0.04 seconds ============
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4917 次 |
| 最近记录: |