python3.x中 pytest之fixture

一、fixture与setup、teardown的作用差异。

1、一句话: setup、teardown能干的事情,fixture也能干,而且还能干的更得心应手。至于为啥,咱们细看:

  。fixture 命名方式灵活,不局限于setup和teardown这几个命名;

  。fixture 所在的配置文件conftest.py(这个文件名是固定的)配置里可以实现数据共享,不需要import就能自动找到一些配置;

  。fixture 中的参数之一 scope="module"可以实现多个.py跨文件共享前置;

  。fixyure 中的参数之一 scope="session"以实现多个.py跨文件使用一个session来完成多个用例;

  。fixture 通过配置文件设置后,可以定制化的为各个用例服务,默认是 function 级别,每个用例都用到

 

二、关于fixture中参数的解释。

  fixture(scope="function", params=None, autouse=False, ids=None, name=None)-----这是源码中的内容

  。scope="function: scope参数有四个级别参数:"function"(默认)、"class"、"module"、"session" ;

  。params=None   : 一个非必须的参数,它将导致多个参数调用fixture功能和所有测试使用它,默认为None;

  。autouse=False  :为True时,则为所有测试激活fixture func,为False(默认值),则显式需要参考来激活fixture;

  。 ids=None    : 每个字符串id的列表,每个字符串对应于params,这样他们就是测试ID的一部分,如果没有提供ID它们将从params自动生成;

  。name=None      :fixture的名称,这默认为装饰函数的名称。如果fixture在定义它的同一模块中使用,夹具的功能名称将被请求夹具的功能arg遮蔽;将装饰函数命名"fixture_<fixturename>",然后使用"@pytest.fixture(name='<fixturename>')"

 

三、fixture中主要参数传参场景

1、当 scope="function" 时:

。使用场景:用例1需要先登录,用例2不需要登录,用例3需要先登录

-------测试代码

 

import pytest

# 不带参数时默认scope="function"
@pytest.fixture()
def login():
        print("输入账号,密码先登录")

def test_s1(login):
        print('用例1:需要先登录,才能进行其他操作')

def test_s2():  # 不传login
        print('用例2:不需要登录,就可以进行其他操作')

def test_s3(login):
        print('用例3:需要先登录,才能进行其他操作')

if __name__ == "__main__":
        pytest.main()

 

------- 测试结果

 

@pytest.fixture()中为空,即表示默认scope="function" ,后边在需要用到fixture的用例在执行前,都调用了它。

2、scope="module" 时:

。当scope="module"时,module作用是整个.py文件(模块)都会生效,用例调用时,参数写上函数名称就行

 

------- 测试代码:

 

import pytest

# scope="module" 时。
@pytest.fixture(scope="module")
def open():
        print("打开被测系统首页")

def test_s1():
        print("然后被执行用例1")

def test_s2(open):
        print("然后被执行用例2")

def test_s3(open):
        print("然后被执行用例3")

if __name__ == "__main__":
        pytest.main()

 

-------测试结果:

 

在整个用例文件中,它只在第一个用例调用它之前执行了一次,后边的调用都没有执行。并且,只有在调用的时候才执行。

 3、scope="session" 时:

             (往下看)

4、fixture 作为公共文件,不同用例文件调用时:

当出现这个情况时,则 conftest.py 配置文件就要闪亮登场了。

使用场景:有一个万年不变的登录接口,有一个封装好的待测接口文件,还有一个封装好的用例文件(可能说法上不是很准确,先这样喊吧!!),以共享session为例说明。

用例场景:登录 ------修改银行卡信息-----查询商品列表------添加商品品牌

因为后边三个接口都是需要在登录后的环境下操作,所以就把登录的接口独立出来到fixture中去。

--------先明确关于conftest.py文件的一点--------

  。 conftest.py 这个文件名称是固定的,不能改,改了就报错

  。conftest.py 有且只有两种存在位置,一是和需要执行的用例在同一个package中,二是在需要执行的用例的父级目录中。

主目录结构:

conftest.py 文件内容:

import pytest
import requests
from test_B.B10_test_1 import login,update_bank,select_shangp,add_make

@pytest.fixture(scope="session")
def login_fixture():
    print("必须要先输入密码登录后才可以执行的用例")
    s = requests.session()
    login(s)
    return s

@pytest.fixture(scope="session")
def nologin_fixture():
    print("不用登录的后就可以执行的用例")
    s = requests.session()
    return s

用例文件:

import requests
from test_B.B10_test_1 import login,update_bank,select_shangp,add_make


def test_get_info(login_fixture):
    '''
    所有的用例都是正常场景下的
    :return:
    '''
    s = login_fixture
    banking = update_bank(s,accountName="小虎子啊")    # 修改
    shangp = select_shangp(s)  # 查询
    assert banking["message"]=="操作成功。"
    assert shangp["message"]=="操作成功。"

def test_get_info_1(login_fixture):
    '''
    部分用例是异常场景下的
    :return:
    '''
    s = login_fixture
    banking = update_bank(s,accountName="")    # 修改
    shangp = select_shangp(s)  # 查询
    assert banking["message"]=="开户名称不能为空\n"
    assert shangp["message"]=="操作成功。"


def test_get_make(login_fixture):
    '''
    所有的用例都是异常场景下的
    :return:
    '''
    s = login_fixture
    addmake = add_make(s,makename="九匹狼")
    assert addmake["message"]=="品牌名称不能重复"

接口文件:

import requests


def login(s,userName="14687513290",password="123456"):
    url = "http://1.17.11.3:180/webapi/login"
    body = {
            "userName":userName,
            "password":password
            }
    r = s.post(url=url,json=body)
    token = r.json()["data"]["token"]
    header = {
            "Content-Type": "application/json",
            "Authorization": "%s"%token
        }
    s.headers.update(header)

def update_bank(s,accountName="小虎子"):
    url = "http://1.17.11.3:180/webapi/user/updateBankinfo"
    body = {
            "bankName":"青海银行",
            "bankAccount":"6228480020668298217",
            "accountName":accountName,
            "bankCode":"313851000018"
        }
    r = s.post(url=url,json=body)
    return r.json()

def select_shangp(s):
    url = "http://1.17.11.3:180/webapi/v1/product/list"
    body = {
            "pageIndex":0,
            "pageSize":2,
            "categoryId":-1,
            "ctegoryParentId":-1,
            "ownerId":"100208"
        }
    r = s.post(url=url,json=body)
    return r.json()

def add_make(s,makename="八匹狼"):
    url = "http://1.17.11.3:180/webapi/brand/add"
    body = {"name":makename}
    r = s.post(url=url,json=body)
    return r.json()

if __name__ == '__main__':
    s = requests.session()
    login(s)
    banking = update_bank(s,accountName="小虎子啊")
    shangp = select_shangp(s)
    add_make(s,makename="八匹狼")

执行结果:

 

可以看到,session实现了多个文件共享。而且通过conftest.py配置文件实现了登录操作的跨文件共享

 

 

 

 

  

 

posted @ 2020-04-22 15:26  漂泊的小虎  阅读(561)  评论(0编辑  收藏  举报