Bootstrap

unittest框架

Python自带的一个作为单元测试的测试框,PyUnit,相当于Java中的JUnit,

随着自动化技术的成熟,UnitTest成为了测试框架第一选择,可以完整的结合Selenium、Requests来实现l和接口的自动化,

由UnitTest再衍生出PyTest,PyTest可以完美结合UnitTest来实现自动化。

鄙视链:Py Test—Unit Test-RobotFrameWork基本应用:

1.环境搭建,

Python中已经直接加载了UnitTest框架,无须额外安装

2.四大组件:

a.test fixture:

setUp(前置条件)、tearDown(后置条件),用于初始化测试用例及清理和释放资源

b.test case:

测试用例,通过集成unitest.TestCase,来实现用例的继承,在UnitTest中,测试用例都是通过test来识别的。

c.test suite:

测试套件,也称之为测试用例集

d.test runner:

运行器,一般通过runner来调用suite去执行测试

3.UnitTest运行机制:

通过在main函数中,调用unittest.main()运行所有内容

UnitTest自动化实现实战:

1.自动化测试减少冗余,便于维护。

【案例1】

import unittest

class fortext(unittest.TestCase):

    # 类的初始化
    @classmethod
    def setUpClass(cls) -> None:
        print('class start')

    @classmethod
    def tearDownClass(cls) -> None: # 类的释放
        print('class end')

    #初始化
    def setUp(self) -> None:
        print('setup')
    def tearDown(self) -> None:
        print('teardown')

    def plus(self,a,b):
        c = a+b
        print(c)
        return c

    def test_a(self):
        print('aaa')

    def test_b(self):
        print('bbb')

    def test_c(self):
        self.plus(1,2)
        print('c')


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


【案例2】

import unittest
from selenium import webdriver
import time

class forTestTest(unittest.TestCase):

    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('http://www.baidu.com')

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


    def test_1(self):
        self.driver.find_element_by_id('kw').send_keys('虚竹')
        self.driver.find_element_by_id('su').click()

    def test_2(self):
        self.driver.find_element_by_id('kw').send_keys('小龙女')
        self.driver.find_element_by_id('su').click()

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

2.ddt 数据驱动

data-driver-tests 数据驱动测试,

在实际测试中,单个测试是需要用多种不同条件(多种数据)进行测试的。

ddt中最基本的使用:

在class前定义@ddt

在基于实际的应用中,选择对应的装饰器使用即可。@data 是其中一个

data 用于设定参数

unpack 用于解析参数

【案例3】

import unittest
from selenium import webdriver
import time
from ddt import ddt,data

@ddt
class forTestTest(unittest.TestCase):

    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('http://www.baidu.com')

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

    @data('虚竹','小龙女')
    def test_1(self,txt):
        self.driver.find_element_by_id('kw').send_keys(txt)
        self.driver.find_element_by_id('su').click()

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

web自动化测试

【案例:百度搜索】

import unittest
import time
from selenium import webdriver

class testBaidu(unittest.TestCase):

    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.base_url ='https://www.baidu.com'

    def test_serarch_key_selenium(self):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys('selenium')
        self.driver.find_element_by_id('su').click()
        time.sleep(10)
        title = self.driver.title
        self.assertEqual(title,"selenium_百度搜索")

    def test_serarch_key_unittest(self):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys('unittest')
        self.driver.find_element_by_id('su').click()
        time.sleep(10)
        title = self.driver.title
        self.assertEqual(title,"unittest_百度搜索")

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

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

【案例:百度搜索+关键字】

import unittest
import time
from selenium import webdriver

class testBaidu(unittest.TestCase):

    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.base_url ='https://www.baidu.com'

    def baidu_search(self,search_key):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys(search_key)
        self.driver.find_element_by_id('su').click()
        time.sleep(10)


    def test_search_key_selenium(self):
        search_key = 'selenium'
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title,search_key+"_百度搜索")

    def test_search_key_unittest(self):
        search_key = 'unittest'
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title, search_key + "_百度搜索")

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

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

