selenium pytest allure 自动化测试

Selenium + Pytest + Allure 自动化测试框架实战

在阅读本文时,大家首先要掌握 python 、pytest 、selenium基础相关

项目目录简介


├───common  		# 公共模块
├───config  		# 常用的系统配置
├───data  			# 用于存储数据驱动是的数据
├───logs  			# 日志记录
├───page  			# selenium 封装
├───page_element  	# 页面元素数据配置
├───page_object  	# 需要测试的测试类封装
├───report  		# 生成的报告路径
├───script  		# 其他常用脚本
├───testcase  		# 测试的case
│   ├───interface  	# 接口相关
│   ├───webui  		# web自动化相关
├───utils  			# 常用工具类
├───requriment.txt  # 项目相关依赖
├───pytest.ini  	# pytest 只配置
├───main.py  		# 启动类

logger 相关

主要用于日志生成,以及写入到校验报告中

import logging

from config.conf import cm


class Logger(object):

    def __init__(self):
        self.log_name = cm.log_file
        self.logger = logging.getLogger("log")
        self.logger.setLevel(logging.DEBUG)

        self.formater = logging.Formatter('[%(asctime)s][%(filename)s %(lineno)d][%(levelname)s]: %(message)s')

        self.filelogger = logging.FileHandler(self.log_name, mode='a', encoding="UTF-8")
        self.console = logging.StreamHandler()
        self.console.setLevel(logging.INFO)
        self.filelogger.setLevel(logging.DEBUG)
        self.filelogger.setFormatter(self.formater)
        self.console.setFormatter(self.formater)
        self.logger.addHandler(self.filelogger)
        self.logger.addHandler(self.console)


log = Logger().logger

读取页面元素

import os
import yaml
from config.conf import cm


class Element(object):
    """获取元素"""

    def __init__(self, name):
        self.file_name = '%s.yaml' % name
        self.element_path = os.path.join(cm.ELEMENT_PATH, self.file_name)
        if not os.path.exists(self.element_path):
            raise FileNotFoundError("%s 文件不存在!" % self.element_path)
        with open(self.element_path, encoding='utf-8') as f:
            self.data = yaml.safe_load(f)

    def __getitem__(self, item):
        """获取属性"""
        data = self.data.get(item)
        if data:
            name, value = data.split('==')
            return name, value
        raise ArithmeticError("{}中不存在关键字:{}".format(self.file_name, item))


if __name__ == '__main__':
    search = Element('demo')
    print(search['inputelment'])

seleniume 封装

seleniume 本身使用就很简便,那么为什么封装?
首先我们上述这种较为原始的方法,基本不适用于平时做UI自动化测试的,因为在UI界面实际运行情况远远比较复杂,可能因为网络原因,或者控件原因,我们元素还没有显示出来,就进行点击或者输入。所以我们需要封装selenium方法,通过内置的显式等待或一定的条件语句,才能构建一个稳定的方法。而且把selenium方法封装起来,有利于平时的代码维护。


from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

from common.logger import log
from config.conf import cm
from utils.times import sleep


