selenium----unittest框架以及数据驱动

unittest框架:UI界面层的单元功能测试框架 (黑盒测试)
Java单元测试框架 Junit (白盒测试)

unittest 各组件:
1)测试固件
setUp() 进行初始化工作
tearDown()进行测试完后的清理工作
2)TestCase 测试用例
测试方法:test_开头
3)批量执行
把多个测试用例(可以说一个脚本中,也可以是多个脚本中)放到一个测试套件中去执行
4)执行测试用例
TestRunner
5)生成测试报告
HTMLRunner

unittest 各组件的关系为:
selenium----unittest框架以及数据驱动_第1张图片
test fixture:初始化和清理测试环境,比如创建临时的数据库,文件和目录等,其中 setUp() :初始化和 setDown():清理工作

是最常用的方法
test case:单元测试用例,TestCase 是编写单元测试用例最常用的类
test suite:单元测试用例的集合,TestSuite 是最常用的类
test runner:执行单元测试
test report:生成测试报告

一个测试方法:


from selenium import webdriver
import unittest
import os
import time


class Baidu1(unittest.TestCase):
#测试固件
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.maximize_window()
        time.sleep(3)

    def tearDown(self):
        self.driver.quit()
#测试方法
    def test_hao(self):
        driver=self.driver
        self.driver.get(self.url)
        driver.find_element_by_link_text("hao123").click()
        time.sleep(6)

    if __name__=="__main__":
        unittest.main(verbosity=0)

self:类的实例

批量执行脚本

构建测试套件

假设我们已经编写了test001.py,test002.py两个文件,那么我们怎么同时执行这两个文件呢?
test001.py:

#浏览器对本地文件进行操作
from selenium import webdriver
import unittest
import os
import time
from selenium.common.exceptions import NoAlertPresentException

