Pytest中使用Fixture替换Unittest的Setupclass及Pytest使用装饰器应用参数化

1 类里使用Fixture

Pytest中夹具(Fixture)有几种生命周期:function->model->class->session->packages,其中默认为function。

python 复制代码
import pytest
from Common.logger import Log
from Common.Operator import *
from Common.Logins import Logins
from Page.Credentials.CredentialsPage import CredentialsPage as cp
from selenium.webdriver.common.by import By
import allure

log = Log("TestJohnDeere")


class TestJohnDeere:
    driver = None
    lg = None
    page = None

    coll = (By.XPATH, '//*[@id="nav_arrow"]/div')

    @pytest.fixture()  # 使用默认值
    def begin(self):
        log.info('--------开始测试John Deere Credentials功能--------')
        self.driver = browser("chrome")
        self.lg = Logins()
        self.lg.login(self.driver, 'atcred@iicon004.com', 'Win.12345')
        self.driver.implicitly_wait(10)

        self.page = cp()
        ac = self.lg.get_attribute(self.coll, 'class')
        while True:
            if ac != 'icn collapse':
                ar = (By.ID, 'nav_arrow')
                self.page.click(ar)
                continue
            else:
                break
        self.lg.click(self.page.johndeere_menu)
        time.sleep(1)
        self.lg.switch_to_iframe(self.page.right_iframe)

        yield self.lg
        self.driver.quit()

    def add_jdlink(self, begin):
        log.info('点击 JD Link 的Add')
        if not begin.is_clickable(self.page.jdlink_add_btn):
            time.sleep(2)
        try:
            begin.click(self.page.jdlink_add_btn)
            time.sleep(1)
            self.driver.switch_to.window(self.driver.window_handles[1])
            time.sleep(2)
            txt = begin.get_text(self.page.jdlink_page_signin_lable)
        except Exception:
            log.info('Add 跳转失败!')
            return False
        else:
            log.info('Add 跳转成功!')
            self.driver.switch_to.window(self.driver.window_handles[0])
            if txt == 'Sign In':
                return True
            else:
                return False

    @allure.feature("测试Credentials功能")
    @allure.story("测试JD Link Credentials设置功能")
    def test_addJDlink(self, begin):
        """测试Add JD Link功能"""
        res = self.add_jdlink(begin)
        if res:
            log.info('Add JD Link 测试成功!')
        else:
            log.info('Add JD Link 测试失败!')
        assert res


if __name__ == '__main__':
    pytest.main(['-vs', 'TestJohnDeere.py'])  # 主函数模式

2 指定Fixture范围

在类外写Fixture,通过@pytest.para.usefixtures("fixture name")来调用。

python 复制代码
import pytest
from Common.logger import Log
from Common.Operator import *
from Common.Logins import Logins
from selenium.webdriver.common.by import By
import allure

log = Log("test_logins")

# 定义fixture
@pytest.fixture(scope='class')
def starts():
    driver = browser("chrome")
    lg = Logins()
    lg.login(driver)
    driver.implicitly_wait(10)

    yield lg
    driver.quit()


# 使用fixtures
@pytest.mark.usefixtures('starts')
class TestLogins(Operator):

    home_log = (By.ID, 'button_home')
    btnuser = (By.ID, 'btnuser')
    loc = (By.ID, 'spanusername')

    # 修改密码元素
    changePwBtn_loc = (By.XPATH, '//*[@id="usermenu_panel"]/ul/li[2]/table/tbody/tr/td[2]/span')
    oldpw_loc = (By.ID, 'txt_old_pass')
    newpw_loc = (By.ID, 'txt_new_pass')
    confirmpw_loc = (By.ID, 'txt_new_pass2')
    changeOk_loc = (By.ID, 'button_submit')

    # 退出登录相关元素
    logout_loc = (By.XPATH, '//*[@id="usermenu_panel"]/ul/li[3]/table/tbody/tr/td[2]/span')
    loginB_loc = (By.ID, 'btn_login')

    @allure.feature("用户登录相关测试")
    @allure.story("测试登录功能")
    def test_login(self, starts):
        starts.click(self.home_log)
        time.sleep(2)
        starts.click(self.btnuser)
        time.sleep(1)

        displayname = starts.find_element(self.loc).text
        starts.click(self.btnuser)
        assert displayname == 'Auto Test'

    def change_password(self, starts):
        starts.driver.refresh()
        time.sleep(2)

        starts.click(self.btnuser)
        try:
            starts.click(self.changePwBtn_loc)
            time.sleep(1)
        except Exception:
            log.info('open change password failed!')
            return False
        else:
            starts.send_keys(self.oldpw_loc, 'Win.12345')
            starts.send_keys(self.newpw_loc, 'Win.12345')
            starts.send_keys(self.confirmpw_loc, 'Win.12345')
            time.sleep(1)

            try:
                starts.click(self.changeOk_loc)
                time.sleep(2)
                starts.driver.switch_to.alert.accept()
                time.sleep(1)
            except Exception:
                return False
            else:
                return True

    @allure.feature("用户登录相关测试")
    @allure.story("测试修改密码")
    def test_change_password(self, starts):
        assert self.change_password(starts)

    @allure.feature("用户登录相关测试")
    @allure.story("测试退出功能")
    def test_logout(self, starts):
        starts.driver.refresh()
        time.sleep(3)

        starts.click(self.btnuser)
        time.sleep(1)
        starts.click(self.logout_loc)

        # 判断是否正确退出
        res = starts.is_text_in_value(self.loginB_loc, 'LOGIN')
        assert res