【案例:百度搜索+关键字+classmethod】

import unittest
import time
from selenium import webdriver

class testBaidu(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome()
        cls.base_url = 'https://www.baidu.com'


    def setUp(self) -> None:
        print('我没用了吗,开始')

    def baidu_search(self,search_key):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys(search_key)
        self.driver.find_element_by_id('su').click()
        time.sleep(10)


    def test_search_key_selenium(self):
        search_key = 'selenium'
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title,search_key+"_百度搜索")

    def test_search_key_unittest(self):
        search_key = 'unittest'
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title, search_key + "_百度搜索")

    def tearDown(self) -> None:
        print('我没用了吗,那我走了')

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

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


"""
1.用setUp与setUpClass区别

    setup():每个测试case运行前运行
    teardown():每个测试case运行完后执行
    setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次
    tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次

2.@是修饰符,classmethod是python里的类方法

"""

小结

1.用setUp与setUpClass区别

setup():每个测试case运行前运行

teardown():每个测试case运行完后执行

setUpClass():必须使用@classmethod 装饰器,所有case运行前只运行一次

tearDownClass():必须使用@classmethod装饰器,所有case运行完后只运行一次

2.@是修饰符,classmethod是python

生成HTML测试报告

下载安装

下载HTMLTestRunner.py文件,放入python\lib 即可。

下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

生成测试报告

import unittest
from HTMLTestRunner import HTMLTestRunner

#定义测试用例的目录为当前目录下的test_case目录

test_dir = './test_case'
suit = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')

if __name__ == '__main__':
    #生成HTML格式的报告
    fp = open('./test_report/result20200523.html','wb')
    rnnner = HTMLTestRunner(stream =fp,
                            title='百度搜索测试报告',
                            description='运行环境:Windows10,Chrome浏览器'
                            )

    rnnner.run(suit)
    fp.close()

加注释的测试报告

"""
使用 setUpModule/ tearDownModule 减少浏览器的启动
"""
import unittest
from time import sleep
from selenium import webdriver


class Browser:
    driver = None
    base_url = None


def setUpModule():
    Browser.driver = webdriver.Chrome()
    Browser.base_url = "https://www.baidu.com"


def tearDownModule():
    Browser.driver.quit()


def baidu_search(search_key):
    Browser.driver.get(Browser.base_url)
    Browser.driver.find_element_by_id("kw").send_keys(search_key)
    Browser.driver.find_element_by_id("su").click()
    sleep(2)


class TestBaidu(unittest.TestCase):
    """百度搜索测试"""

    def test_search_key_selenium(self):
        '''搜索关键字:selenium '''
        search_key = "selenium"
        baidu_search(search_key)
        self.assertEqual(Browser.driver.title, search_key + "_百度搜索")

    def test_search_key_unttest(self):
        '''搜索关键字:unittest '''
        search_key = "unittest"
        baidu_search(search_key)
        self.assertEqual(Browser.driver.title, search_key + "_百度搜索")


class TestBaidu2(unittest.TestCase):
    """百度搜索测试2"""
    def test_search_key_python(self):
        """搜索关键字:python"""
        search_key = "python"
        baidu_search(search_key)
        self.assertEqual(Browser.driver.title, search_key + "_百度搜索")


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

按当前时间生成测试报告名

import unittest
from HTMLTestRunner import HTMLTestRunner
import time

#定义测试用例的目录为当前目录下的test_case目录

test_dir = './web_case'
suit = unittest.defaultTestLoader.discover(test_dir,pattern='test*.py')

if __name__ == '__main__':
    #生成HTML格式的报告
    now_time = time.strftime("%Y-%m-%d %H_%M_%S")  # 取当前日期时间
    fp = open(now_time+'result.html','wb')
    rnnner = HTMLTestRunner(stream =fp,
                            title='百度搜索测试报告',
                            description='运行环境:Windows10,Chrome浏览器'
                            )

    rnnner.run(suit)
    fp.close()

