当前位置:网站首页>pytest 之 fixture的调用

pytest 之 fixture的调用

2022-08-09 13:06:00 沉觞流年

fixture的调用

将fixture函数名称,作为用例的参数

只返回前置中的一个参数

首先,定义一个函数,作为前置和后置使用,前置要完成的任务是打开浏览器,打开百度网页,后置的作用是退出浏览器。
然后,定义一个函数,充当测试用例的使用,打开百度进行搜索,而这个用例中,需要用到前置条件中的内容,也就是说,前置中的driver ,要作为参数进行传递,供用例使用
pytest 是通过关键字 yield进行返回前置中的driver

import pytest
from selenium import webdriver

@pytest.fixture()
def func_init():
    print("此处是用例的前置,作用于函数")
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    yield driver
    print("此处是用例的后置,作用于函数")
    driver.quit()


@pytest.mark.usefixtures("func_init")
class TestDemo:

    def test_answer(self,func_init):
        print("通过百度进行搜索")
        func_init.find_element_by_id("kw").send_keys("python")

        pass

test_answer 函数中,func_init 作为参数传递,其实 func_init 就相当于driver的作用。

 func_init.find_element_by_id("kw").send_keys("python")
 相当于
 driver.find_element_by_id("kw").send_keys("python")

在终端输入命令 pytest -s -v,可以发现,用例执行了,调用了前置和后置里的内容
在这里插入图片描述

pytest中的使用极为灵活,将fixture函数名称,作为用例的参数进行调用,此时测试用例中,可以不加 @pytest.mark.usefixtures(“func_init”) 标识,也能调用前置和后置里返回值的内容
这是pytest的搜索机制,pytest会默认在当前文件所属路径下去寻找func_init这个函数,去调用前置和后置里的内容

import pytest
from selenium import webdriver

@pytest.fixture()
def func_init():
    print("此处是用例的前置,作用于函数")
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    yield driver
    print("此处是用例的后置,作用于函数")
    driver.quit()



class TestDemo:

    def test_answer(self,func_init):
        print("通过百度进行搜索")
        func_init.find_element_by_id("kw").send_keys("python")

        pass

这种方式是用例中要用到前置中的返回值,是一定要进行传参的,过程就是将fixture函数名称,作为用例的参数进行调用。

注意: 如果前置中没有返回值,或者说用例中不需要去调用前置里的返回值,那用例要使用前置和后置里的内容,就必须加上 @pytest.mark.usefixtures(“func_init”) 标识
且此时测试用例中不能再将fixture函数名称作为用例的参数进行调用,因为yield中没有返回内容
不过这种方式使用的不常见

import pytest
from selenium import webdriver

@pytest.fixture()
def func_init():
    print("此处是用例的前置,作用于函数")
    yield 
    print("此处是用例的后置,作用于函数")
    


@pytest.mark.usefixtures("func_init")
class TestDemo:

    def test_answer(self):
    	driver = webdriver.Chrome()
    	driver.get("http://www.baidu.com")
        print("通过百度进行搜索")
        driver.find_element_by_id("kw").send_keys("python")

        pass

返回前置中的多个参数

import pytest
from selenium import webdriver

@pytest.fixture()
def func_init():
    print("此处是用例的前置,作用于函数")
    driver1 = webdriver.Chrome()
    driver1.get("http://wwwcn.bing.com")
    driver2 = webdriver.Chrome()
    driver2.get("http://www.baidu.com")
    yield driver1,driver2
    print("此处是用例的后置,作用于函数")
    driver.quit()


@pytest.mark.usefixtures("func_init")
class TestDemo:

    def test_answer(self,func_init):
        print("通过百度进行搜索")
        func_init[1].find_element_by_id("kw").send_keys("python")

        pass

yield可以返回前置中的多个参数,而返回多个参数的时候,是将这多个变量以元组的形式进行传参的

