IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> selenium学习(Unittest框架,数据驱动) -> 正文阅读

[开发测试]selenium学习(Unittest框架,数据驱动)

Unittest框架

unittest 简介

unittest 是python 的Uij界面的单元测试框架,unittest 单元测试提供了创建测试用例,测试套件以及批量执行的方案, unittest 在安装pyhton 以后就直接自带了,直接import unittest 就可以使用。作为单元测试的框架, unittest 也是可以对程序最小模块的一种敏捷化的测试。在自动化测试中,我们虽然不需要做白盒测试,但是必须需要知道所使用语言的单元测试框架。利用单元测试框架,创建一个类,该类继承unittest的TestCase,这样可以把每个case看成是一个最小的单元, 由测试容器组织起来,到时候直接执行,同时引入测试报告。

unittest组成部分及关系

在这里插入图片描述

  • test ?xture:初始化和清理测试环境,比如创建临时的数据库,文件和目录等,其中setUp()和tearDown()是最常用的方法
  • test case:单元测试用例,TestCase是编写单元测试用例最常用的类
  • test suite:单元测试用例的集合,TestSuite是最常用的类
  • test runner:执行单元测试
  • test report:生成测试报告

test case

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
# 定义获得类(继承)
class Baidu1(unittest.TestCase):
 def setUp(self): # 相当于初始化方法,测试固件
 self.driver = webdriver.Firefox()
 self.driver.implicitly_wait(30)
 self.base_url = "http://www.baidu.com/"
 self.verificationErrors = []
 self.accept_next_alert = True
 def test_baidusearch(self): # 测试用例,要以test开头
 driver = self.driver
 driver.get(self.base_url + "/")
 driver.find_element_by_id("kw").click()
 driver.find_element_by_id("kw").clear()
 driver.find_element_by_id("kw").send_keys(u"测试")
 driver.find_element_by_id("su").click()
 
 def test_hao(self):
 driver = self.driver
 driver.get(self.base_url + "/")
 driver.find_element_by_link_text("hao123").click()
 self.assertEqual(u"hao123_上网从这里开始", driver.title)

 #test fixture,清除环境
 def tearDown(self):
 self.driver.quit()
 self.assertEqual([], self.verificationErrors)
if __name__ == "__main__": # 执行入口
 unittest.main(verbosity=2)

构建测试套件
完整的单元测试很少只执行一个测试用例,开发人员通常都需要编写多个测试用例才能对某一软件功能进行比较完整的测试,这些相关的测试用例称为一个测试用例集,在unittest中是用TestSuite 类来表示的。

addTest() 的应用
当有多个或者几百测试用例的时候, 这样就需要一个测试容器( 测试套件) ,把测试用例放在该容器中进行执行,unittest 模块中提供了TestSuite 类来生成测试套件,使用该类的构造函数可以生成一个测试套件的实例,该类提供了addTest来把每个测试用例加入到测试套件中。只能一个一个的添加。

import unittest,csv
import os,sys
import time
#导入testbaidu1,testbaidu2
import testbaidu1
import testbaidu2
#手工添加案例到套件,
def createsuite():
 suite = unittest.TestSuite()
 #将测试用例加入到测试容器(套件)中
 suite.addTest(testbaidu1.Baidu1("test_baidusearch"))
 # testbaidu1文件下的Baidu1 测试类(test case)中的test_baidusearc测试用例(一个方法)
 suite.addTest(testbaidu2.Baidu2("test_baidusearch"))
 return suite
 
if __name__=="__main__":
 suite=createsuite()
 runner = unittest.TextTestRunner(verbosity=2)
 runner.run(suite)

makeSuite()和TestLoader()的应用
在unittest 框架中提供了makeSuite() 的方法,makeSuite可以实现把测试用例类内所有的测试case组成的测试套件TestSuite ,unittest 调用makeSuite的时候,只需要把测试类名称传入即可。TestLoader 用于创建类和模块的测试套件,一般的情况下,使TestLoader().loadTestsFromTestCase(TestClass)来加载测试类。

