python单元测试框架(继承、unittest参数化、断言、测试报告)

2023-11-13

一、继承

继承能解决什么问题?

unittest每个模块都要用到前提条件以及清理,如果有上百个模块,我们要改域名和浏览器,就会工作量很大特别麻烦,这时我们可以用继承的思想只用改一次

我们可以将前提和清理提出来单独放到一个文件里,具体代码如下

from selenium import webdriver
import unittest

class Init(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        cls.driver=webdriver.Chrome()
        cls.driver.maximize_window()
        cls.driver.get('http://www.baidu.com')
        cls.driver.implicitly_wait(30)

    @classmethod
    def tearDownClass(cls) -> None:
        cls.driver.quit()

然后我们写测试用例的时候可以继承它,具体代码如下

from selenium import webdriver
import unittest

from 单元测试框架.test.init import Init
class BaiduTest(Init):
    def test_baidu_title(self):
        '''百度测试:验证百度首页的title'''
        # assert self.driver.title=='百度一下,你就知道'
        self.assertEqual(self.driver.title,'百度一下,你就知道')

    def test_baidu_url(self):
        '''百度测试:验证百度首页的url'''
        assert self.driver.current_url=='https://www.baidu.com/'

    def test_baidu_video(self):
        '''百度测试:验证点击视频后跳转到视频的页面'''
        nowhandler=self.driver.current_window_handle
        self.driver.find_element_by_link_text('视频').click()
        allhandlers=self.driver.window_handles
        for handler in allhandlers:
            if handler!=nowhandler:
                self.driver.switch_to.window(handler)
                self.assertTrue(self.driver.current_url,'https://haokan.baidu.com/?sfrom=baidu-top')
                self.driver.close()
        self.driver.switch_to.window(nowhandler)

    def test_baidu_map(self):
        '''百度测试:验证点击地图后跳转到地图的页面'''
        nowhandler=self.driver.current_window_handle
        self.driver.find_element_by_link_text('地图').click()
        allhandlers=self.driver.window_handles
        for handler in allhandlers:
            if handler!=nowhandler:
                self.driver.switch_to.window(handler)
                self.assertTrue(self.driver.current_url.startswith('https://map.baidu'))
                self.driver.close()
        self.driver.switch_to.window(nowhandler)

if __name__ == '__main__':
    unittest.main()
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

二、参数化

在unittest测试框架中,参数化使用的库为:parameterized 安装方式为:pip3 install parameterized

参数化:

我们把相同的测试步骤,应用于不同的测试场景,那么我们就可以使用参数化了

可以解决的问题是可以使用少量的测试代码,来覆盖更多的测试场景

例如:我们测一下sina邮箱的登录模块,代码如下:

from selenium import webdriver
import unittest
import time as t
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None: #前提
        self.driver=webdriver.Chrome()
        self.driver.get('https://mail.sina.com.cn/')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None: #清理
        self.driver.quit()
    def test_sina_null(self):
        '''sina邮箱验证:登录账户为空'''
        self.driver.find_element_by_class_name('loginBtn').click()
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,'请输入邮箱名')

    def test_sina_email_format(self):
        '''sina邮箱验证:登录邮箱格式不正确'''
        self.driver.find_element_by_id('freename').send_keys('qwert')
        self.driver.find_element_by_class_name('loginBtn').click()
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,'您输入的邮箱名格式不正确')

    def test_sina_username_error(self):
        '''sina邮箱验证:登录账户不匹配'''
        self.driver.find_element_by_id('freename').send_keys('asdf@sina.com')
        self.driver.find_element_by_id('freepassword').send_keys('asdfg')
        self.driver.find_element_by_class_name('loginBtn').click()
        t.sleep(3)
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,'登录名或密码错误')

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

由于登录模块主要是⽤户名和密码的input表单的验证以及错误信息的验证,我们可以把用户名、密码、错误信息的验证参数化,具体实现的代码如下:

 from selenium import  webdriver
import  unittest
import  time as t
from parameterized import  parameterized,param
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None: #前提
        self.driver=webdriver.Chrome()
        self.driver.get('https://mail.sina.com.cn/')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None: #清理
        self.driver.quit()

    @parameterized.expand([
        param('','','请输入邮箱名'),
        param('wertasd', 'asdf', '您输入的邮箱名格式不正确'),
        param('wertasd@sina.cn', 'asdf', '登录名或密码错误')
    ])
    def test_sina_login(self,username,password,result):
        self.driver.find_element_by_id('freename').send_keys(username)
        t.sleep(3)
        self.driver.find_element_by_id('freepassword').send_keys(password)
        t.sleep(3)
        self.driver.find_element_by_class_name('loginBtn').click()
        t.sleep(3)
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,result)

三、断言

assertEqual

assertEqual()是验证两个值相等,值的是数据类型与内容也是相等的,⻅案例代码:

from selenium import webdriver
import unittest
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None:
        self.driver=webdriver.Chrome()
        self.driver.get('http://www.baidu.com')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None:
        self.driver.quit()

    def test_baidu_title(self):
        '''百度测试:验证百度首页的title'''
        # assert self.driver.title=='百度一下,你就知道'
        self.assertEqual(self.driver.title,'百度一下,你就知道')

assertTrue

返回的是bool类型,也就是对被测试的对象进⾏验证,如果返回的是boolean类型并且是true,那么结果验证通过,那么⽅法assertFlase()验证的是被测试对象返回的内容是false,⻅案例代码:

from selenium import webdriver
import unittest
import time as t
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None: #前提
        self.driver=webdriver.Chrome()
        self.driver.get('https://mail.sina.com.cn/')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None: #清理
        self.driver.quit()

    def test_sina_isLogin(self):
        '''sina邮箱验证,判断自动登录是否勾选'''
        isLogin=self.driver.find_element_by_id('store1')
        self.assertTrue(isLogin.is_selected())

assertIn

assertIn()值的是⼀个值是否包含在另外⼀个值⾥⾯,在这⾥特别的强调⼀下,在assertIn()的⽅法⾥⾯,有两个参数,那么值的包含其实就是第⼆个实际参数包含第⼀个实际参数。与之相反的⽅法是assergNotIn(),⻅案例代码:

import unittest
from selenium import webdriver
class UiTest(unittest.TestCase):
def setUp(self) -> None:
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
def tearDown(self) -> None:
self.driver.quit()
def test_baidu_title_001(self):
self.assertIn('百度',self.driver.title)
def test_baidu_title_002(self):
self.assertIn('百度⼀下,你就知道',self.driver.title)
if __name__ == '__main__':
unittest.main()

四、测试报告

在unittest的框架中,⽣成测试报告需要使⽤到HTMLTestRunner

import unittest
import os
from 单元测试框架.HTMLTestRunner import HTMLTestRunner #从HTMLTestRunner模块调用HTMLTestRunner类

def getTests():
    '''加载所有的测试模块'''
    suite=unittest.TestLoader().discover(
        #找到被执行模块的路径
        start_dir=os.path.dirname(__file__),
        #加载路径下所有以test_开头的测试模块的文件
        pattern='test_*.py' #正则表达式
    )
    return suite

def runSuite():
    unittest.TextTestRunner().run(getTests())

def base_dir():
    return os.path.dirname(os.path.dirname(__file__))#获取当前目录的上级目录

def run():
    fp=open(os.path.join(base_dir(),'report','report.html'),'wb')#拼接report.html的路径 wb 二进制的方式写入
    runner=HTMLTestRunner(
        stream=fp,  #流 执行一个写入一个
        title='UI自动化测试报告',
        description='' 
    )
    runner.run(getTests())

if __name__ == '__main__':
    run()

怎么解决每次生成的测试报告不覆盖之前的测试报告,同时被保留:

解决方法:引入时间库获取时间戳

代码如下:

import time
import unittest
import os
from HTMLTestRunner import HTMLTestRunner

def getTests():
    '''加载所有的测试模块'''
    suite=unittest.TestLoader().discover(
        #找到被执行模块的路径
        start_dir=os.path.dirname(__file__),
        #加载路径下所有以test_开头的测试模块的文件
        pattern='test_*.py' #正则表达式
    )
    return suite

def getNowTime():
    return time.strftime('%y-%m-%d %H-%M-%S',time.localtime(time.time()))

def base_dir():
    return os.path.dirname(os.path.dirname(__file__))

def run():
    fp=open(os.path.join(base_dir(),'report',getNowTime()+'report.html'),'wb')
    runner=HTMLTestRunner(
        stream=fp,
        title='UI自动化测试报告',
        description=''
    )
    runner.run(getTests())

if __name__ == '__main__':
    run()

这样每次执行的都会生成一个测试报告:

最后: 可以在我的VX公众号:【自动化测试老司机】免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

如果对你有帮助的话,点个赞收个藏,给作者一个鼓励。也方便你下次能够快速查找。  

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

python单元测试框架(继承、unittest参数化、断言、测试报告) 的相关文章