class testCase1(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.get(self.url)
        self.driver.maximize_window()
        time.sleep(3)

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

    def test_baidu1(self):
        driver=self.driver
        driver.find_element_by_id("kw").send_keys("刘亦菲")
        driver.find_element_by_id("su").click()
        time.sleep(6)

    def test_baidu2(self):
        driver = self.driver
        driver.find_element_by_link_text("新闻").click()
        time.sleep(6)

    def is_alter_exist(self):
        try:
            self.driver.switch_to.alert
        except NoAlertPresentException as e:
            return False
        return True

    if __name__=="__main__":
        unittest.main(verbosity=0)

test002.py:

#浏览器对本地文件进行操作
from selenium import webdriver
import unittest
import os
import time
from selenium.common.exceptions import NoAlertPresentException

class testCase2(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.get(self.url)
        self.driver.maximize_window()
        time.sleep(3)

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

    def test_baidu1(self):
        driver=self.driver
        driver.find_element_by_id("kw").send_keys("陕西")
        driver.find_element_by_id("su").click()
        time.sleep(6)

    def test_baidu2(self):
        driver = self.driver
        driver.find_element_by_link_text("hao123").click()
        time.sleep(6)

    def is_alter_exist(self):
        try:
            self.driver.switch_to.alert
        except NoAlertPresentException as e:
            return False
        return True

    if __name__=="__main__":
        unittest.main(verbosity=0)

addTest() 的应用

把一个脚本文件类中的所有测试用例一个一个添加进测试套件
当有多个或者几百测试用例的时候, 这样就需要一个测试容器( 测试套件) ,把测试用例放在该容器中进行执行,unittest 模块中提供了TestSuite 类来生成测试套件,使用该类的构造函数可以生成一个测试套件的实例,该类提供了addTest来把每个测试用例加入到测试套件中。
将test001.py、test002.py、runall.py放在同一个目录testcase中

import unittest
from src0717 import test001
from src0717 import test002

def createSuite():
    suite=unittest.TestSuite()
    suite.addTest(test001.testCase1("test_baidu1"))
    suite.addTest(test001.testCase1("test_baidu2"))
    suite.addTest(test002.testCase2("test_baidu1"))
    suite.addTest(test002.testCase2("test_baidu2"))
    return suite

if __name__ =="__main__":
    suite=createSuite()
    runner=unittest.TextTestRunner(verbosity=2)
    runner.run(suite)

上述做法有两个不方面的地方,阻碍脚本的快速执行,必须每次修改runall.py:
1)需要导入所有的py文件,比如import test001,每新增一个需要导入一个
2)addTest需要增加所有的testcase,如果一个py文件中有10个case,就需要增加10次

 runner=unittest.TextTestRunner(verbosity=2)
 =0(静默模式:只能获取总的测试用例数和总的结果比如总共有100个失败20,成功80
 =1(默认模式):非常类似静默模式,只是在每个成功的用例前面有个"."每个失败的用例前面有个”F“
 =2(详细模式):测试结果会显示每个测试用例的所有相关的信息

makeSuite()和TestLoader()的应用

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

import unittest
from src0717 import test001
from src0717 import test002

def createSuite():
    suite=unittest.TestSuite()
    # make Suite
    #suite.addTest(unittest.makeSuite(test001.testCase1))
    #suite.addTest(unittest.makeSuite(test002.testCase2))
    #return suite
    
    #TestLoader
    suite1=unittest.TestLoader().loadTestsFromTestCase(test001.testCase1)
    suite2=unittest.TestLoader().loadTestsFromTestCase(test002.testCase2)
    suite=unittest.TestSuite([suite1,suite2])
    return suite
    
if __name__ =="__main__":
    suite=createSuite()
    runner=unittest.TextTestRunner(verbosity=2)
    runner.run(suite)

discover()的应用

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

import unittest
from src0717 import test001
from src0717 import test002

def createSuite():
 
discover=unittest.defaultTestLoader.discover('../src0717',pattern='test00*.py',top_level_dir=None)
    print(discover)
    return discover

if __name__ =="__main__":
    suite=createSuite()
    runner=unittest.TextTestRunner(verbosity=2)
    runner.run(suite)

总结:

1.unittest测试固件
setUp():初始化
tearDown():清理工作
2.TestDown
Test_运行这个类的时候默认执行
3.测试套件:存放测试用例(测试方法)的一个容器
addTest 可以一次存放一个测试脚本里一个类的一个方法(提供方法名)
makeSuite 可以一次性存放一个测试脚本的一个类的所有方法
TestLoader 可以一次性存放一个测试脚本的一个类的所有方法
discover 可以把指定文件夹下,所有特定格式命名的测试脚本中类的所有以test_开头的方法
4.runner

测试用例的执行顺序

unit test框架中测试用例执行顺序:0~9,A ~ Z ,a ~z

忽略测试用例的执行

加上标签:@unittest.skip(“skipping”)

unit test断言

selenium----unittest框架以及数据驱动_第2张图片

测试报告

脚本执行完毕之后,还需要看到HTML报告,下面我们就通过HTMLTestRunner.py 来生成测试报告。 HTMLTestRunner支持python2.7
HTMLTestRunner.py 文件,下载地址: http://tungwaiyip.info/software/HTMLTestRunner.html
python3 下载地址: http://pan.baidu.com/s/1tp3Ts
下载后将其放在testcase目录中去或者放入…\Python3\Lib 目录下(windows)。

import unittest
import HTMLTestRunner
import os,sys
import time

def createSuite():
    discover = unittest.defaultTestLoader.discover('../src0717', pattern='test00*.py', top_level_dir=None)
    print(discover)
    return discover

if __name__ =="__main__":
    #获取当前文件所在的文件路径
    #1.创建一个文件夹
    curpath=sys.path[0]
    #sys.path是一个路径集合数组
    print(curpath)
    print(sys.path[0])
    #当前路径下resultreport文件夹不存在时就创建一个
    if not os.path.exists("/resultReport"):
        os.makedirs(curpath+"/resultReport")
    #2.解决重复命名的问题
    now=time.strftime("%Y-%m-%d-%H %M %S",time.localtime(time.time()))
    print(time.time)
    print(time.location(time.time()))
    #文件名是路径加上文件的名称
    filename=curpath+"/resultReport"+now+"-"+"resultReport.html"
    #打开HTML文件,wb以写的方式
    with open(filename,'wb') as fp:
        #括号里的参数是HTML括号里面的参数
        runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u"测试报告",
                                             description=u'用例执行情况',verbosity=2)
        suite=createSuite()
        runner.run(suite)

查看报告:
selenium----unittest框架以及数据驱动_第3张图片
selenium----unittest框架以及数据驱动_第4张图片

sys.path 和sys.path[0]

sys.path[0] :\java\python\test\src0717
sys.path 是一个路径集合
[‘D:\java\python\test\src0717’, ‘D:\java\python\test’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\python38.zip’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\DLLs’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\lib’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38’, ‘C:\Users\lenovo\AppData\Local\Programs\Python\Python38\lib\site-packages’]

time.time:Linux 时间戳
time.location()格式化本地时间

异常捕捉和错误截图

#错误截图
from selenium import webdriver
import unittest
import os
import time
from selenium.common.exceptions import NoAlertPresentException

