• 【四:Unittest框架】


    day1

    总结:

    from selenium import webdriver 页面及元素常用操作:
    四大操作
    元素操作
    三大等待
    三大切换 句柄/frame/alert
    键盘操作 keys
    鼠标操作 ActionChains
    JS操作 日期控件/滚动条
    下拉列表
    文件上传 input/非input类型文件

    pytest有inittest的区别
    https://blog.csdn.net/qq_33385691/article/details/112004487image.png

    一、如何开展自动化测试

    1、项目需求分析,了解业务需求 web功能纳入自动化测试 web功能:
    1、新功能 手工测试
    2、老功能 回归 冒烟用例 纳入自动化测试
    2、选择何种方式实现自动化测试
    1、工具 robotframework
    2、独立搭建web自动化测试框架
    3、编写自动化测试用例 一边写用例,一边调试用例脚本(用例编辑/封装/测试数据/脚本调试) 结合jenkins进行持续集成
    4、执行自动化测试用例
    1、定时执行、一键式执行
    2、执行策略 执行频率?—回归频率、转测试、上线前、 自动化测试执行环境----集成测试环境、预发布环境、
    5、测试报告 测试结果的汇总
    6、维护脚本、优化框架 企业自动化测试岗位:
    1、业务自动化测试 项目自动化测试框架已经构建了 工作内容: 维护框架+用例编辑
    2、平台自动化测试开发 参与自动测试框架构建与设计、+维护框架+用例编

    二、Unittest框架 Unittest框架:

    框架=测试模块+测试管理模块+测试统计模块,python的内置模块

    框架四大组件

    import unittest Unittest框架四大组件:
    1、TestCase 测试用例
    2、TestFixture
    3、TestSuite
    4、TestRunner

    三、TestCase 测试用例

    unittest中TestCase部分的规则:
    1、用例类必须继承Unittest.TestCase,并且以test开头
    2、每条用例,都必须以test开头
    3、用例执行的顺序按照ASCII
    0-9 a-z A-Z 顺序来执行用例
    unittest也可以通过命令运行
    命令执行TestShopnc类下的所有用例: python -m unittest 用例文件名.用例类 执行某一条用例: python -m unittest 用例文件名.用例类.用例名称

    import unittest
    class testShopnc(unittest.TestCase):
        def test01_login(self):
            # 用例操作步骤
            # self.driver = webdriver.Chrome()
            # self.driver.get("https://www.baidu.com")
            # el1=self.driver.find_element(By.ID,"kw")
            # el1.send_keys("码尚教育")
            print("用例01")
            # 用例断言?
        def test02_selectgoods(self):
            print("用例02")
    
        def test03_intocart(self):
            print("用例03")
    
        def test04_paygoods(self):
            print("用例04")
    
    if __name__ == '__main__':
        # 执行方式2  执行所有用例
        # unittest.main()
        # 执行部分用例
        # suite=unittest.TestSuite()
        # 添加一个用例
        # suite.addTest(testShopnc('test01_login'))
        # suite.addTest(testShopnc('test02_selectgoods'))
    
        # 添加多个用例
        # caselist=[testShopnc('test03_intocart'),testShopnc('test04_paygoods')]
        # suite.addTest(caselist)
        # unittest.main(defaultTest='suite')
    
    
        # 用例加载器 加载某个用例类(继承TestCase 下的所有类)loadTestsFromTestCase
        # suite2 = unittest.TestSuite()
        # testcase2=unittest.TestLoader().loadTestsFromTestCase(testShopnc)
        # suite2.addTest(testcase2)
        # unittest.main(defaultTest='suite2')
    
    
        # 利用默认家啊在其执行用例
        suite3 = unittest.TestSuite()
        testcase3=unittest.defaultTestLoader.discover('test*.py')
        unittest.main(defaultTest='suite3')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    四、TestFixture 测试夹具 执行测试用例前的前置操作及后置操作

    web自动化测试:
    前置操作:
    后置操作:

    import unittest
    from selenium.webdriver.chrome import webdriver
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    
    
    
    
    class testShopnc(unittest.TestCase):
        # 前置操作
        def setUp(self):
            # webdriver.Chrome.close()
            # webdriver.Chrome.quit()
            # 加载项目
            print("setUp执行每条用例前都会执行函数代码,有n条用例,则会执行n次")
    
        @classmethod
        def setUpClass(cls):
            # 前置操作:连接数据,打开浏览器
            print("setUpClass执行用例前会执行 ,总共只执行一次")
    
        # 后置操作
        def tearDown(self) -> None:
            # 后置操作:浏览器的关闭
            print("tearDown执行完每条用例前都会执行代码,有n条用例,则会执行n次")
    
        @classmethod
        def tearDownClass(cls) -> None:
            # 退出浏览器,关闭数据库连接,清理数据
            print("tearDownClass执行完所有用例之后会执行代码 ,总共只执行一次")
    
        def test01_login(self):
            # 用例操作步骤
            # self.driver = webdriver.Chrome()
            # self.driver.get("https://www.baidu.com")
            # el1=self.driver.find_element(By.ID,"kw")
            # el1.send_keys("码尚教育")
            print("用例01")
            # 用例断言?
    
        def test02_selectgoods(self):
            print("用例02")
    
        def test03_intocart(self):
            print("用例03")
    
        def test04_paygoods(self):
            print("用例04")
    
    if __name__ == '__main__':
            # 执行方式2  执行所有用例
            # unittest.main()
            # 执行部分用例
            # suite=unittest.TestSuite()
            # 添加一个用例
            # suite.addTest(testShopnc('test01_login'))
            # suite.addTest(testShopnc('test02_selectgoods'))
    
            # 添加多个用例
            # caselist=[testShopnc('test03_intocart'),testShopnc('test04_paygoods')]
            # suite.addTest(caselist)
            # unittest.main(defaultTest='suite')
    
            # 用例加载器 加载某个用例类(继承TestCase 下的所有类)loadTestsFromTestCase
            suite2 = unittest.TestSuite()
            testcase2 = unittest.TestLoader().loadTestsFromTestCase(testShopnc)
            suite2.addTest(testcase2)
            unittest.main(defaultTest='suite2')
    
            # 利用默认家啊在其执行用例
            # suite3 = unittest.TestSuite()
            # testcase3=unittest.defaultTestLoader.discover('test*.py')
            # unittest.main(defaultTest='suite3')
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    五、 TestSuite 测试套件 用例集(把需要执行的用例汇总到一起)

    if __name__ == '__main__':
            # 执行方式2  执行所有用例
            # unittest.main()
            # 执行部分用例
            # suite=unittest.TestSuite()
            # 添加一个用例
            # suite.addTest(testShopnc('test01_login'))
            # suite.addTest(testShopnc('test02_selectgoods'))
    
            # 添加多个用例
            # caselist=[testShopnc('test03_intocart'),testShopnc('test04_paygoods')]
            # suite.addTest(caselist)
            # unittest.main(defaultTest='suite')
    
            # 用例加载器 加载某个用例类(继承TestCase 下的所有类)loadTestsFromTestCase
            suite2 = unittest.TestSuite()
            testcase2 = unittest.TestLoader().loadTestsFromTestCase(testShopnc)
            suite2.addTest(testcase2)
            unittest.main(defaultTest='suite2')
    
            # 利用默认家啊在其执行用例
            # suite3 = unittest.TestSuite()
            # testcase3=unittest.defaultTestLoader.discover('test*.py')
            # unittest.main(defaultTest='suite3')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    六、TestRunner 测试运行器 执行用例,把执行的结果输出给到用户 用例执行结果状态:

    . 用例执行成功
    E 用例有异常
    F 用例执行失败(断言失败)

    day2

    一、TestRunner 测试运行器 执行用例,输出测试结果
    1、unittest提供生产测试报告的模块 TextTestRunner 生成文本格式测试报告

    import unittest
    
    from class01.test_02 import TestCase01
    
    testcase=unittest.TestLoader().loadTestsFromTestCase(TestCase01)
    with open('./report/report.txt','w+')as f:
        unittest.TextTestRunner(stream=f,verbosity=2).run(testcase)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、常见的第三方库结合unittest生产html格式测试报告
    HtmlTestRunner 官网下载HtmlTestRunner.py只能支持python2版本,支持Python3,需要做修改
    路径:python安装路径/Lib
    HtmlTestRunner 的应用
    BeatifulReport 的应用

    # -!- coding: utf-8 -!-
    import unittest
    import HTMLTestRunner
    from BeautifulReport import BeautifulReport
    from class01.test_02 import TestCase01
    
    testcase=unittest.TestLoader().loadTestsFromTestCase(TestCase01)
    # 生成BeautifulReport报告
    BeautifulReport(testcase).report(filename='百度测试报告', description='搜索测试', report_dir='.')    #log_path='.'把report放到当前目录下
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    企业测试报告的优化及定制 优化测试报告模板 通过js+html/html5

    1、pytest+allure 生成更加美观的测试报告+优化定制(装饰器)

    from twisted.trial import unittest
    import unittest
    
    class TestCase01(unittest.TestCase):
    
        @unittest.skip("此用例暂时不启用")
        def test_login(self):
            """
            登录
            :return:
            """
            print("用例01")
        @unittest.skipIf(3>2,"条件为真,则跳过执行")
        def test_selectgoods(self):
            """
            检索商品
            :return:
            """
            print("用例02")
    
        @unittest.skipUnless(2>3,"条件:2>3不成立,则跳过执行")
        def test_gointocart(self):
            """
            加入购物车
            :return:
            """
            print("用例03")
            """
            @unittest.skip 强制跳过执行
            @unittest.skipIf 符合条件,则跳过执行
            @unittest.skipUnless 条件不成立,则跳过执行
            """
    
    
    @unittest.skipUnless(False,"整个模块下的用例强制跳过执行")
    class TestSkipModule(unittest.TestCase):
    
        def test_login(self):
            """
            登录
            :return:
            """
            print("用例01")
    
        def test_selectgoods(self):
            """
            检索商品
            :return:
            """
            print("用例02")
    
        def test_gointocart(self):
            """
            加入购物车
            :return:
            """
            print("用例03")
    
    if __name__ == '__main__':
        unittest.main()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    2、装饰器 @ unittest.skip 强制跳过&条件跳过

    import unittest
    
    class TestCase01(unittest.TestCase):
        @unittest.skip("此用例暂时不启用")
        def test_login(self):
            """
            登录
            :return:
            """
            print("用例01")
        @unittest.skipIf(3>2,"条件为真,则跳过执行")
        def test_selectgoods(self):
            """
            检索商品
            :return:
            """
            print("用例02")
    
        @unittest.skipUnless(2>3,"条件:2>3不成立,则跳过执行")
        def test_gointocart(self):
            """
            加入购物车
            :return:
            """
            print("用例03")
            """
            @unittest.skip 强制跳过执行
            @unittest.skipIf 符合条件,则跳过执行
            @unittest.skipUnless 条件不成立,则跳过执行
            """
    
    @unittest.skipUnless(False,"整个模块下的用例强制跳过执行")
    class TestSkipModule(unittest.TestCase):
    
        def test_login(self):
            """
            登录
            :return:
            """
            print("用例01")
    
        def test_selectgoods(self):
            """
            检索商品
            :return:
            """
            print("用例02")
    
        def test_gointocart(self):
            """
            加入购物车
            :return:
            """
            print("用例03")
    
    if __name__ == '__main__':
        unittest.main()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    3、unittest的常用断言方法

    # 常用断言方法
    # 1、assertIn(字符1,字符2) 字符1是否包含在字符2
    # 2、self.assertNotIn(字符1,字符2) 字符1不包含包含在字符2
    self.assertEqual(参数1, 参数2, "断言失败的描述")  参数1等于参数2
    self.assertNotEqual (参数1, 参数2, "断言失败的描述")  参数不等于参数2
    self.assertTrue(True)
    self.assertFalse(False)
    from selenium import webdriver
    class TestCase01(unittest.TestCase):
    def setUp(self)> None:
    # 打开chrome浏览器
    self.driver = webdriver.Chrome()
    def test_selectgoods(self):
        self.driver.get("http://47.107.116.139/shopnc/shop/")
        # 定位搜索输入
        el_select = self.driver.find_element(By.ID, "keyword")
        el_select.send_keys("手机")
        el_button = self.driver.find_element(By.ID, "button")
        el_button.click()
        time.sleep(2)
        # 断言:验证测试结果与预期结果是否一致
        # 获取商品列表的标题
        content = self.driver.find_element(By.XPATH, "//div[@class='goods‐name']/a").text
        print(content)
        # 判断content是否包含手机字符?
        # 常用断言方法
        """
        常用断言方法
        1、assertIn(字符1,字符2) 字符1是否包含在字符2
        2、self.assertNotIn(字符1,字符2) 字符1不包含包含在字符2
        self.assertEqual(参数1,参数2,"断言失败的描述") 参数1等于参数2
        self.assertNotEqual(参数1,参数2,"断言失败的描述")参数不等于参数2
        self.assertTrue(True)
        self.assertFalse(False)
        """
        # 标题是否包含手机
        self.assertIn("手机2222", content, "断言失败的描述")
        # 列表下有多少个商品 返回元素列表得到个数
        # count=els.count
        # self.assertEqual(count,1)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    4、报告的生成

    # -!- coding: utf-8 -!-
    import unittest
    import HTMLTestRunner
    from BeautifulReport import BeautifulReport
    
    from class01.test_02 import TestCase01
    
    testcase=unittest.TestLoader().loadTestsFromTestCase(TestCase01)
    # with open('./report/report.txt','w+')as f:
        # unittest自带的报告
        # unittest.TextTestRunner(stream=f,verbosity=2).run(testcase)
    
    
    #
    # with open('./report/report.html','wb+')as f:
    #     # htmlt自带的报告  2.3一下版本才能支持
    #     runner=HTMLTestRunner.HTMLTestRunner(stream=f,title="教育报告",description="描述")
    #     runner.run(testcase)
    
    
    # 生成BeautifulReport报告
    BeautifulReport(testcase).report(filename='百度测试报告', description='搜索测试', report_dir='.')    #log_path='.'把report放到当前目录下
    
    
    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    day3

    POM-页面对象模型

    POM page object model 页面对象模型 WEB自动化测试框架应用最为广泛的一种框架
    设计模式
    设计思路:web项目由很多页面组成,把每个页面当做页面对象来进行设计
    Python专题:什么是对象?通过类描述一组对象 对象=属性+方法
    码尚电商项目=n个页面=登录页面=对每个页面设计对应页面类=相同属性+相同的方法
    登录页面=对每个页面设计对应页面类=相同属性+相同的方法
    class LoginPage:
    #属性?元素、页面标题…
    #方法?你在页面进行操作/行为:点击、定位、输入…等等元素及页面的操作
    每个页面有相同的属性及方法 比如:点击、输入、元素定位
    基于POM进行设计分为四层进行架构:
    第一层 basepage 层 每个页面有相同的属性及方法 比如:点击、输入、元素定位
    第二层 pageobjects 层 针对每个页面定义页面类 每个页面有独有的属性及方法 登录页面 LoginPage类 注册页面 RegisterPage类
    第三层 TestCases层 用例层包含项目的业务流程
    第四层 TestData测试数据

    二、如何基于POM进行自动化框架架构?

    1、base层封装

    import time
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    class BasePage:
        """
        BasePage:定义每个页面的相同属性及方法
        相同属性?获取浏览器驱动对象(数据)
        相同方法?元素定位、点击、输入...等等操作
        """
        def __init__(self,driver=webdriver.Chrome()):
            self.driver=driver
        
        def locator(self,loc):
            """元素定位"""
            # loc=(By.LINK_TEXT,"登录"
            # WebElement对象
            return self.driver.find_element(*loc)
        
        def input(self,loc,value):
            """输入"""
            self.locator(loc).send_keys(value)
        
        def click(self,loc):
            """点击"""
            self.locator(loc).click()
        
        def sleep(self,s):
            time.sleep(s)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    2、pageobjects层封装

    import time
    
    from selenium.webdriver.common.by import By
    
    from class09.base.basepage import BasePage
    
    
    class LoginPage(BasePage):
        
        """
        登录页面类=页面独有的属性及方法
        页面独有的属性:页面元素定位
        方法:登录页面的操作
        """
        #登录页面的属性
        el_username=(By.ID,"user_name")
        el_password=(By.ID, "password")
        el_login=(By.XPATH, "//input[@name='Submit']")
        url="http://47.107.116.139/shopnc/shop/index.php?act=login&op=index"
    
        #方法
        def login(self,usname,passwd):
            #实现登录的步骤
            self.driver.get(self.url)
            self.sleep(2)
            # 输入用户名
            self.input(loc=self.el_username,value=usname)
            # 输入密码
            self.input(loc=self.el_password,value=passwd)
            # 点击登录
            self.click(loc=self.el_login)
            time.sleep(2)
    
    
    class GoodlistPage(BasePage):
    pass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    3 、TestCases层封装

    import unittest
    from class09.pageobjects.webpage import LoginPage
    
    class TestLogin(unittest.TestCase):
    def test_login(self):
        # 实例化对象
        loginpage=LoginPage()
        username = "xingyao"
        password = "mashang"
        loginpage.login(username,password)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    day4

    数据驱动:现在主流的设计模式之一(以数据驱动测试)

    结合unittest框架如何实现数据驱动?ddt模块实现
    数据驱动的意义:通过不同的数据对同一脚本实现循环测试,最终实现数据与脚本的分离
    ddt模块模块的安装 pip install ddt
    ddt模块:一个类装饰器+三个装饰器方法
    ddt类装饰器 装饰继承unittest.TestCase的类
    data装饰器方法 data()装饰器方法把列表、元组、字典作为参数
    unpack装饰器方法 实现把复杂的数据实现分解成多个数据
    file_data装饰器方法 可以直接接收数据文件(json数据/基于yaml数据文件),实现循环测试

    关键字驱动:现在主流的设计模式之一

    什么关键字驱动?(以关键字函数驱动测试)
    关键字驱动又叫动作字驱动
    把项目业务封装成关键字函数,再基于关键字函数实现自动化测试
    项目业务实现转化为关键字函数?
    覆盖项目业务=用例集合覆盖测试
    用例集合=一个一个用例实现覆盖测试
    覆盖用例=多个操作步骤组成=多个关键字函数
    操作步骤封装成对应的关键字函数
    比如:登录用例
    登录用例=多个操作步骤组成 基于每个操作步骤封装对应的关键字函数
    登录用例:
    1、打开浏览器 关键字函数open_browser()
    2、加载项目地址 关键字函数load_url()
    3、输入用户名 关键字函数 input()
    4、输入密码 关键字函数 input()
    5、点击登录 关键字函数 click()
    pom :把每个页面当做一个对象来进行编程 实现某个业务流程的测试=调用页面对象的一
    些属性及方法实现测试
    数据驱动:用外部数据驱动测试
    关键字驱动:所有业务流程封装成对应的函数 实现某个业务流程的测试=调用多个关键字
    方法,实现业务流程的测试 难点:封装什么样的关键字函数?

  • 相关阅读:
    vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
    JVM篇---第四篇
    Android 1.2 开发环境搭建
    Socks5代理IP与网络安全:保障HTTP通信的不可或缺工具
    在Ubuntu或linux中为coreutils工具包的cp和mv命令添加进度条
    学习typescript(1)
    CSS时间线样式
    等保主机测评防骗指南(资产调研)
    win32汇编源程序结构
    RESTFULL请求模式
  • 原文地址:https://blog.csdn.net/Leoon123/article/details/133955419