def createsuite():
 suite = unittest.TestSuite()
 #将测试用例加入到测试容器(套件)中
 suite.addTest(unittest.makeSuite(testbaidu1.Baidu1))
 suite.addTest(unittest.makeSuite(testbaidu2.Baidu2))
 return suite
 '''
 suite1 = unittest.TestLoader().loadTestsFromTestCase(testbaidu1.Baidu1) 
 suite2 = unittest.TestLoader().loadTestsFromTestCase(testbaidu2.Baidu2) 
 suite = unittest.TestSuite([suite1, suite2])
 return suite

discover()的应用
discover 是通过递归的方式到其子目录中从指定的目录开始, 找到所有测试模块并返回一个包含它们对象的TestSuite ,然后进行加载与模式匹配唯一的测试文件,discover 参数分别为discover(dir,pattern,top_level_dir=None)

import unittest,csv
import os,sys
import time
#手工添加案例到套件,
def createsuite():
 
discover=unittest.defaultTestLoader.discover('../test',pattern='test*.py',top_level_dir=None)
 print discover
 return discover
 
if __name__=="__main__":
 suite=createsuite()
 runner = unittest.TextTestRunner(verbosity=2)
 runner.run(suite)

用例的执行顺序
unittest 框架默认加载测试用例的顺序是根据ASCII 码的顺序,数字与字母的顺序为: 09,AZ,a~z 。所以, TestAdd 类会优先于TestBdd 类被发现, test_aaa() 方法会优先于test_ccc() 被执行。对于测试目录与测试文件来说, unittest 框架同样是按照这个规则来加载测试用例。addTest()方法按照增加顺序来执行。
忽略用例执行
放在方法前

@unittest.skip("skipping")
def test_baidusearch(self):

unittest断言

自动化的测试中, 对于每个单独的case来说,一个case的执行结果中, 必然会有期望结果与实际结果, 来判断该case是通过还是失败, 在unittest 的库中提供了大量的实用方法来检查预期值与实际值, 来验证case的结果, 一般来说, 检查条件大体分为等价性, 逻辑比较以及其他, 如果给定的断言通过, 测试会继续执行到下一行的代码, 如果断言失败, 对应的case测试会立即停止或者生成错误信息( 一般打印错误信息即可) ,但是不要影响其他的case执行。
在这里插入图片描述

self.assertEqual("admin", driver.find_element_by_link_text("admin").text)

HTML报告生成

脚本执行完毕之后,还需要看到HTML报告,下面我们就通过HTMLTestRunner.py 来生成测试报告。HTMLTestRunner支持python2.7。

import unittest,csv
import os,sys
import time
import HTMLTestRunner
#手工添加案例到套件,
def createsuite(): 
discover=unittest.defaultTestLoader.discover('../test',pattern='test*.py',top_level_dir=None)
 print discover
 return discover
if __name__=="__main__":
 curpath=sys.path[0]
 #取当前时间
 now=time.strftime("%Y-%m-%d-%H %M %S",time.localtime(time.time()))
 if not os.path.exists(curpath+'/resultreport'):
 os.makedirs(curpath+'/resultreport')
 
 filename=curpath+'/resultreport/'+now+'resultreport.html'
 with open(filename,'wb') as fp:
 #出html报告
 runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u'测试报告',description=u'用例执行情况',verbosity=2)
 suite=createsuite()
 runner.run(suite)

异常捕捉与错误截图

用例不可能每一次运行都成功,肯定运行时候有不成功的时候。如果可以捕捉到错误,并且把错误截图保存,这将是一个非常棒的功能,也会给我们错误定位带来方便。

 def savescreenshot(self,driver,file_name):
 if not os.path.exists('./image'):
 os.makedirs('./image')
 now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
 #截图保存
 driver.get_screenshot_as_file('./image/'+now+'-'+file_name)
 time.sleep(1)

数据驱动

python 的unittest 没有自带数据驱动功能。所以如果使用unittest,同时又想使用数据驱动,那么就可以使用DDT来完成。

@data(“1”,“2”,“3”)适合传递一个参数的,并把方法里的量改为变量,数据量大时,可以通过file_data加JSON文件的方式来,例如下面的例子会一次查找 :“王凯”, “Lisa”, “特朗普”, "蒋欣"等四个数据

from selenium import webdriver
import unittest
import time
from ddt import ddt, unpack, data, file_data
import sys, csv
# 先要表示这个类是DDT类
@ddt
class Baidu1(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.implicitly_wait(30)
        self.base_url = "http://www.baidu.com/"
        self.driver.maximize_window()
        self.verificationErrors=[]
        self.accept_next_alert = True
    def tearDown(self):
        self.driver.quit()
        self.assertEqual([],self.verificationErrors)
 
    @data("王凯", "Lisa", "特朗普", "蒋欣")
    def test_baidu1(self, value): 
    #这里的value参数就是一次读入的@data("王凯", "Lisa", "特朗普", "蒋欣")的四个数据
        driver = self.driver
        driver.get(self.base_url + "/")
        driver.maximize_window()
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(value)
        driver.find_element_by_id("su").click()
        #time.sleep(6)
        #self.assertEqual(driver.title, expected_value, msg="搜索结果和期望不一致!")
        time.sleep(3)

当@data需要传递的是多个参数的时候 要用一个中括号将一组数据抱起来,并加上 @unpack(表示解绑),例如:
@data([“1”,“1”,“1”,“1”],[“1”,“1”,“1”,“2”],[“1”,“2”,“1”,“1”])
@unpack
具体代码

    @data(["1","1","1","1"],["1","1","1","2"],["1","2","1","1"])
    @unpack
    def test_triangle1(self,value1,value2,value3,value4):
        # text_开头会默认的去运行
        driver = self.driver
        driver.find_element_by_id("username").send_keys(value1)
        time.sleep(1)
        driver.find_element_by_id("idcard").send_keys(value2)
        time.sleep(1)
        driver.find_element_by_id("pwd").send_keys(value3)
        time.sleep(1)
        driver.find_element_by_id("pwd2").send_keys(value4)
        time.sleep(1)

还可以写一个JSON文件,读取JSON文件
在这里插入图片描述

     @file_data("test.json")# 当每一次要传多组数据的时候,用unpack
  
    def test_triangle1(self,value1,value2,value3,value4):
        # text_开头会默认的去运行
        driver = self.driver
        driver.find_element_by_id("username").send_keys(value1)
        time.sleep(1)
        driver.find_element_by_id("idcard").send_keys(value2)
        time.sleep(1)
        driver.find_element_by_id("pwd").send_keys(value3)
        time.sleep(1)
        driver.find_element_by_id("pwd2").send_keys(value4)

很多时候测试的数据比较多,这样就不可能将成千上万的数据放在代码中,这样就会显得代码很臃肿,所以就需要将这些测试数据和代码进行分离,需要数据的时候直接在文件中读取就可以了,这样不仅显得代码简洁美观,还易于理解并添加数据。

import csv,os,sys,time
from selenium import webdriver
import unittest
from ddt import ddt, unpack, data
# 继承TestCase类
def getCsv(file_name):
    rows = []
    path = sys.path[0]
    print(path)
    # 'rt代表读,wb代表写
    with open(path + "/data/" + file_name, 'rt') as f:
        readers = csv.reader(f, delimiter=',', quotechar='|')
        next(readers, None)  
        # 一行一行的读,delimiter=','用逗号分割, quotechar='|'代表回车,读的结果放在readers中
        for row in readers:
            temprows = []  # 将遍历的每一行结果放在这个数组当中,在读
            for i in row:
                temprows.append(i)
            rows.append(temprows)
        return rows

@ddt
class test01(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.url = "http://localhost:8080/dd/reg.html"
        self.driver.get(self.url)
        self.driver.maximize_window()


    def tearDown(self):
        self.driver.quit()
    @data(*getCsv("wenjianqudong01.txt"))
    @unpack
    def test_triangle1(self, value1, value2, value3, value4):
        # text_开头会默认的去运行
        driver = self.driver
        driver.find_element_by_id("username").send_keys(value1)
        # time.sleep(1)
        driver.find_element_by_id("idcard").send_keys(value2)
        # time.sleep(1)
        driver.find_element_by_id("pwd").send_keys(value3)
        # time.sleep(1)
        driver.find_element_by_id("pwd2").send_keys(value4)
        # time.sleep(1)
        driver.find_element_by_css_selector("#button1 > div > input[type=button]:nth-child(1)").click()
        time.sleep(1)
        alert = driver.switch_to.alert
        print(value1 + value2 + value3 + value4 + ":" + alert.text)
        alert.accept()
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-07-25 11:58:14  更:2021-07-25 11:58:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年3日历 -2024/3/29 1:17:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码