python+selenium+unittest自动化测试框架

2023-11-11

前言

关于自动化测试的介绍,网上已有很多资料,这里不再赘述,UI自动化测试是自动化测试的一种,也是测试金字塔最上面的一层,selenium是应用于web的自动化测试工具,支持多平台、多浏览器、多语言来实现自动化,优点如下:

①开源、免费且对web界面有良好的支持;;

②多浏览器支持:chrome、Firefox、IE、Edge等;

③多平台支持:Linux、Windows、MAC;

④多语言支持:java、python、Ruby、C#、JavaScript、C++;

⑤简单(API简单)、灵活(开发语言驱动),支持分布式测试用例执行; 

selenium官方中文文档:http://selenium-python-zh.readthedocs.io/en/latest/index.html 

环境准备

  • 浏览器(Chrome)
  • Python
  • Selenium
  • chromedriver(请下载于Chrome对应版本的驱动)
  • IDE(Pycharm)

1、python、pycharm安装 
Python官网下载链接:https://www.python.org/downloads/windows/ 
pycharm官网下载链接:https://www.jetbrains.com/pycharm/download/#section=windows 

2、selenium安装 

pip install selenium 

关于selenium元素定位是开展web自动化测试的基础和关键,总共有八种定位方式,包括id,class,xpath等,可以参考网上资料学习,这里不再赘述。

3、chromedriver驱动安装

驱动下载:http://chromedriver.storage.googleapis.com/index.html

然后把chromedriver.exe拷贝到到chrome的安装目录下…\Google\Chrome\Application\ ,同时把chrome的安装目录加入到path环境变量。

4、快速验证测试

自动化测试框架

  • config目录中存放的是测试配置相关的文件,文件类型ini,包括测试的网址、浏览器驱动等信息
  • framework目录中存放的是页面基础类base_page: 封装一些常用的页面操作方法;日志类 Logger: 封装日志输出及控制台输出方法
  • logs用来存放输出的日志文件
  • pageobjects目录存放的是页面对象,一个页面封装为一个类,一个元素封装为一个方法
  • screenshots目录存放的是测试过程中的相关截图
  • test_report用来存放输出的测试报告
  • testsuites目录存放测试用例,包括test_base和单个测试用例

1、config.ini配置信息如下:

2、framework目录下base_page的封装:

import time
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.select import Select
import os.path
from framework.logger import Logger

# 创建一个日志实例
logger = Logger(logger="BasePage").getlog()

class BasePage(object):
    """
    定义一个页面基类,让所有页面都继承这个类,封装一些常用的页面操作方法
    """
    def __init__(self, driver):
        self.driver = driver

        #get an url link
    def open(self,url):
        self.driver.get(url)

        #quit browser and end testing
    def quit_browser(self):
        self.driver.quit()

        # 浏览器前进操作
    def forward(self):
        self.driver.forward()
        logger.info("Click forward on current page.")

        # 浏览器后退操作
    def back(self):
        self.driver.back()
        logger.info("Click back on current page.")

        # 显示等待
    def wait(self,loc,seconds):
        try:
            wait_=WebDriverWait(self.driver,seconds)
            wait_.until(lambda driver:driver.find_element(*loc))
            logger.info("wait for %d seconds." % seconds)
        except NameError as e:
            logger.error("Failed to load the element with %s" % e)

        # 保存图片
    def get_windows_img(self):
        """
        把file_path保存到我们项目根目录的一个文件夹.\Screenshots下
        """
        file_path = os.path.dirname(os.path.abspath('.')) + 'Selenium/screenshots/'
        rq = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
        screen_name = file_path + rq + '.png'
        try:
            self.driver.get_screenshot_as_file(screen_name)
            logger.info("Had take screenshot and save to folder : /screenshots")
        except NameError as e:
            logger.error("Failed to take screenshot! %s" % e)
            self.get_windows_img()

         # 定位元素方法
    def find_element(self,loc):
        """
        :return: element
        """
        return self.driver.find_element(*loc)

        # 输入
    def send_keys(self, selector, text):

        el = self.find_element(selector)
        el.clear()
        try:
            el.send_keys(text)
            logger.info("Had type \' %s \' in inputBox" % text)
        except NameError as e:
            logger.error("Failed to select in input box with %s" % e)
            self.get_windows_img()

        # 清除文本框
    def clear(self, selector):

        el = self.find_element(selector)
        try:
            el.clear()
            logger.info("Clear text in input box before typing.")
        except NameError as e:
            logger.error("Failed to clear in input box with %s" % e)
            self.get_windows_img()

        # 点击元素
    def click(self, selector):

        el = self.find_element(selector)
        try:
            el.click()
            logger.info("The element \'%s\' was clicked." % el.text)
        except NameError as e:
            logger.error("Failed to click the element with %s" % e)


        #鼠标事件(左键点击)
    def move_element(self,loc,sloc):
        mouse=self.find_element(loc)
        try:
            ActionChains(self.driver).move_to_element(mouse).perform()
            self.click(sloc)
            pass
        except Exception as e:
            logger.error("Failed to click move_element with %s" % e)
            self.get_windows_img()

        # 强制等待
    @staticmethod
    def sleep(seconds):
        time.sleep(seconds)
        logger.info("Sleep for %d seconds" % seconds)