随机推荐

  • 硬件设计27之RS232

    串口通讯 串口通讯 Serial Communication 是一种设备间非常常用的串行通讯方式 因为它简单便捷 大部分电子设备都支持该通讯方式 电子工程师在调试设备时也经常使用该通讯方式输出调试信息 在计算机科学里 大部分复杂的问题都可以
  • js实现简单的视频播放

    功能1 播放暂停切换 思路 准备一个播放的图片和一个暂停的图片 利用标杆思想 设置一个flag变量 播放的时候将flag设置为false 暂停的时候设置为true 如果flag为true则播放同时改变为播放图片 为false则暂停同时改变为
  • 游游的排列构造

    示例1 输入 5 2 输出 3 1 5 2 4 示例2 输入 5 3 输出 2 1 4 3 5 include
  • C语言一行一行读取文件

    C语言中 使用fgets函数可以一行行读du取文件 1 fgets函数 原型 char fgets char buf int bufsize FILE stream 功能 从文件结构体指针stream中读取数据 每次读取一行 说明 读取的数
  • MySQL常用的文本文件导出导入方式总结

    目录 一 导出 1 1 mysql命令导出文本文件 1 2 select into outfile导出文本文件 1 3 mysqldump导出文本文件 二 导入 2 1 mysqlimport导入文本文件 2 2 LOAD DATA INF
  • 笔记记录--基于ccpd数据集利用Paddle OCR训练车牌检测模型

    目录 1 环境搭建 2 数据集划分 3 训练模型 4 推理测试 1 环境搭建 安装Paddle OCR参考 创建环境 conda create n paddle env python 3 8 conda activate paddle en
  • Zookeeper报错Will not attempt to authenticate using SASL解决办法

    Will not attempt to authenticate using SASL unknown error 经过查资料 这个问题与zookeeper里面的zoo cfg配置有关 在程序填写的zookeper的路径 一定与zoo cf
  • CSS网页设计》》

    这是跟着老师做的一个小案例 小小的有了一点成就感 下次努力 div class header div class logo img src img logo png alt logo div div class nav u u div di
  • Linux设备驱动的软件架构思想与设备驱动的基础内容总结

    Linux设备驱动的软件架构思想与设备驱动的基础内容总结 Linux是一个兼容性特别强的一个系统 而兼容性的实现与驱动强大的适应性密不可分 而这个具体的实现是离不开 总线bus和类class的管理方式 Linux使用bus统一的管理一系列相
  • Tomcat 部署方式

    Tomcat中三种部署项目的方法 第一种方法 在tomcat中的conf目录中 在server xml中的
  • 思科三层交换机IPv6静态和默认路由配置

    基础配置 SWA Switch gt ena Switch conf t Switch config host SWA SWA config vlan 10 SWA config vlan vlan 100 SWA config vlan
  • echarts ——timeLine组件

    echarts timeLine组件问题 带timeLine 组件的动态图例 从官网社区中的图例非常完美 拷贝到自己的项目中 下面的1月 2月 只显示0 1 2 3 刚开始以为是获取数据的方法有误 项目空闲期再回看代码发现问题所在 地址 h
  • JavaMail读取收件箱退信邮件/分析邮件附件获取Message_Id

    需求描述 公司最近有个项目邮件通知功能 但是客户上传的邮件地址并不一定存在 以及其他的各种问题 所有希望发送通知后有个回执 及时发现地址存在问题的邮箱 需求分析 经过分析JavaMail可以读取收件箱邮件 我们可以通过对应通知的退信来回写通
  • 爬取12306验证码图片

    author yc import urllib urllib2 import ssl headers User Agent Mozilla 5 0 Windows NT 10 0 WOW64 AppleWebKit 537 36 KHTML
  • c taskspawn 需要申请堆栈的大小 怎么设置_FreeRTOS Task.h/Task.c详解

    刚入门 把自己的理解记录以下 ifndef INC FREERTOS H error include FreeRTOS h must appear in source files before include task h endif 在
  • vaware上安装Linux详细步骤(Slackware10.2)

    环境 HostOS Win2K SP4 GuestOS Slackware10 2 VMware Workstation 5 5 1 b19175 1 建立虚拟机 在VMware上新建一个2 4 x内核的Linux虚拟机 因为Slackwa
  • 消防图像火灾探测器原理

    消防图像火灾探测器是一种基于图像处理技术的先进火灾探测设备 它的工作原理是通过对火灾图像进行分析和识别 实现对火灾的早期探测和报警 这种火灾探测器采用了先进的计算机视觉技术 可以实时监测火灾发生的地点 并在火灾发生之初就能够及时发出警报 从
  • 永擎服务器主板稳定性,永擎双路服务器主板+Platinum铂金8124 8172M 8272CL 8222L套装...

    以下套餐均为单CPU价格 不含主板 不含内存 不要再重复问了 谢谢 套餐一 铂金Platinum 8251 正显版 2 12核24线程 基础频率3 8G 24线程满载4 0G 睿频4 2G 套餐二 铂金 3647 Platinum 8175
  • 如何调试VUE代码(VUE调试利器 vue devtools)

    前言 最新想开发一个前后端分离的项目 一直想开始的 拖延了好久终于决定要对它下手了 最早的时候开发的时候使用的还是JSP 那个时候使用的还是EL表达式 后来切换到Spring和SpringMVC之后采用的是HTML JS的all in on
  • python单元测试框架(继承、unittest参数化、断言、测试报告)

    一 继承 继承能解决什么问题 unittest每个模块都要用到前提条件以及清理 如果有上百个模块 我们要改域名和浏览器 就会工作量很大特别麻烦 这时我们可以用继承的思想只用改一次 我们可以将前提和清理提出来单独放到一个文件里 具体代码如下