数据驱动-csv文件

import csv
import codecs
import unittest
from time import sleep
from itertools import islice
from selenium import webdriver

class TestBaidu(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome()
        cls.base_url = 'https://www.baidu.com'

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

    def baidu_search(self,search_keys):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys(search_keys)
        self.driver.find_element_by_id('su').click()
        sleep(3)

    def test_search(self):
        with codecs.open('baidu_data.csv','r','utf_8_sig') as f:
            data = csv.reader(f)
            for line in islice(data,1,None):
                search_key = line[1]
                self.baidu_search(search_key)

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

优化

import csv
import codecs
import unittest
from time import sleep
from itertools import islice
from selenium import webdriver

class TestBaidu(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome()
        cls.base_url = 'https://www.baidu.com'
        cls.test_data = []
        with codecs.open('baidu_data.csv', 'r', 'utf_8_sig') as f:
            data = csv.reader(f)
            for line in islice(data, 1, None):
                cls.test_data.append(line)

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

    def baidu_search(self,search_keys):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys(search_keys)
        self.driver.find_element_by_id('su').click()
        sleep(3)

    def test_search_selenium(self):
        self.baidu_search(self.test_data[0][1])

    def test_search_unittest(self):
        self.baidu_search(self.test_data[1][1])

    def test_search_parameterized(self):
        self.baidu_search(self.test_data[2][1])


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

Parameterized参数化库

import unittest
from time import sleep
from selenium import webdriver
from parameterized import parameterized

# import parameterized

class TestBaidu(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome()
        cls.base_url = 'https://www.baidu.com'

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

    def baidu_search(self,search_key):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys(search_key)
        self.driver.find_element_by_id('su').click()
        sleep(3)

    #通过parameterized 参数化
    @parameterized.expand([
        ("case1","selenium"),
        ("case2","unittest"),
        ("case3","parameterized")
    ])

    def test_search(self,name,search_key):
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title,search_key+"_百度搜索")

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

ddt参数库

参数一 列表
import unittest
from time import sleep
from selenium import webdriver
from ddt import  ddt,data,file_data,unpack

@ddt
class TestBaidu(unittest.TestCase):

    @classmethod
    def setUpClass(cls) -> None:
        cls.driver = webdriver.Chrome()
        cls.base_url = 'https://www.baidu.com'

    def baidu_search(self,search_key):
        self.driver.get(self.base_url)
        self.driver.find_element_by_id('kw').send_keys(search_key)
        self.driver.find_element_by_id('su').click()
        sleep(3)

    #参数化使用方式一 列表
    @data(['case1','selenium'],['case2','ddt'],['case3','python'])
    @unpack
    def test_search1(self,case,search_key):
        print('第一组测试用例 列表',case)
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title,search_key+'_百度搜索')

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

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

参数二 元祖
    #参数化使用方式二 元祖
    @data(('case1','selenium'),('case2','ddt'),('case3','python'))
    @unpack
    def test_search2(self,case,search_key):
        print('第二组测试用例 列表',case)
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title,search_key+'_百度搜索')

参数三 字典
    #参数化使用方式二 元祖
    @data(('case1','selenium'),('case2','ddt'),('case3','python'))
    @unpack
    def test_search2(self,case,search_key):
        print('第二组测试用例 列表',case)
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title,search_key+'_百度搜索')

参数四 JSON

ddt_data_file.json

{
  "case1": {"search_key": "python"},
  "case2": {"search_key": "ddt"},
  "case3": {"search_key": "Selenium"}
}

  #参数化读取JSON文件
    @file_data('ddt_data_file.json')
    def test_search4(self,search_key):
        print('第四组测试用例:',search_key)
        self.baidu_search(search_key)
        self.assertEqual(self.driver.title,search_key+'_百度搜索')

未完待续 20200523