此时返回了 driver1driver2 两个参数,用例中需要调用driver2,所以,也就是需要用到 func_init 身上第二个参数

fixture的共享机制

一般情况下,多个用例会有相同的前置和后置的内容,所以,这些前置和后置的内容,可以将其独立出来

fixture的查找机制是,先在当前py文件查找是否有前置和后置的内容;
如果没有,再去当前py文件所属文件夹下查找 conftest文件(该文件的名称是固定的,是pytest的查找规则),查找是否有前置和后置的内容;
如果再没有,就再次往上级目录查找(不会超过项目根目录)

在这里插入图片描述
例如,假设 TestCases 是项目根目录,该目录下有 conftest 文件和 demo 文件夹,demo 文件夹下有 conftest 文件 和 test_demo1.py 文件

test_demo1.py

import pytest
from selenium import webdriver

@pytest.fixture()
def func_init():
    print("此处是用例的前置,作用于函数")
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    yield driver
    print("此处是用例的后置,作用于函数")
    driver.quit()


@pytest.mark.usefixtures("func_init")
class TestDemo:

    def test_answer(self,func_init):
        print("通过百度进行搜索")
        func_init.find_element_by_id("kw").send_keys("python")

        pass

test_demo1.py 文件中定义了一个名为 func_init 的fixture函数,执行 test_answer 用例,会先在 当前的 test_demo1.py 文件下查找 名为 func_init 的fixture函数,调用其中前置和后置的内容。

而如果当前的 test_demo1.py 文件下没有名为 func_init 的fixture函数,就会在demo 文件夹下查找是否有有 conftest 文件 ,查找 名为 func_init 的fixture函。以此类推

conftest.py

import pytest
from selenium import webdriver

@pytest.fixture()
def func_init():
    print("此处是用例的前置,作用于函数")
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    yield driver
    print("此处是用例的后置,作用于函数")
    driver.quit()

定义多个层级的conftest,一般不推荐这种方式,在测试用例TeseCases目录下定义一个即可,可以通过定义不同名称的fixture函数进行区分,这样调用不同的fixture函数,也就调用了不同的前置和后置的内容

fixture的嵌入调用

不同的测试用例,有着不同的前置和后置的内容。也就是说我们需要定义不同的fixture函数,在fixture函数中去定义不同的前置和后置。
但是有些fixture函数中有着相同的前置和后置内容,为了减少代码量,可以通过定义fixture函数去调用不同fixture函数中的前置和后置内容(可以简单的理解为继承)

test_demo2.py

import pytest
from selenium import webdriver


@pytest.fixture()
def init():
    print("此处是init方法的前置,作用于函数")

    yield
    print("此处是init方法的后置,作用于函数")


@pytest.fixture()
def func_init(init):
	print("此处是func_init方法的前置,作用于函数")
    driver = webdriver.Chrome()
    driver.get("http://www.baidu.com")
    yield driver

    driver.quit()
    print("此处是func_init方法的后置,作用于函数")

@pytest.mark.usefixtures("func_init")
class TestDemo:

    def test_answer(self,func_init):
        print("通过百度进行搜索")
        func_init.find_element_by_id("kw").send_keys("python")

        pass

这里,func_init fixture函数 将 init fixture函数 的函数名作为参数传入,调用了init fixture函数中前置和后置的内容

在这里插入图片描述

这个例子的比较烂,其实和上面 test_demo1.py 执行的效果是差不多的,主要是说明 fixture函数的之间的调用

上面两个 fixture函数级别都是 function 级别的,同级别的 fixture函数可以调用,低级别的 fixture函数可以调用高级别的 fixture函数。
function 级别的 fixture函数可以调用class 级别的fixture函数; class 级别的fixture函数可以调用 module 级别的fixture函数;
module 级别的fixture函数可以调用 session 级别的fixture函数。
但是高级别的 fixture函数不能调用低级别的 fixture函数。

原网站

版权声明
本文为[沉觞流年]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_44614026/article/details/114648400