PyTest管理UI自动化测试用例

一、 基本应用

1、如下代码是对日报的增加、查看、修改和删除:(文件名称:test_dailyreport.py)

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
'''
caseName:工作日报
'''
# import unittest
import pytest
from businessView.daily_report import DailyReportPage
from baseView.browser_view import Browser
from common.get_configInfo import get_config
from businessView.login import LoginView
from common.get_log import get_log
log = get_log()

save_data = [("2019-07-03", "测试数据01", "0")]
update_data = [("2019-07-01", "测试数据-修改", "0"), ]


class TestDailyReport(object):

    '''
    1、用fixture在所有用例开始前初始化测试对象、在所有用例结束后销毁测试对象
    2、yield是用于生成器,与return不同!所有用例执行完后,会执行yield后面的代码,
        无论用例是否执行成功,该代码都会执行(相当于teardown)
    3、在一个文件中,用例的执行顺序是从上到下的
    '''
    @pytest.fixture(scope="class")
    def init_dailyreport(self):
        # 打开浏览器和url
        browser = Browser()
        driver = browser.open_browser()

        # 登录(以下用例的前置条件一致,均需要登录,所以放到该方法中)
        username = get_config("accountInfo", "username")
        password = get_config("accountInfo", "password")

        lv = LoginView(driver)
        lv.login_action(username, password)
        lv.into_report_page()

        # 初始化工作日报界面类
        drp = DailyReportPage(driver)
        yield drp

        # 以下相当于teardown代码,不管用例执行成功与否,该代码都会执行,完美
        log.info("Close the browser.")
        # quit关闭浏览器后,会自动删除临时文件夹,不要用close
        driver.quit()

    '''
    1、用例调用fixture的返回值,直接把函数名称当做变量名称,比如:setup_teardown
    2、测试用例参数化用pytest.mark.parametrize,注意测试数据的格式
    3、pytest.mark.usefixtures只能用于没有返回值的fixture
    '''
    # 暂存日报用例
    @pytest.mark.parametrize("date,content,hours", save_data)
    def test_save(self, init_dailyreport, date, content, hours):

        log.info("******** 用例名称:暂存日报 ********")
        init_dailyreport.save(date, content, hours)

    @pytest.mark.add
    # 查看日报用例
    def test_check(self, init_dailyreport):
        log.info("******** 用例名称:查看日报 ********")
        init_dailyreport.check()

    # 修改日报用例
    @pytest.mark.parametrize("update_date, update_content, update_hours", update_data)
    def test_update(self, init_dailyreport, update_date, update_content, update_hours):
        log.info("******** 用例名称:修改日报 ********")
        init_dailyreport.update(update_date, update_content, update_hours)

    # 删除日报用例
    def test_delete(self, init_dailyreport):
        log.info("******** 用例名称:删除日报 ********")
        init_dailyreport.delete()


if __name__ == "__main__":

    # 运行该文件中所有用例
    pytest.main(['-s', "test_dailyreport.py"])

    # 运行单个用例
    # pytest.main(['-s', "test_dailyreport.py::TestDailyReport::test_save"])

    # 运行某些被标记的用例
    # pytest.main(['-s', "test_dailyreport.py", "-m=add"])

    # 运行某些未被标记的用例(除了标记为add之外的用例)
    # pytest.main(['-s', "test_dailyreport.py", "-m=not add"])

    # 该命令表示运行该文件所在路径下的所有测试文件
    # pytest.main()


2、fixture的应用:

  1)类似于unittest中的setUp和tearDown函数的应用,用来初始化测试对象和销毁测试对象;

  2)用scope来控制fixture的作用范围:

       class代表作用于该类中的所有用例。即该类中所有用例执行前和执行后;

       function代表每个用例执行前和执行后;

       还有module和session,使用时在网上查找使用方法即可

  3)其中yeild不同于return,yeidl返回了实例化的对象drp,供其他测试用例调用;

  4)yeild后面放置的代码相当于tearDown函数中代码,不管用例执行是否成功,在用例执行结束后均会执行该代码

3、用例调用fixture的返回值:直接把函数名作为参数和变量使用

4、使用pytest.mark.parametrize来管理测试用例数据,第一个参数是用例中参数列表,第二个参数是参数对应的值

5、运行用例的多种方式:

1)运行该文件中所有用例

pytest.main(['-s', "test_dailyreport.py"])

2)运行单个用例(类中的某个函数)

pytest.main(['-s', "test_dailyreport.py::TestDailyReport::test_save"])

3)用mark标记用例,并执行这些被标记的用例

pytest.main(['-s', "test_dailyreport.py", "-m=add"])
pytest.main(['-s', "test_dailyreport.py", "-m=check or add"])

4)执行除了被标记之外的其他用例

pytest.main(['-s', "test_dailyreport.py", "-m=not add"])

5)运行该文件所在路径下的所有测试文件,比如test_login.py与该文件在同一路径下,则如下命令会执行这两个文件中所有用例

pytest.main()

6、命名规则:

1)文件名:test_*.py或者*_test.py

2)类:Test开头

3)函数:test_开头

二、仅执行一次登录和退出操作

1、在测试用例所在的文件夹下新建文件conftest.py

import pytest
from baseView.browser_view import Browser
from businessView.login import LoginView
from common.get_configInfo import get_config
from common.get_log import get_log
log = get_log()


@pytest.fixture(scope="session")
def login():
    # 打开浏览器和url
    browser = Browser()
    driver = browser.open_browser()
    # 登录
    lv = LoginView(driver)
    username = get_config("accountInfo", "username")
    password = get_config("accountInfo", "password")
    lv.login_action(username, password)
    yield driver
    # 以下相当于teardown代码,不管用例执行成功与否,该代码都会执行
    # 关闭浏览器
    log.info("Close the browser.")
    driver.quit()

1)该文件用于编写多个测试用例文件的fixture功能。比如:我只想登录一次,执行多个界面的用例,则可以用到该文件

2)注意该文件中的函数的fixture范围为“session”,作用于所有测试用例文件

3)文件名称是固定的,且不需要导入该文件,pytest可自行找到

2、结合工作日报界面的用例文件:

'''
caseName:工作日报
'''
import pytest
import allure
from businessView.daily_report import DailyReportPage
from common.get_log import get_log
log = get_log()

save_data = [("2019-07-03", "测试数据01", "0")]
update_data = [("2019-07-01", "测试数据-修改", "0"), ]


@allure.feature('工作日报')
@pytest.mark.run(order=1)
class TestDailyReport(object):

    @pytest.fixture(scope="class")
    def init_dailyreport(self, login):
        # 初始化工作日报界面类
        drp = DailyReportPage(login)
        # 进入工作日报界面
        drp.into_report_page()
        yield drp
        drp.tab_close()

    @allure.story('暂存日报')
    @pytest.mark.flaky(reruns=3, reruns_delay=2)
    @pytest.mark.parametrize("date,content,hours", save_data)
    def test_save(self, init_dailyreport, date, content, hours):
        log.info("******** 用例名称:暂存日报 ********")
        init_dailyreport.daily_report_save(date, content, hours)
        assert init_dailyreport.dailyReport_check_save()

1)注意看init_dailyreport函数里面的参数“login”,就是取自文件conftest.py的函数名称(因为需要用到返回值)

2)测试用例中也可以设置fixture功能,用来初始化界面类

3)若想设置用例的执行顺序,则需要安装插件pytest-ordering,然后在用例类上添加@pytest.mark.run(order=1)

其中order的数值越小优先级越高

发布了26 篇原创文章 · 获赞 24 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/changyixue/article/details/96973043
今日推荐