我使用selenium进行端到端测试,但我无法了解如何使用setup_class
和teardown_class
方法。
我需要在setup_class
方法中设置浏览器,然后执行一系列定义为类方法的测试,最后在teardown_clas
方法中退出浏览器。
但从逻辑上讲,这似乎是一个糟糕的解决方案,因为实际上我的测试不是用于类,而是用于对象。我在每个测试方法中都传递了self
param,因此我可以访问对象'瓦尔:
class TestClass:
def setup_class(cls):
pass
def test_buttons(self, data):
# self.$attribute can be used, but not cls.$attribute?
pass
def test_buttons2(self, data):
# self.$attribute can be used, but not cls.$attribute?
pass
def teardown_class(cls):
pass
为类创建浏览器实例似乎不正确..它应该分别为每个对象创建,对吧?
那么,我需要使用__init__
和__del__
方法而不是setup_class
和teardown_class
?
答案 0 :(得分:49)
根据Fixture finalization / executing teardown code,使用addfinalizer
是“历史性的”。
作为历史记录,另一种编写拆卸代码的方法是将一个请求对象接受到fixture函数中,并可以一次或多次调用其request.addfinalizer:
目前设置和拆解的最佳做法是使用yield
import pytest
@pytest.fixture()
def resource():
print("setup")
yield "resource"
print("teardown")
class TestResource(object):
def test_that_depends_on_resource(self, resource):
print("testing {}".format(resource))
运行它会导致
$ py.test --capture=no pytest_yield.py
=== test session starts ===
platform darwin -- Python 2.7.10, pytest-3.0.2, py-1.4.31, pluggy-0.3.1
collected 1 items
pytest_yield.py setup
testing resource
.teardown
=== 1 passed in 0.01 seconds ===
答案 1 :(得分:37)
当你编写“定义为类方法的测试”时,你真的是指类方法(接收类作为第一个参数的方法) )或只是常规方法(接收实例作为第一个参数的方法)?
由于您的示例使用self
作为测试方法,我假设后者,所以您只需要使用setup_method
代替:
class Test:
def setup_method(self, test_method):
# configure self.attribute
def teardown_method(self, test_method):
# tear down self.attribute
def test_buttons(self):
# use self.attribute for test
测试方法实例传递给setup_method
和teardown_method
,但如果您的setup / teardown代码不需要知道测试上下文,则可以忽略它。可以找到更多信息here。
我还建议您熟悉py.test的fixtures,因为它们是一个更强大的概念。
答案 2 :(得分:17)
正如@Bruno建议的那样,使用pytest fixtures是另一种解决方案,可以为两个测试类甚至只是简单的测试函数访问。 Here's an example testing python2.7 functions:
import pytest
@pytest.fixture(scope='function')
def some_resource(request):
stuff_i_setup = ["I setup"]
def some_teardown():
stuff_i_setup[0] += " ... but now I'm torn down..."
print stuff_i_setup[0]
request.addfinalizer(some_teardown)
return stuff_i_setup[0]
def test_1_that_needs_resource(some_resource):
print some_resource + "... and now I'm testing things..."
因此,运行test_1...
会产生:
I setup... and now I'm testing things...
I setup ... but now I'm torn down...
请注意,夹具中引用了stuff_i_setup
,允许该对象为setup
和torn down
进行与之交互的测试。您可以想象这对于持久对象(例如假设数据库或某些连接)非常有用,必须在每次测试运行之前将其清除以保持隔离。
答案 3 :(得分:14)
这可能会有助http://docs.pytest.org/en/latest/xunit_setup.html
在我的测试套件中,我将测试用例分组到类中。对于我需要该类中所有测试用例的设置和拆解,我使用setup_class(cls)
和teardown_class(cls)
类方法。
对于每个测试用例我需要的设置和拆解,我使用setup_method(method)
和teardown_method(methods)
示例:
lh = <got log handler from logger module>
class TestClass:
@classmethod
def setup_class(cls):
lh.info("starting class: {} execution".format(cls.__name__))
@classmethod
def teardown_class(cls):
lh.info("starting class: {} execution".format(cls.__name__))
def setup_method(self, method):
lh.info("starting execution of tc: {}".format(method.__name__))
def teardown_method(self, method):
lh.info("starting execution of tc: {}".format(method.__name__))
def test_tc1(self):
<tc_content>
assert
def test_tc2(self):
<tc_content>
assert
现在,当我运行我的测试时,当TestClass执行开始时,它会记录开始执行时的详细信息,结束执行时的详细信息以及方法的相同内容。
您可以在相应位置添加其他设置和拆卸步骤。
希望它有所帮助!
答案 4 :(得分:10)
如果添加@classmethod
装饰器,您的代码应该按预期工作。
@classmethod
def setup_class(cls):
"Runs once per class"
@classmethod
def teardown_class(cls):
"Runs at end of class"
请参阅http://pythontesting.net/framework/pytest/pytest-xunit-style-fixtures/
答案 5 :(得分:1)
import pytest
class Test:
@pytest.fixture()
def setUp(self):
print("setup")
yield "resource"
print("teardown")
def test_that_depends_on_resource(self, setUp):
print("testing {}".format(setUp))
要运行:
pytest nam_of_the_module.py -v