class testCase1(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.maximize_window()
        time.sleep(3)

    def tearDown(self):
        self.driver.quit()
    @unittest.skip("skipping")
    def test_baidu1(self):
        driver=self.driver
        driver.find_element_by_id("kw").send_keys("刘亦菲")
        driver.find_element_by_id("su").click()
        time.sleep(6)

    def test_baidu2(self):
        driver = self.driver
        self.driver.get(self.url)
        #判断到底有没有打开百度页面
        try:
            self.assertEqual(driver.title,"百度一下,你就知道",msg="判断失败")
        except:
            self.save_error_image(driver,"baidu.png")
        time.sleep(6)

    def save_error_image(self,driver,name):
        if not os.path.exists("./errorImage"):
            os.makedirs("./errorImage")
        now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
        driver.get_screenshot_as_file("./errorImage/"+now+"-"+name)
    def is_alter_exist(self):
        try:
            self.driver.switch_to.alert
        except NoAlertPresentException as e:
            return False
        return True

    if __name__=="__main__":
        unittest.main(verbosity=0)

数据驱动

安装ddt: pip install ddt
查看是否安装上:pip show ddt

#数据驱动
from selenium import webdriver
import unittest
import os
import time
from ddt import ddt,file_data,unpack,data
@ddt
class testCase1(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.maximize_window()
        time.sleep(3)

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

    @data("刘亦菲", "Lisa", "腾讯", "阿里巴巴")
    def test_baidu1(self,value):
        driver=self.driver
        driver.get(self.url)
        driver.find_element_by_id("kw").send_keys(value)
        driver.find_element_by_id("su").click()
        time.sleep(6)

    if __name__=="__main__":
        unittest.main(verbosity=0)

方法二:
test_baidu.json.py:

[
    "jolin",
    "林俊杰"
]

test.py:

#数据驱动

from selenium import webdriver
import unittest
import os
import time
from ddt import ddt,file_data,unpack,data
@ddt
class testCase1(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.maximize_window()
        time.sleep(3)

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

    #@data("刘亦菲", "Lisa", "腾讯", "阿里巴巴")
    @file_data('test_baidu.json.py')
    def test_baidu1(self,value):
        driver=self.driver
        driver.get(self.url)
        driver.find_element_by_id("kw").send_keys(value)
        driver.find_element_by_id("su").click()
        time.sleep(6)

    if __name__=="__main__":
        unittest.main(verbosity=0)

传递一组参数,每组参数位两个及两个以上:

#数据驱动

from selenium import webdriver
import unittest
import os
import time
from ddt import ddt,file_data,unpack,data

@ddt
class testCase1(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.url="https://www.baidu.com/"
        self.driver.maximize_window()
        time.sleep(3)

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


    @data(["Jojin","Jojin_百度搜索"],["刘亦菲","刘亦菲_百度搜索"])
    @unpack
    def test_baidu1(self,value1,value2):
        driver = self.driver
        driver.get(self.url)
        driver.find_element_by_id("kw").send_keys(value1)
        driver.find_element_by_id("su").click()
        time.sleep(6)
        print(driver.title)
        self.assertEqual(driver.title,value2,msg="fail")
        time.sleep(6)

    if __name__=="__main__":
        unittest.main(verbosity=0)

方法二:
创建一个test_baidu.txt:
data
刘亦菲,刘亦菲_百度搜索
汉服,汉服_百度搜索
西安,西安_百度搜索
创建一个test.py:

# -*- coding: utf-8 -*-

from selenium import webdriver
import unittest
import os,sys
import time,csv
from ddt import ddt,file_data,unpack,data



def getCsv(file_name):
    rows=[]
    path=sys.path[0]

    with open(path+'/data/'+file_name,'rt') as f:
        readers=csv.reader(f,delimiter=',',quotechar='|')
        next(readers,None)
        for row in readers:
            temprows=[]
            for i in row:
                temprows.append(i)
            rows.append(temprows)
        return rows


@ddt
class Baidu1(unittest.TestCase):
    def setUp(self):
        self.driver=webdriver.Chrome()
        self.driver.implicitly_wait(30)
        self.base_url="https://www.baidu.com/"
        self.driver.maximize_window()

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

    @data(*getCsv('test_baidu_data.txt'))
    @unpack
    def test_baidu2(self,value,expect_value):
        driver = self.driver
        driver.get(self.base_url+"/")
        driver.find_element_by_id("kw").clear()
        driver.find_element_by_id("kw").send_keys(value)
        driver.find_element_by_id("su").click()
        driver.maximize_window()
        time.slee(6)
        #判断搜索网页的title和我们期望的是否一致
        print(expect_value)
        print(driver.title)
        self.assertEqual(expect_value,driver.title,msg="和预期结果不一致!")

        time.sleep(6)

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

你可能感兴趣的:(基于python的自动化测试,测试,selenium,python)