我使用硒端到端测试,我不知道如何使用setup_class和teardown_class方法。

我需要在setup_class方法中设置浏览器,然后执行一堆定义为类方法的测试,最后在teardown_class方法中退出浏览器。

但从逻辑上讲,这似乎是一个糟糕的解决方案,因为实际上我的测试不会对类有效,而是对对象有效。我在每个测试方法中传递self param,所以我可以访问对象的vars:

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?


当前回答

这可能会有帮助http://docs.pytest.org/en/latest/xunit_setup.html

在我的测试套件中,我将测试用例分组为类。对于该类中所有测试用例所需的设置和拆卸,我使用setup_class(cls)和teardown_class(cls)类方法。

对于每个测试用例所需的设置和拆除,我使用setup_method(方法)和teardown_method(方法)

例子:

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执行开始时,它会记录详细信息,当它开始执行时,当它结束执行时,方法也是如此。

您可以在相应的位置添加其他安装和拆卸步骤。

希望能有所帮助!

其他回答

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 

这可能会有帮助http://docs.pytest.org/en/latest/xunit_setup.html

在我的测试套件中,我将测试用例分组为类。对于该类中所有测试用例所需的设置和拆卸,我使用setup_class(cls)和teardown_class(cls)类方法。

对于每个测试用例所需的设置和拆除,我使用setup_method(方法)和teardown_method(方法)

例子:

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执行开始时,它会记录详细信息,当它开始执行时,当它结束执行时,方法也是如此。

您可以在相应的位置添加其他安装和拆卸步骤。

希望能有所帮助!

如果您添加了@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/

根据Fixture终结/执行拆卸代码,当前安装和拆卸的最佳实践是使用yield而不是return:

import pytest

@pytest.fixture()
def resource():
    print("setup")
    yield "resource"
    print("teardown")

class TestResource:
    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 ===

编写拆卸代码的另一种方法是在fixture函数中接受请求上下文对象并调用其请求。Addfinalizer方法,带有执行一次或多次拆卸的函数:

import pytest

@pytest.fixture()
def resource(request):
    print("setup")

    def teardown():
        print("teardown")
    request.addfinalizer(teardown)
    
    return "resource"

class TestResource:
    def test_that_depends_on_resource(self, resource):
        print("testing {}".format(resource))

正如@Bruno所建议的,使用pytest fixture是另一种解决方案,它可以用于两个测试类,甚至只是简单的测试函数。下面是一个测试python2.7函数的例子:

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在fixture中被引用,允许为与之交互的测试设置和拆除该对象。您可以想象,这对于持久对象(例如假设的数据库或某些连接)非常有用,这些对象必须在每次测试运行之前清除,以保持它们之间的隔离。