logger日志输入方法:

import logging
import os.path
import time

class Logger(object):
    def __init__(self, logger):
        '''''
            指定保存日志的文件路径,日志级别,以及调用文件
            将日志存入到指定的文件中
        '''
        # 创建一个logger
        self.logger = logging.getLogger(logger)
        self.logger.setLevel(logging.DEBUG)

        # 创建一个handler,用于写入日志文件
        rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
        log_path = os.path.dirname(os.path.abspath('.')) + 'Selenium/logs/'
        log_name = log_path + rq + '.log'
        fh = logging.FileHandler(log_name)
        fh.setLevel(logging.INFO)

        # 再创建一个handler,用于输出到控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)

        # 定义handler的输出格式
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        fh.setFormatter(formatter)
        ch.setFormatter(formatter)

        # 给logger添加handler
        self.logger.addHandler(fh)
        self.logger.addHandler(ch)

    def getlog(self):
        return self.logger

3、关于页面对象的写法参考:

页面对象继承于base_page基类

from framework.base_page import BasePage
from selenium.webdriver.common.by import By
from framework.logger import Logger

logger = Logger(logger="cloud_page").getlog()
class Cloud(BasePage):
    #定位器
    input_box = (By.ID,'kw')
    search_submit = (By.XPATH,'//*[@id="su"]')

    def value_input(self, text):
        self.wait(self.input_box,5)
        self.send_keys(self.input_box, text)

    def submit_btn(self):
        self.click(self.search_submit)
        logger.info("show results!")
        self.sleep(2)

4、testsuite部分,每个用例都要执行的用例前的准备setup和清理teardown写在test_base文件里,单个测试用例文件继承于它

from selenium import webdriver
import unittest

