如何分离测试和固定装置

时间:2018-12-10 11:58:23

标签: python selenium pytest

我在PyCharm中有一个示例项目-包含一个简单的测试,该测试检查登录到给定的正确Slack工作空间。它具有web_drivers目录,其中包含chromedriverconftest.py具有用于测试的Webdriver设置,tests.py具有实际测试,例如

  

conftest.py

import os
import pytest
from selenium import webdriver

@pytest.fixture(scope='class')
def driver_get(request):
    web_driver = webdriver.Chrome(executable_path=os.path.join("web_drivers","chromedriver.exe"))
    yield web_driver

def fin():
    web_driver.close()

request.addfinalizer(fin)
  

tests.py

import pytest

class TestSlackWorkspace(object):
    @pytest.fixture(autouse=True)
    def setup(self, driver_get):
        self.driver = driver_get
        self.driver.get("https://slack.com/signin")
        self.input_field = self.driver.find_element_by_xpath(
        "//input[@type='text' and @id='domain']")
        self.continue_button = self.driver.find_element_by_xpath(
        "//button[@id='submit_team_domain']")

    def test_correct_workspace(self):
        self.input_field.send_keys("test")
        self.continue_button.click()
        assert self.driver.find_element_by_xpath("//h1[@id='signin_header']"
        ).is_displayed(), "Login page should be displayed"

现在的问题是将测试划分为页面初始化部分-def setup,将实际测试执行部分-def test_correct_workspace划分为不同的类和文件(类似于页面对象模式)

所以conftest.py的基数应该相同,并将test.py除以即。

  

page.py

class SlackWorkspace(object):
    @pytest.fixture(autouse=True)
    def __init__(self, driver_get):
        self.driver = driver_get
        self.driver.get("https://slack.com/signin")
        self.input_field = self.driver.find_element_by_xpath("//input[@type='text' and @id='domain']")
        self.continue_button = self.driver.find_element_by_xpath("//button[@id='submit_team_domain']")
  

test.py

class TestWorkspace(object):
    def test_correct_workspace(self):
        self.input_field.send_keys("test")
        self.continue_button.click()
        login_page = self.driver.find_element_by_xpath("//h1[@id='signin_header']")
        assert login_page.is_displayed(), "Login page should be displayed"

但是可以肯定的是,它不能以这种形式工作:

1)应该以某种方式将driver_get导入页面初始化文件并将其转发到__init__-吗?

2)应该以某种方式将页面初始化与其他文件中的测试实现链接在一起??

不知道如何在单独的文件之间组织所有这些导入

2 个答案:

答案 0 :(得分:1)

在“页面对象”模式中,应避免在测试类中直接引用驱动程序。您可以将page.py作为基类以具有通用方法。可以将设置移到其他页面,例如login.py。此设置方法应返回您要验证的页面。然后,测试方法应使用这些页面对象进行验证。我将登录名保留为conftest.py中的固定装置,然后在测试和其他固定装置中使用它。例如,这是我的概述。您应该在page object pattern上阅读更多内容。

我建议使用pytest-selenium插件,该插件与pytest一起使用硒可以减少很多样板代码

conftest.py

@fixture
def selenium(): 
     # pytest-selenium provides this fixture & you can override it if required.
    return selenium

@fixture
def home(selenium):
    #do login
    return HomePage

login.py

from page import Page #Import base class with common methods.

class LoginPage(Page):

def login(self, driver):
    #do the login steps
    return HomePage   #return Landing Page

test_login.py

def test_login_successful(home):  #Use the home fixture
     assert home.is_displayed("xyz")

答案 1 :(得分:0)

pytest -> How to use fixture return value in test method under a class的帮助下,以下列方式设法找到了解决方案

1)证明conftest中的灯具需要通过pages.py中的登录页面传递已初始化的webdriver,并使用内置的request灯具使用此驱动程序来初始化此页面类。因此正确的conftest.py如下所示:

import pytest
import os
from selenium import webdriver
from pages import SigninPage

@pytest.fixture(scope='class', autouse=True)
def driver_get(request):
    request.cls.webdriver = webdriver.Firefox(executable_path=os.path.join("web_drivers", "geckodriver"))
    request.cls.signin = SigninPage(request.cls.webdriver)
    yield request.cls.webdriver

    def fin():
        request.cls.webdriver.quit()
    request.addfinalizer(fin)

2)'pages.py'包含SigninPage的初始化和接收到的webdriver,用于输入工作区的输入字段和用于继续的按钮,方法enter_workspace实际上是这样做的,并返回LogInPage login_page字段需要检查,因此看起来像这样:

class SigninPage(object):
    def __init__(self, web_driver):
        self.driver = web_driver
        self.driver.get("https://slack.com/signin")

        self.input_field = self.driver.find_element_by_xpath("//input[@type='text' and @id='domain']")
        self.continue_button = self.driver.find_element_by_xpath("//button[@id='submit_team_domain']")

    def enter_workspace(self):
        self.input_field.send_keys("test")
        self.continue_button.click()
        return LogInPage(self.driver)


class LogInPage(object):
    def __init__(self, web_driver):
       self.driver = web_driver
       self.login_page = self.driver.find_element_by_xpath("//h1[@id='signin_header']")

3)最后,test.py由两件事组成-通过从enter_workspace调用方法SigninPage进入工作区,打开LogInPage,然后检查登录是否实际显示:

class TestSlackWorkspace(object):
    def test_workspace(self):
        login = self.signin.enter_workspace()
        assert login.login_page.is_displayed(), "Missing!"

它仍然需要改进,但是问题得以解决。谢谢。