python-selenium-pytest-allure UI自动化测试

一、下载及安装插件

python

selenium

pytest

allure

辅助:pyautoit  pymysql  

二、代码框架

1、基础文件

[main.py]

if __name__ == '__main__':
    pytest.main(["--alluredir", "./alluretmp"])
    # pytest.main()
    os.system("allure generate ./alluretmp -o ./allure-report --clean")

[pytest.ini]

[pytest]

addopts = -vs -rerun=2
;addopts = -vs
testpaths = ./testcase
python_files = test*.py
python_classes =Test*
python_functions = test_*
markers = smoke
    story: sdv
    sit: sit
    uat: uat

[conftest.py]

import time

import allure
import pytest
import os
from selenium import webdriver
from common.path import Path
from common.getFileDatas import GetFileDatas
from page.login.loginpage import LoginPage

driver = None


@pytest.fixture(scope='session', autouse=True)
def clean_tmp_allure():
    tmp_allure_path = Path().get_project_path() + r'\alluretmp'
    tmpallure_files = os.listdir(tmp_allure_path)
    for fl in tmpallure_files:
        fl_path = tmp_allure_path + "\\" + fl
        if fl.endswith(".json") or fl.endswith(".txt"):
            os.remove(fl_path)


@pytest.fixture(scope='class')
def start_login():
    global driver
    # if driver is None:
    #     driver = webdriver.Chrome()
    driver = webdriver.Chrome()
    index_url = GetFileDatas().get_ini_data_bypath_section(Path().get_project_path() + r'\config\env.ini', 'test_env')[
        'testurl']
    login_url = '/user/login'
    LoginPage(driver).login(index_url + login_url,
                            GetFileDatas().get_ini_data_bypath_section(Path().get_project_path() + r'\config\env.ini',
                                                                       'user_info')[
                                'username'],
                            GetFileDatas().get_ini_data_bypath_section(Path().get_project_path() + r'\config\env.ini',
                                                                       'user_info')[
                                'pwd'])
    yield driver
    driver.quit()


#  调试无头模式,还未ok
# @pytest.fixture(scope='class')
# def start_driver():
#     """是否启用headless"""
#     chrome_option = Options()
#     if GetFileDatas().get_ini_data_bypath_section(Path().get_project_path() + r'\config\env.ini', 'selenium')[
#         'headless']:
#         chrome_option.add_argument('--headless')
#         chrome_option.add_argument('--disable-software-rasterizer')
#     driver = webdriver.ChromeOptions(options=chrome_option)
#     yield driver
#     driver.quit()


""" 控制台用例名称乱码"""
def pytest_collection_modifyitems(items):
    print("收集到的所有测试用例{}".format(items))
    for item in items:
        item.name = item.name.encode("utf-8").decode("unicode_escape")
        item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
    """
    获取每个用例的钩子函数
    :param item:
    :param call:
    :return:
    """
    outcome = yield
    rep = outcome.get_result()
    # 以下为实现异常截图的代码:
    # rep.when可选参数有call、setup、teardown,
    # call表示为用例执行环节、setup、teardown为环境初始化和清理环节
    # 这里只针对用例执行且失败的用例进行异常截图
    if rep.when == "call" and rep.failed:
        mode = "a" if os.path.exists("failures") else "w"
        with open("failures", mode) as f:
            if "tmpdir" in item.fixturenames:
                extra = " (%s) " % item.funcargs["tmpdir"]
            else:
                extra = ""
            f.write(rep.nodeid + extra + "\n")
        item.name = item.name.encode("utf-8").decode("unicode-escape")

        file_name = '{}.png'.format(str(round(time.time() * 1000)))
        path = os.path.join(Path().get_project_path()+r'\alluretmp', file_name)

        driver.save_screenshot(path)

        if hasattr(driver, "get_screenshot_as_png"):
            with allure.step("添加失败截图"):
                # get_screenshot_as_png实现截图并生成二进制数据
                # allure.attach直接将截图二进制数据附加到allure报告中
                allure.attach(driver.get_screenshot_as_png(), "失败截图", allure.attachment_type.PNG)


if __name__ == '__main__':
    pass

[common/basepage.py]

import time
import autoit
from selenium.webdriver import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.support.select import Select


class BasePage:

    def __init__(self, driver):
        self.driver = driver

    def visit(self, url):
        self.driver.get(url)
        self.driver.maximize_window()
        time.sleep(1)

    def locator(self, loc):
        return WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(loc))

    def get_ele_isvisibility(self, loc):
        return self.locator(loc).is_displayed()

    def get_ele_isexist(self, loc):
        try:
            self.locator(loc)
            return True
        except:
            return False

    def input(self, loc, txt):
        self.locator(loc).send_keys(txt)

    """"清空textarea文本域的内容"""

    def clear(self, loc):
        self.locator(loc).clear()

    """通过键盘事件,清空input输入框的内容"""

    def clear_input(self, loc):
        self.locator(loc).send_keys(Keys.CONTROL, 'A')
        self.locator(loc).send_keys(Keys.DELETE)

    """ 针对下拉选择框定位,引用select类"""
    def select_by_value(self,loc,value):
        Select(self.locator(loc)).select_by_value(value)

    @staticmethod
    def execute_script(script1):
        WebDriver().execute_script(script=script1)

    def click(self, loc):
        self.locator(loc).click()

    def wait(self, time_):
        time.sleep(time_)

    def quit(self):
        self.driver.quit()

    def close_return_Home(self):
        self.driver.close()
        home_page = self.driver.window_handles[0]
        self.driver.switch_to.window(home_page)

    def get_ele_attr_value(self, loc, name):
        ele = self.locator(loc)
        return ele.get_attribute(name)

    """ 鼠标悬停事件"""

    def move_to_element(self, loc):
        ActionChains(self.driver).move_to_element(self.locator(loc)).perform()

    """ 获取页面元素的内容"""

    def get_page_ele_txt(self, loc):
        return self.locator(loc).text

    """校验某一个button按钮是否disable"""

    def get_ele_isdisable(self, loc):
        return self.locator(loc).is_enabled()

    """获取表格中某一单元格的值
    """

    def get_table_cell_value(self, loc):
        return self.locator(loc).text

    def click_table_cell_btn(self, loc):
        self.locator(loc).click()

    """ 获取表格中某一单元格的值"""

    def check_table_cell_value(self, loc, row, col):
        cell_loc = (loc[0], loc[1] + "/tr[" + str(row) + "]" + "/td[" + str(col) + "]")
        return self.locator(cell_loc).text

    """判断某元素是否置灰"""

    def check_element_isenable(self, loc):
        return self.locator(loc).is_enabled

    """alert弹框,只有一个确定按钮
    1、点击确定
    2、获取alert弹框的内容"""

    def switch_to_alert_comfirm(self):
        time
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值