class WebPage(object):
    """selenium基类"""

    def __init__(self, driver):
        # self.driver = webdriver.Chrome()
        self.driver = driver
        self.timeout = 20
        self.wait = WebDriverWait(self.driver, self.timeout)

    def get_url(self, url):
        """打开网址并验证"""
        self.driver.maximize_window()
        self.driver.set_page_load_timeout(60)
        try:
            self.driver.get(url)
            self.driver.implicitly_wait(10)
            log.info("打开网页:%s" % url)
        except TimeoutException:
            raise TimeoutException("打开%s超时请检查网络或网址服务器" % url)

    @staticmethod
    def element_locator(func, locator):
        """元素定位器"""
        name, value = locator
        return func(cm.LOCATE_MODE[name], value)

    def find_element(self, locator):
        """寻找单个元素"""
        return WebPage.element_locator(lambda *args: self.wait.until(
            EC.presence_of_element_located(args)), locator)

    def find_elements(self, locator):
        """查找多个相同的元素"""
        return WebPage.element_locator(lambda *args: self.wait.until(
            EC.presence_of_all_elements_located(args)), locator)

    def elements_num(self, locator):
        """获取相同元素的个数"""
        number = len(self.find_elements(locator))
        log.info("相同元素:{}".format((locator, number)))
        return number

    def input_text(self, locator, txt):
        """输入(输入前先清空)"""
        sleep(0.5)
        ele = self.find_element(locator)
        ele.clear()
        ele.send_keys(txt)
        log.info("输入文本:{}".format(txt))

    def is_click(self, locator):
        """点击"""
        self.find_element(locator).click()
        sleep()
        log.info("点击元素:{}".format(locator))

    def element_text(self, locator):
        """获取当前的text"""
        _text = self.find_element(locator).text
        log.info("获取文本:{}".format(_text))
        return _text

    @property
    def get_source(self):
        """获取页面源代码"""
        return self.driver.page_source

    def refresh(self):
        """刷新页面F5"""
        self.driver.refresh()
        self.driver.implicitly_wait(30)

基于POM模式去test

关于什么 POM 模式 大家可以参考 https://www.cnblogs.com/lym51/p/6646033.html

POM是 Page Object Model 的简写,其实简单的说,就是面向对象的封装,让代码解耦,方便维护与扩展!

这里我们以测试百度的首页搜索为案例:

搜索页面

from common.readelement import Element
from page.webpage import WebPage

search = Element('demo/demo')


class SearchPage(WebPage):
    """搜索类"""

    def input_search(self, content):
        """输入搜索"""
        self.input_text(search['inputelment'], txt=content)

    def click_search(self):
        """点击搜索"""
        self.is_click(search['click_search'])

SearchPage 继承了 WebPage 具有了错做浏览器的全部方法,Element 为我们提供了搜索所需的页面元素

测试页面功能

本测试案例围绕在百度搜素里进行搜索 selenium

  • 页面搜索结果是否包含输入的内容
  • 如果搜索结果是否包含指定对比的内容,如果包含,进行截图显示
import re

import allure
import pytest

from common.logger import log
from page_object.demo.baidu_test import SearchPage
from utils.load_yaml import read_config_file

url = read_config_file("base", "url")


@allure.feature("测试项目")
class TestSearch:

    @pytest.fixture(scope='function', autouse=True)
    def open_baidu(self, drivers):
        """打开百度"""
        search = SearchPage(drivers)
        with allure.step("step1:打开登录首页"):
            search.get_url(url)

    @allure.title("第一个测试用例")
    def test_001(self, drivers):
        """搜索"""
        search = SearchPage(drivers)
        with allure.step("step2:输入搜索内容"):
            search.input_search("selenium")
        with allure.step("step3:确认搜素"):
            search.click_search()
        with allure.step("step4:获取反回值"):
            result = re.search(r'selenium', search.get_source)
        log.info("页面返回值 %s" % result)
        assert result

    @allure.title("测试失败后截图的操作")
    def test_002(self, drivers):
        """搜索"""
        search = SearchPage(drivers)
        with allure.step("step2:输入搜索内容"):
            search.input_search("selenium")
        with allure.step("step3:确认搜素"):
            search.click_search()
        with allure.step("step4:获取反回值"):
            result = re.search(r'Java有货交流群,联系小编', search.get_source)
        log.info("页面返回值 %s" % result)
        assert result

校验报告

本文采用了allure校验报告,这里就不多做介绍了,我们打开上一步结果生成的校验报告!!!
在这里插入图片描述
当我们打开错误的校验报告进行查看,这里包含里错误的日志,错误是的页面截图!!!
在这里插入图片描述

总结与源码

总体来说,这样的测试还是比较丝滑的,但是由于代码比较多,文中之阐述了一部分,大家如感兴趣,可以阅读源码!
源码地址 https://github.com/yanghaiji/qualification-test-plan 如果对您有所帮助记得star

到这里本次分享即将结束!!! 感谢您的阅读!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小杨同学~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值