if __name__ == '__main__':
    pytest.main(['-v', 'Testlogins.py'])

3 fixture和参数化同时使用

fixture中不使用参数,测试用例使用参数化。

python 复制代码
__author__ = 'ljzeng'

import pytest
from Common.logger import Log
from Common.Operator import *
from Common.Logins import Logins
import allure
from Common.excel import *
from Common.queryMSSQL import updateSQL
from Page.ManageAssets.ManageDevicesPage import ManageDevicesPage

log = Log("TestManageDevices")
file_path = "TestData\\managedevice.xlsx"
testData = get_list(file_path)


# 初始化数据库数据
def clearTestData():
    log.info('从数据库删除测试数据')
    dta = 'ironintel_admin'
    dtm = 'IICON_001_FLVMST'
    sqlstr = "delete from GPSDEVICES where CONTRACTORID='IICON_001' and Notes like '%AutoTest%'"
    sqls = "delete from COMMENTS where COMMENTS like '%AutoTest%'"
    updateSQL(dta, sqlstr)
    updateSQL(dtm, sqls)


@pytest.fixture(scope='class')
def begin():
    driver = browser("chrome")
    lg = Logins()
    lg.login(driver, 'atdevice@iicon001.com', 'Win.12345')
    driver.implicitly_wait(10)
    clearTestData()

    lg.device = ManageDevicesPage()
    try:
        lg.switch_to_iframe(lg.device.iframe_loc)
        time.sleep(1)
    except Exception:
        log.info('------Open Manage Devices failed!')
    else:
        log.info('------Open Manage Devices completed!')

    yield lg
    clearTestData()
    driver.quit()


@pytest.mark.usefixtures("begin")
class TestManageDevices:
    def saveDevices(self, begin, data):
        current_time1 = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
        current_date1 = time.strftime('%m/%d/%Y')
        time.sleep(1)
        try:
            while not begin.is_clickable(begin.device.addBtn_loc):
                log.info('添加按钮不可点击,等待3秒再看')
                time.sleep(3)
            begin.click(begin.device.addBtn_loc)
            time.sleep(1)
            begin.switch_to_iframe(begin.device.addDeviceIframe_loc)
            time.sleep(1)
        except Exception:
            log.info('--------打开添加设备页面失败!--------')
        else:
            log.info('----测试:  %s' % data['casename'])
            time.sleep(3)
            begin.select_by_text(begin.device.selectSource_loc, data['source'])
            time.sleep(2)
            if data['source'] == 'Foresight ATU':
                begin.select_by_text(begin.device.seldeviceType_loc, data['type'])
            else:
                begin.send_keys(begin.device.deviceType_loc, data['type'])

            begin.send_keys(begin.device.deviceId_loc, data['sn'])
            time.sleep(2)

            begin.send_keys(begin.device.invoiceDate_loc, current_date1)
            begin.send_keys(begin.device.invoiceNo_loc, current_time1)
            begin.send_keys(begin.device.startDate_loc, current_date1)
            begin.send_keys(begin.device.notes_loc, 'AutoTestNotes' + current_time1)
            try:
                begin.click(begin.device.saveBtn_loc)
                time.sleep(1)
                mess = begin.get_text(begin.device.savemessage_loc)
                time.sleep(1)
                begin.click(begin.device.saveDialogOkBtn_loc)
                time.sleep(1)
                res = (mess == data['mess'])
            except Exception:
                log.info('-----保存设备添加失败!-----')
                res = False
            else:
                begin.click(begin.device.exitWithoutSavingBtn_loc)
                time.sleep(3)
                begin.driver.switch_to.default_content()
                begin.switch_to_iframe(begin.device.iframe_loc)
                time.sleep(3)
            return res

    @allure.feature('测试设备管理相关功能')
    @allure.story('测试新建设备')
    @pytest.mark.parametrize('data', testData)
    def test_add_devices(self, begin, data):
        """测试添加设备"""
        res = self.saveDevices(begin, data)
        assert res


if __name__ == '__main__':
    pytest.main(['-vs', 'TestManageDevices.py']) 
相关推荐
qq_433716951 天前
Selenium+Pytest自动化测试框架 ------ 禅道实战
自动化测试·软件测试·selenium·单元测试·pytest·接口测试·压力测试
blues_C2 天前
Pytest-Bdd-Playwright 系列教程(11):场景快捷方式
自动化测试·pytest·bdd·playwright
幸运的星竹2 天前
pytest结合allure做接口自动化
自动化·pytest
blues_C3 天前
Pytest-Bdd-Playwright 系列教程(12):步骤参数 & parsers参数解析
自动化测试·pytest·bdd·playwright
胜天半月子5 天前
pytest | 框架的简单使用
运维·pytest
blues_C5 天前
Pytest-Bdd-Playwright 系列教程(10):配置功能文件路径 & 优化场景定义
自动化测试·软件测试·pytest·bdd·playwright
bigbig猩猩6 天前
pytest中的断言:深入解析与实践
pytest
CSXB996 天前
三十八、Python(pytest框架-上)
python·功能测试·测试工具·单元测试·pytest
漫漫人生路^_^7 天前
unittest和pytest
pytest
_可乐无糖7 天前
使用--log-file保存pytest的运行日志
pytest