class TestBase(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()   #驱动浏览器
        self.driver.implicitly_wait(10)  #设置隐式等待
        self.driver.maximize_window()    #最大化浏览器

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

if __name__=='__main__':
    unittest.main()

测试用例参考,注意测试用例方法命名一定要以test开头

import time
from testsuites.test_base import TestBase
from pageobjects.baidu_page import Cloud

class BaiduSearch(TestBase):

    def test_baidu_search(self):
        """
        这里一定要test开头,把测试逻辑代码封装到一个test开头的方法里。
        :return:
        """
        input = Cloud(self.driver)
        input.open('https://www.baidu.com/')
        input.value_input('selenium')  # 调用页面对象中的方法
        input.submit_btn()  # 调用页面对象类中的点击搜索按钮方法
        time.sleep(2)
        input.get_windows_img()  # 调用基类截图方法
        try:
            assert 'selenium' in 'selenium'
            print('Test Pass.')
        except Exception as e:
            print('Test Fail.', format(e))

5、最后就是核心代码,testrunner.py 用来批量执行测试用例,引用HTMLTestRunner模块生成测试报告。

import unittest
from HTMLTestRunner import HTMLTestRunner
import time
import os

# 定义输出的文件位置和名字
DIR = os.path.dirname(os.path.abspath(__file__))
now = time.strftime("%Y%m%d%H%M", time.localtime(time.time()))

filename =now+"report.html"
#discover方法执行测试套件
testsuite = unittest.defaultTestLoader.discover(
   start_dir='./testsuites',
   pattern='*case.py',
   top_level_dir=None
   )

with open(DIR+'/test_report/'+filename,'wb') as f:
    runner = HTMLTestRunner(
       stream=f,
       verbosity=2, 
       title='gateway UI report',
       description='执行情况',
       tester='tester'
   )
    runner.run(testsuite)

6、测试报告展示

总结

基于selenium实现的web自动化框架不仅轻量级而且灵活,可以快速的开发自动化测试用例。本篇中的框架设计比较简单,希望对大家以后的web自动化框架的设计和实现有所帮助,共同交流,共同进步!

今天要比昨天有进步!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python+selenium+unittest自动化测试框架 的相关文章

随机推荐

  • 2023年第二届全国大学生数据统计与分析竞赛——电影评分的大数据分析

    问题一 请分析附件 1 中最受欢迎的电影类型是什么 排名前 250 名电影中 出现次数最多的导演前 10 名是谁 出现次数最多的国家前 5 名是哪些国家 最受欢迎的电影类型 lst for i in df1 电影类型 apply lambd
  • 程序员面试题精选100题(01)-把二元查找树转变成排序的双向链表

    程序员面试题精选100题 01 把二元查找树转变成排序的双向链表 参见博客 http zhedahht blog 163 com blog static 254111742007127104759245 http www cnblogs c
  • Java中notify和notifyAll的区别以及应用场景

    Differences between notify and notifyAll Notification to number of threads We can use notify method to give the notifica
  • 10、Java 8 - 接口 ( interface ) 默认方法

    总所周知 在 Java 7 和之前的版本中 接口 interface 是不能包含具体的方法实现的 比如 下面的代码 是会报错的 public class InterfaceDefaultMethodTester public static
  • Java 读取freemarker模板(html)转换成String

    2019独角兽企业重金招聘Python工程师标准 gt gt gt Java代码 package com main util import freemarker template Template import org slf4j Logg
  • springboot日期时间格式全局处理

    import com fasterxml jackson datatype jsr310 deser LocalDateTimeDeserializer import com fasterxml jackson datatype jsr31
  • Mysql进阶优化篇01——四万字详解数据库性能分析工具(深入、全面、详细,收藏备用)

    前 言 作者简介 半旧518 长跑型选手 立志坚持写10年博客 专注于java后端 专栏简介 mysql进阶 主要讲解mysql数据库进阶知识 包括索引 数据库调优 分库分表等 文章简介 本文将介绍数据库优化的步骤 思路 性能分析工具 比如
  • js 中的隐士转换 + ==规则

    ToString 1 数组中的null或undefined 会被当做空字符串处理 2 普通对象 转为字符串相当于直接使用Object prototype toString 返回 object Object ToNumber 1 null 转
  • Linux学习之基础工具一

    1 Linux 软件包管理器 yum 首先我们需要知道的是在Linux下 现存的软件和指令是一定的 而有的时候我们想需要更多的指令或者软件 而这在Linux本身下是没有的 故我们可以利用指令yum指令安装或卸载你想要或者不需要的软件 ubu
  • k8s学习pod第七天

    init Container 初始化容器是一类只运行一次的容器 本质是也是容器 不同容器间启动有先后顺序 只有前面的容器运行成功了 后面的容器才能运行 初始化容器的场景 在其他容器运行之前做个初始化 比如配置文件生成 环境变量生成 有先后顺
  • OpenCV——分水岭算法

    目录 一 分水岭算法 1 概述 2 图像分割概念 3 分水岭算法原理 二 主要函数 三 C 代码 四 结果展示 1 原始图像 2 分割结果 五 参考链接 一 分水岭算法 1 概述 分水岭算法是一种图像分割常用的算法 可以有效地将图像中的目标
  • Javascript高级程序设计——15-1.匿名函数和闭包

    1 匿名函数 表示没有定义函数名的函数 案例1 1 简单的匿名函数 function 单独的匿名函数无法执行 alert Lee 案例1 2 将匿名函数赋值给一个变量 var box function return Lee alert bo
  • 复数矩阵计算行列式

    项目上需要对复矩阵的行列式计算 根据计算一般矩阵行列式的代码改成了复矩阵行列式计算 include
  • 性能测试中TPS上不去的几种原因

    中TPS一直上不去 是什么原因 这篇文章 就具体说说在实际压力测试中 为什么有时候TPS上不去的原因 先来解释下什么叫TPS TPS Transaction Per Second 每秒事务数 指服务器在单位时间内 秒 可以处理的事务数量 一
  • Python库的使用说明

    目录 1 第三方库索引网站 2 第三方安装 2 1 pip工具介绍 2 2 pip工具安装 2 2 1 list 命令查看已安装的库列表 2 2 2 uninstall 命令 2 2 3 show 命令 2 2 4 download 命令
  • C++标准模板库 迭代器 iterator 详解(二)

    迭代器提供对一个容器中的对象的访问方法 并且定义了容器中对象的范围 迭代器就如同一个指针 事实上 C 的指针也是一种迭代器 但是 迭代器不仅仅是指针 因此你不能认为他们一定具有地址值 例如 一个数组索引 也可以认为是一种迭代器 迭代器有各种
  • [NOI2009]植物大战僵尸【拓扑+最大权闭合子图】

    题目链接 BZOJ 1565 看到这道题之后很容易想到的就是最大权闭合子图了 但是却有个问题就是要去除掉那些环 因为构成了环之后 相当于是无敌的状态 它们就永远不会得到贡献 并且环之后的点也是得不到贡献的 所以 这里利用拓扑 知道哪些点是可
  • 「Qt」事件概念

    0 引言 在本文所属专栏的前面的文章里 我们介绍了Qt的 信号 Signal 与 槽 Slot 机制 信号 Signal 与 槽 Slot 机制是 Qt 框架用于多个对象之间通信的 是 Qt 的核心特性 也是 Qt 与其他框架最大的不同之处
  • anaconda中spyder改变背景颜色(黑色)

    spyder挺好用的 但是未定义的背景颜色实在不好看 纯属个人审美 下面开始更换背景图 打开spyder 依此点击 Tools 再点击preference 喜爱 选择Syntax coloring Scheme调成Monokai 这是我喜欢
  • python+selenium+unittest自动化测试框架

    前言 关于自动化测试的介绍 网上已有很多资料 这里不再赘述 UI自动化测试是自动化测试的一种 也是测试金字塔最上面的一层 selenium是应用于web的自动化测试工具 支持多平台 多浏览器 多语言来实现自动化 优点如下 开源 免费且对we