zoukankan      html  css  js  c++  java
  • 36 web自动化实战二 pytest用例筛选 断言 生成测试报告 数据驱动

    79节

    目录

    1.pytest 筛选用例

    2.pytest的断言 assert

    3.测试报告

    4.pytest用例执行顺序

    5.数据驱动

    1.pytest 筛选用例:标记功能

    1).标签打在整个测试类上面

    举例,在上面的登录测试用例的测试类上面加标签:@pytest.mark.login

    ①在pytest.ini文件中加上标签名:login

    ②在TestLogin类上面加@pytest.mark.login

    ③terminal中运行 pytest -m "login"

    代码实现:

    """登录功能的测试用例"""
    
    import unittest
    import pytest
    from middware.handler import HandlerMiddle
    from config.config import Wait_time
    
    @pytest.mark.login
    class TestLogin(unittest.TestCase):
        """登录功能的测试类"""
        @pytest.mark.error
        def test_login_error(self):
            """登录失败测试步骤
            1.打开浏览器
            2.访问登录页面
            3.元素定位+元素操作,输入用户名和密码,点击登录
            4.通过获取页面内容得到实际结果,进行断言
            :return:
            """
    
            from selenium import webdriver
    
            #1.打开浏览器
            driver = webdriver.Chrome()
            #设置隐性等待 等待的时间就可以放在config中,直接参数调用
            ##方法一:放在yaml中
            wait_time = HandlerMiddle.yaml_data["selenium"]["wait_time"]
            ##方法二、放在config.py中
            #wait_time = Wait_time
            driver.implicitly_wait(wait_time)
    
            #2.访问登录页面
            url = "http://120.78.128.25:8765/Index/login.html"
            driver.get(url)
    
            #3.元素定位+元素操作,输入用户名和密码,点击登录
            driver.find_element_by_name("phone").send_keys("") #定位输入手机号为空
            driver.find_element_by_name("password").send_keys("")#定位输入的密码为空
            driver.find_element_by_class_name("btn-special").click()
    
            #4.通过获取页面内容得到实际结果,进行断言
            #实际结果是在页面上的提示,再次进行定位
            actual_result = driver.find_element_by_class_name("form-error-info").text
    
            #断言
            self.assertTrue(actual_result == "请输入手机号")
    
    
        # @pytest.mark.success
        def test_login_success(self):
            """登录成功测试用例
            1.打开浏览器
            2.访问登录页面
            3.元素定位+元素操作,输入用户名和密码,点击登录
            4.通过获取页面内容得到实际结果,进行断言
            :return:
            """
            from selenium import webdriver
            #1.打开浏览器
            driver = webdriver.Chrome()
    
            #设置隐性等待时间
            wait_time  = HandlerMiddle.yaml_data["selenium"]["wait_time"]
            driver.implicitly_wait(wait_time)
    
            #2.访问登录页面
            url="http://120.78.128.25:8765/Index/login.html"
            driver.get(url)
    
            #3.元素定位+元素操作,输入用户名和密码,点击登录
            driver.find_element_by_name("phone").send_keys("15*********")
            driver.find_element_by_name("password").send_keys("15")
            driver.find_element_by_class_name("btn-special").click()
    
            #4.获取实际结果,进行断言
            actual_result = driver.find_element_by_xpath("//a[@href='/Member/index.html']").text
            print(type(actual_result))
            self.assertTrue("我的帐户[小蜜蜂177872141]" in actual_result)

    运行结果:

     2).标记功能组合------不同的testcase的py文件中,可以同时运行多个

    语法1.:

    pytest -m "register_error or success" -------只需要满足一个条件就可以运行(可以组合2个或者2个以上)

    pytest -m "register_error and success" -------2个条件同事满足才可以运行(可以组合2个或者2个以上)

    pytest -m "register_error and not success" -------2个条件同事满足才可以运行(可以组合2个或者2个以上),取非

    举例:运行test_register.py中的register_error,或者test_login中的success

    首先别忘记在ini文件中注册tagname

    代码实现:

    test_register.py:

    import unittest
    import pytest
    
    
    class TestRegister(unittest.TestCase):
        """注册功能的测试类"""
        @pytest.mark.register_error
        def test_register_error(self):
            pass

    test_login.py:

    """登录功能的测试用例"""
    
    import unittest
    import pytest
    from middware.handler import HandlerMiddle
    from config.config import Wait_time
    
    @pytest.mark.login
    class TestLogin(unittest.TestCase):
        """登录功能的测试类"""
        @pytest.mark.error
        def test_login_error(self):
            """登录失败测试步骤
            1.打开浏览器
            2.访问登录页面
            3.元素定位+元素操作,输入用户名和密码,点击登录
            4.通过获取页面内容得到实际结果,进行断言
            :return:
            """
    
            from selenium import webdriver
    
            #1.打开浏览器
            driver = webdriver.Chrome()
            #设置隐性等待 等待的时间就可以放在config中,直接参数调用
            ##方法一:放在yaml中
            wait_time = HandlerMiddle.yaml_data["selenium"]["wait_time"]
            ##方法二、放在config.py中
            #wait_time = Wait_time
            driver.implicitly_wait(wait_time)
    
            #2.访问登录页面
            url = "http://120.78.128.25:8765/Index/login.html"
            driver.get(url)
    
            #3.元素定位+元素操作,输入用户名和密码,点击登录
            driver.find_element_by_name("phone").send_keys("") #定位输入手机号为空
            driver.find_element_by_name("password").send_keys("")#定位输入的密码为空
            driver.find_element_by_class_name("btn-special").click()
    
            #4.通过获取页面内容得到实际结果,进行断言
            #实际结果是在页面上的提示,再次进行定位
            actual_result = driver.find_element_by_class_name("form-error-info").text
    
            #断言
            self.assertTrue(actual_result == "请输入手机号")

    运行pytest -m "register_error or success",结果:

    3)标记功能组合---------一个函数或者类上面,可以加多个标签

    例1: 标签组合and

    代码如下:

    """登录功能的测试用例"""
    
    import unittest
    import pytest
    from middware.handler import HandlerMiddle
    from config.config import Wait_time
    
    @pytest.mark.login
    class TestLogin(unittest.TestCase):
        """登录功能的测试类"""

    @pytest.mark.smoke @pytest.mark.error def test_login_error(self): """登录失败测试步骤 1.打开浏览器 2.访问登录页面 3.元素定位+元素操作,输入用户名和密码,点击登录 4.通过获取页面内容得到实际结果,进行断言 :return: """ from selenium import webdriver 。 。 。 。

    运行:pytest -m "login and smoke" ,类标签有2个方法,但是and smoke,表示只筛选类里面的标记为smoke的方法。、

    结果:

    例2: 标签组合 not

    运行TestLogin这个类下面的success的方法(success方法没有打标签)

    运行:pytest -m "login and not smoke"

    或者pytest -m "login and not error"

    import unittest
    import pytest
    from middware.handler import HandlerMiddle
    from config.config import Wait_time
    
    @pytest.mark.login
    class TestLogin(unittest.TestCase):
        """登录功能的测试类"""

    @pytest.mark.smoke @pytest.mark.error def test_login_error(self): """登录失败测试步骤 1.打开浏览器 2.访问登录页面 3.元素定位+元素操作,输入用户名和密码,点击登录 4.通过获取页面内容得到实际结果,进行断言 :return: """ from selenium import webdriver #1.打开浏览器 driver = webdriver.Chrome() #设置隐性等待 等待的时间就可以放在config中,直接参数调用 ##方法一:放在yaml中 wait_time = HandlerMiddle.yaml_data["selenium"]["wait_time"] ##方法二、放在config.py中 #wait_time = Wait_time driver.implicitly_wait(wait_time) #2.访问登录页面 url = "http://120.78.128.25:8765/Index/login.html" driver.get(url) #3.元素定位+元素操作,输入用户名和密码,点击登录 driver.find_element_by_name("phone").send_keys("") #定位输入手机号为空 driver.find_element_by_name("password").send_keys("")#定位输入的密码为空 driver.find_element_by_class_name("btn-special").click() #4.通过获取页面内容得到实际结果,进行断言 #实际结果是在页面上的提示,再次进行定位 actual_result = driver.find_element_by_class_name("form-error-info").text #断言 self.assertTrue(actual_result == "请输入手机号") def test_login_success(self): """登录成功测试用例 1.打开浏览器 2.访问登录页面 3.元素定位+元素操作,输入用户名和密码,点击登录 4.通过获取页面内容得到实际结果,进行断言 :return: """ from selenium import webdriver #1.打开浏览器 driver = webdriver.Chrome() #设置隐性等待时间 wait_time = HandlerMiddle.yaml_data["selenium"]["wait_time"] driver.implicitly_wait(wait_time) #2.访问登录页面 url="http://120.78.128.25:8765/Index/login.html" driver.get(url) #3.元素定位+元素操作,输入用户名和密码,点击登录 driver.find_element_by_name("phone").send_keys("15********") driver.find_element_by_name("password").send_keys("15") driver.find_element_by_class_name("btn-special").click() #4.获取实际结果,进行断言 actual_result = driver.find_element_by_xpath("//a[@href='/Member/index.html']").text print(type(actual_result)) self.assertTrue("我的帐户[小蜜蜂177872141]" in actual_result)

    注意:用例标记的时候,标签如果有逻辑运算,一定要加双引号。

    2.pytest的断言 assert

    背景:上篇博客中有提到,pytest是可以脱离类存在的,所以单个函数的断言,是用不了self.assertTrue

    1).pytest 的断言直接用assert即可

       assert 3>2、assert 4=4 这样表述即可。

    3.测试报告

    1).安装HTML的测试报告  pip install pytest-html

    2).运行结果生成报告:pytest -m "login and not error" --html=report.html

       即可在项目下生成测试报告。

    3).测试报告生成时间戳:脚本运行pytest

      ①在run.py文件中,以pytest.main()形式运行用例。

      首先看下main()方法的源码:参数表示:列表形式的命令行参数;插件暂时用不到,先不看

     run.py如下:

    "运行测试用例"
    import pytest
    
    if __name__ == '__main__':
        pytest.main(["--html=report1.html"])

    下面将测试报告加上时间戳:

    ①import datatime

    ②ts = datatime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")

    run.py实现:

    "运行测试用例"
    import pytest
    import datetime
    ts = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
    
    if __name__ == '__main__':
        pytest.main(["--html={}report.html".format(ts)])

    4.pytest用例执行顺序

    类里面的用例方法:从上到下,运行(简单来说,想让哪个用例先运行,就把用例写在前面)

    5.数据驱动  79节45min

    首先,回顾下,如果用unittest框架去测试,代码如下:

    """登录功能的测试用例"""
    import ddt
    import unittest
    import pytest
    from middware.handler import HandlerMiddle
    from config.config import Wait_time
    
    data = HandlerMiddle.excel.read_data("login")
    
    @ddt.ddt
    class TestLogin(unittest.TestCase):
        """登录功能的测试类"""
        
        @ddt.data(*data)
        def test_login_error(self,test_info):
            """登录失败测试步骤
            1.打开浏览器
            2.访问登录页面
            3.元素定位+元素操作,输入用户名和密码,点击登录
            4.通过获取页面内容得到实际结果,进行断言
            :return:
            """
    
            from selenium import webdriver
    
            #1.打开浏览器
            driver = webdriver.Chrome()
            #设置隐性等待 等待的时间就可以放在config中,直接参数调用
            ##方法一:放在yaml中
            wait_time = HandlerMiddle.yaml_data["selenium"]["wait_time"]
            ##方法二、放在config.py中
            #wait_time = Wait_time
            driver.implicitly_wait(wait_time)
    
            #2.访问登录页面
            url = "http://120.78.128.25:8765/Index/login.html"
            driver.get(url)
    
            #3.元素定位+元素操作,输入用户名和密码,点击登录
            driver.find_element_by_name("phone").send_keys(eval(test_info["data"])["username"])
            driver.find_element_by_name("password").send_keys(eval(test_info["data"])["password"])
            driver.find_element_by_class_name("btn-special").click()
    
            #4.通过获取页面内容得到实际结果,进行断言
            #实际结果是在页面上的提示,再次进行定位
            actual_result = driver.find_element_by_class_name("form-error-info").text
            expected_result = test_info["expected_result"]
            #断言
            self.assertTrue(actual_result == expected_result)

    通过pytest用例筛选运行error用例,读取web_excel.xlsx中的2条用例(一条通过,一条不通过),run,py代码如下:

    "运行测试用例"
    import pytest
    import datetime
    ts = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
    
    if __name__ == '__main__':
        pytest.main(["--html={}report.html".format(ts), "-m error"])

    用unittest框架(使用筛选用例)的数据驱动,运行通过。

    下面用pytest的数据驱动完成测试:

    pytest数据驱动的语法:

    ① 在用例的方法上添加:@pytest.mark.parametrize("test_info",data)      data表示 列表表示的数据

    ② 用例方法中添加参数test_info

    注:pytest中,类上面不需要加任何东西(因为它可能没有类)

           pytest中,parametrize中的第一个参数“test_info” 跟函数中的参数名称必须是一致的------->(def test_login_error(self,test_info):)

    完成上面的操作后,还有需要跟unittest区分的是:不能继承unittest.TestCase,断言就不能用self.assertTrue了

    代码实现如下:

    """登录功能的测试用例"""
    
    import pytest
    from middware.handler import HandlerMiddle
    from config.config import Wait_time
    
    data = HandlerMiddle.excel.read_data("login")
    
    @pytest.mark.login
    class TestLogin():
        """登录功能的测试类"""
        @pytest.mark.smoke
        @pytest.mark.error
        @pytest.mark.parametrize("test_info",data)
        def test_login_error(self,test_info):
            """登录失败测试步骤
            1.打开浏览器
            2.访问登录页面
            3.元素定位+元素操作,输入用户名和密码,点击登录
            4.通过获取页面内容得到实际结果,进行断言
            :return:
            """
    
            from selenium import webdriver
    
            #1.打开浏览器
            driver = webdriver.Chrome()
            #设置隐性等待 等待的时间就可以放在config中,直接参数调用
            ##方法一:放在yaml中
            wait_time = HandlerMiddle.yaml_data["selenium"]["wait_time"]
            ##方法二、放在config.py中
            #wait_time = Wait_time
            driver.implicitly_wait(wait_time)
    
            #2.访问登录页面
            url = "http://120.78.128.25:8765/Index/login.html"
            driver.get(url)
    
            #3.元素定位+元素操作,输入用户名和密码,点击登录
            driver.find_element_by_name("phone").send_keys(eval(test_info["data"])["username"]) #定位输入手机号为空
            driver.find_element_by_name("password").send_keys(eval(test_info["data"])["password"])#定位输入的密码为空
            driver.find_element_by_class_name("btn-special").click()
    
            #4.通过获取页面内容得到实际结果,进行断言
            #实际结果是在页面上的提示,再次进行定位
            actual_result = driver.find_element_by_class_name("form-error-info").text
            expected_result = test_info["expected_result"]
            

         #断言 assert actual_result == expected_result

    运行上面的run.py,测试通过。

    数据驱动注意事项:

    ①在使用@pytest.mark.parametrize("test_info",data)做数据驱动时,pytest和unittest不兼容,即,如果想使用pytest的数据驱动,就不能继承unittest.TestCase,并修改断言

    ②如果用unittest写用例,就需要用 unittest 的数据驱动。(类 继承unittest.TestCase;添加ddt

    总结来说:pytest不跟unittest兼容的是:数据驱动parametrize,测试夹具fixture,hook

    只要用上面的三个,pytest和unittest 就是不兼容。

  • 相关阅读:
    闲来无事研究研究.Net中的异步编程
    Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理
    c# 连接Redis报错:WRONGTYPE Operation against a key holding the wrong kind of value:类型搞混弄出的错误
    VS2013 调试时出现“表达式计算器中发生内部错误”的问题解决办法
    WCF优化的几个常规思路
    UWP汉堡菜单
    C#注册系统全局快捷键
    CXF详细介绍
    hadoop默认3个核心配置文件说明
    在虚拟机配置hive
  • 原文地址:https://www.cnblogs.com/ananmy/p/13557420.html
Copyright © 2011-2022 走看看