pytest Capítulo 3 Accesorio y alcance

pytest Capítulo 3 Accesorio y alcance

Resumen: la configuración y el desmontaje actúan globalmente. Si diferentes casos en una clase de prueba tienen diferentes operaciones previas y posteriores, la configuración y el desmontaje no se pueden utilizar para resolver el problema. Por lo tanto, necesitamos personalizar las condiciones preestablecidas para las pruebas .

Ventajas de los accesorios.

Las ventajas de los accesorios incluyen lo siguiente:

  • El método de denominación es flexible y claro, y no se limita a la instalación/desmontaje.
  • Los dispositivos se implementan de forma modular, ya que cada nombre de dispositivo activa una llamada a la función del dispositivo, que a su vez puede usar otros dispositivos.
  • El intercambio de datos se puede lograr en el archivo conftest.py y algunas configuraciones se pueden encontrar automáticamente sin importar.
  • Permite parametrizar dispositivos y casos de prueba según la configuración y las opciones de componentes, o reutilizar el dispositivo dentro de un método/clase/módulo de prueba o durante una sesión de prueba.

Tres formas de convocar partidos

Tres formas de llamar a los partidos:

  1. La función o método de clase pasa directamente el nombre de la función del dispositivo como parámetro
  2. Utilice el decorador @pytest.mark.usefixtures()
  3. autouse=Verdadero usado automáticamente

El nombre de la función del aparato se utiliza como parámetro.

La función se registra como una función fija a través del decorador @pytest.fixture y el objeto devuelto por la función se puede pasar al método de prueba como parámetro.

import pytest
@pytest.fixture()
def get_a():
    print('\n执行fixture函数')

def test001(get_a):
    print('\n执行test001')
    assert True

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 1 item

test_b.py 
执行fixture函数

执行test001
.

============================== 1 passed in 0.01s ===============================

Como en el ejemplo anterior, la función fija get_a no tiene valor de retorno y se ejecuta primero después de pasarse a test001 como parámetro. La función de fijación puede tener un valor de retorno o no. Los accesorios permiten que los métodos de prueba introduzcan fácilmente funciones de preparación de inicialización predefinidas sin tener que preocuparse por los detalles de los métodos de importación/configuración/limpieza. Este es un excelente ejemplo de inyección de dependencia, donde la funcionalidad de la función de dispositivo actúa como un "inyector" y el método de prueba "consume" estos objetos de dispositivo.

autouse=Verdadero usado automáticamente

#test_b.py
import pytest
def test001():
    print('\n执行test001')

def test002():
    print('\n执行test002')

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])
    
#conftest.py
import pytest
@pytest.fixture(scope="function",autouse=True)
def get_a():
    a=1
    print('\n执行fixture函数>>>>>>>>get_a(function)')
    return a

@pytest.fixture(scope="module",autouse=True)
def get_b():
    b=2
    print('\n执行fixture函数>>>>>>>>get_b(module)')
    return b

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数>>>>>>>>get_b(module)

执行fixture函数>>>>>>>>get_a(function)

执行test001
.
执行fixture函数>>>>>>>>get_a(function)

执行test002
.

============================== 2 passed in 0.01s ===============================

Como se muestra en el ejemplo anterior, después de que la función del dispositivo usa autouse=True, el caso de prueba se puede usar automáticamente sin pasar el nombre de la función del dispositivo.

Desventajas: actualmente esto no puede hacer frente a la situación en la que el caso de prueba necesita llamar a la función de fijación para devolver el valor.

Utilice el decorador @pytest.mark.usefixtures()

Puedes usar el decorador **@pytest.mark.usefixtures()**

#test_b.py
import pytest
@pytest.mark.usefixtures('get_b')
@pytest.mark.usefixtures('get_a')
def test001():
    print('\n执行test001')

@pytest.mark.usefixtures('get_a')
def test002():
    print('\n执行test002')

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

#conftest.py
import pytest
@pytest.fixture(scope="function")
def get_a(request):
    a=1
    print('\n执行fixture函数>>>>>>>>get_a(function)')
    return a

@pytest.fixture(scope="module")
def get_b(request):
    b=2
    print('\n执行fixture函数>>>>>>>>get_b(module)')
    return b

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数>>>>>>>>get_b(module)

执行fixture函数>>>>>>>>get_a(function)

执行test001
.
执行fixture函数>>>>>>>>get_a(function)

执行test002
.

============================== 2 passed in 0.01s ===============================

rango efectivo del dispositivo

El dispositivo utiliza el parámetro de alcance para indicar 4 alcances efectivos:

  • función (predeterminada): se llamará cada función o método
  • clase: llamado una vez para cada clase
  • módulo: llamado una vez por archivo py
  • sesión: llamada a través de archivos py, llamada una vez en una ejecución

El alcance es sesión>módulo>clase>función

Vea los ejemplos a continuación:

función

import pytest
@pytest.fixture(scope="class")
def get_a():
    a=1
    print('\n执行fixture函数')
    return a

def test001(get_a):
    print('\n执行test001')
    print("获取a:%d" % get_a)
    assert True

def test002(get_a):
    print('\n执行test002')
    print("获取a:%d" % get_a)
    assert True

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数

执行test001
获取a:1
.
执行fixture函数

执行test002
获取a:1
.

============================== 2 passed in 0.01s ===============================

función: si la función pasa la función de dispositivo como parámetro, la función de dispositivo se ejecuta una vez antes de la función. No se ejecutará si no se pasa y no se ejecutará si se pasa en el método, solo actúa sobre la función y es una función del mismo archivo py.

clase

import pytest
@pytest.fixture(scope="class")
def get_a():
    a=1
    print('\n执行fixture函数')
    return a

class TestCase:
    def test001(self,get_a):
        print('\n执行test001')
        print("获取a:%d" % get_a)
        assert True

    def test002(self,get_a):
        print('\n执行test002')
        print("获取a:%d" % get_a)
        assert True

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数

执行test001
获取a:1
.
执行test002
获取a:1
.

============================== 2 passed in 0.02s ===============================

clase: todos los métodos de la clase pasan la función de fijación, y la función de fijación se ejecuta una vez al comienzo de la clase.

import pytest
@pytest.fixture(scope="class")
def get_a():
    a=1
    print('\n执行fixture函数')
    return a

class TestCase:
    def test001(self):
        print('\n执行test001')
        assert True

    def test002(self,get_a):
        print('\n执行test002')
        print("获取a:%d" % get_a)
        assert True

    def test003(self):
        print('\n执行test003')
        assert True

    def test004(self,get_a):
        print('\n执行test004')
        print("获取a:%d" % get_a)
        assert True

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 4 items

test_b.py 
执行test001
.
执行fixture函数

执行test002
获取a:1
.
执行test003
.
执行test004
获取a:1
.

============================== 4 passed in 0.02s ===============================

clase: si la función de fijación no se pasa a todos los métodos de la clase, se ejecutará una vez antes de que se ejecute el primer método pasado a la función de fijación y no se ejecutará antes que los otros métodos. (Es decir, independientemente de si se pasan uno o más métodos a la función de dispositivo, la función de dispositivo solo se ejecutará una vez en una clase, antes de que se ejecute el primer método pasado a la función de dispositivo ).

Pase la función de fijación con el alcance de la clase en la función. La función de fijación es equivalente a la función de alcance. Consulte el siguiente ejemplo.

import pytest
@pytest.fixture(scope="class")
def get_a():
    a=1
    print('\n执行fixture函数')
    return a

def test000(get_a):
    print('\n执行test000')

def test0000(get_a):
    print('\n执行test0000')

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数

执行test000
.
执行fixture函数

执行test0000
.

============================== 2 passed in 0.01s ===============================

módulo

import pytest
@pytest.fixture(scope="module")
def get_a():
    a=1
    print('\n执行fixture函数')
    return a

def test001(get_a):
    print('\n执行test001')
    print("获取a:%d" % get_a)
    assert True

class TestCase:
    def test005(self,get_a):
        print('\n执行test005')
        print("获取a:%d" % get_a)
        assert True

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数

执行test001
获取a:1
.
执行test005
获取a:1
.

============================== 2 passed in 0.01s ===============================

módulo: puede actuar sobre funciones y métodos en un archivo py. Solo se ejecuta una vez en un archivo py, antes de que se ejecute la primera función o método pasado a la función de fijación.

sesión

#test_b.py
def test001(get_a):
    print('\n执行test001')

class TestCase:
    def test002(self,get_a):
        print('\n执行test001')
        
#test_c.py
def test003(get_a):
    print('\n执行test003')

class TestCase1:
    def test004(self, get_a):
        print('\n执行test004')
        
#conftest.py
import pytest
@pytest.fixture(scope="session")
def get_a():
    a=1
    print('\n执行fixture函数')
    return a

Resultados de:

=========================================================== test session starts ============================================================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 4 items                                                                                                                          

test_b.py 
执行fixture函数

执行test001
.
执行test001
.
test_c.py 
执行fixture函数

执行test003
.
执行test004
.

============================================================ 4 passed in 0.03s ========================================================

sesión: solo se ejecuta una vez en una ejecución de pytest. Se ejecuta antes de que se ejecute el primer método o función pasado a la función de fijación. Debe usarse junto con el archivo conftest.py y se puede ejecutar en archivos py.

Ámbito de uso mixto

#test_b.py
def test001(get_a):
    print('\n执行test001')

class TestCase:
    def test002(self,get_b):
        print('\n执行test002')
        
#test_c.py
def test003(get_d):
    print('\n执行test003')

class TestCase1:
    def test004(self, get_c):
        print('\n执行test004')
        
#conftest.py
import pytest
@pytest.fixture(scope="session")
def get_a():
    a=1
    print('\n执行fixture函数>>>>>>>>get_a(session)')
    return a

@pytest.fixture(scope="module")
def get_b():
    b=2
    print('\n执行fixture函数>>>>>>>>get_b(module)')
    return b

@pytest.fixture(scope="class")
def get_c():
    c=3
    print('\n执行fixture函数>>>>>>>>get_c(class)')
    return c

@pytest.fixture(scope="function")
def get_d():
    d=4
    print('\n执行fixture函数>>>>>>>>get_d(function)')
    return d

resultados de ejecución de pytest:

=========================================================== test session starts ============================================================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 4 items                                                                                                                          

test_b.py 
执行fixture函数>>>>>>>>get_a(session)

执行test001
.
执行fixture函数>>>>>>>>get_b(module)

执行test002
.
test_c.py 
执行fixture函数>>>>>>>>get_d(function)

执行test003
.
执行fixture函数>>>>>>>>get_c(class)

执行test004
.

============================================================ 4 passed in 0.02s =============================================================

Como se muestra en el ejemplo, get_a>test001>get_b>test002>get_d>test003>get_c>test004

Sólo las funciones de dispositivos a nivel de clase tendrán efectos a nivel de función en funciones fuera de la clase. Consulte el siguiente ejemplo.

#test_b.py
import pytest
def test001(get_a):
    print('\n执行test001')

def test002(get_a):
    print('\n执行test002')

class TestCase:
    def test003(self,get_a):
        print('\n执行test003')

    def test004(self,get_a):
        print('\n执行test003')

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])
    
#conftest.py
import pytest
@pytest.fixture(scope="class")
def get_a():
    a=1
    print('\n执行fixture函数>>>>>>>>get_a(class)')
    return a

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 4 items

test_b.py 
执行fixture函数>>>>>>>>get_a(class)

执行test001
.
执行fixture函数>>>>>>>>get_a(class)

执行test002
.
执行fixture函数>>>>>>>>get_a(class)

执行test003
.
执行test003
.

============================== 4 passed in 0.01s ===============================

Como se muestra en el ejemplo anterior, la función de fijación a nivel de clase get_a se ejecuta antes de cada método fuera de la clase, pero las funciones de fijación a nivel de sesión y de módulo no tienen este efecto.

Llamarse entre funciones de dispositivo

Las funciones de los dispositivos pueden llamarse entre sí.

#test_b.py
import pytest
def test001(get_a):
    print(get_a)
    print('\n执行test001')

def test002(get_a):
    print(get_a)
    print('\n执行test002')

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

#conftest.py
import pytest
@pytest.fixture(scope="class")
def get_a(get_b):
    a=get_b+2
    print('\n执行fixture函数>>>>>>>>get_a(class)')
    return a

@pytest.fixture(scope="class")
def get_b():
    b=2
    print('\n执行fixture函数>>>>>>>>get_b(class)')
    return b

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数>>>>>>>>get_b(class)

执行fixture函数>>>>>>>>get_a(class)
4

执行test001
.
执行fixture函数>>>>>>>>get_b(class)

执行fixture函数>>>>>>>>get_a(class)
4

执行test002
.

============================== 2 passed in 0.01s ===============================

Al igual que las funciones de dispositivo get_a y get_b en el ejemplo, get_b se pasa a get_a como parámetro.

Cabe señalar que las funciones de los dispositivos que se llaman entre sí deben seguir las siguientes reglas:

  1. El alcance de la función del dispositivo como parámetro debe ser mayor o igual que la función del dispositivo principal. Por ejemplo, en el ejemplo anterior, el alcance de get_b debe ser mayor que get_a; de lo contrario, se producirá un error de que no se puede acceder a la función de fijación.
  2. El alcance de la función del dispositivo como parámetro es mayor que la función del dispositivo principal. Si la función del dispositivo principal se llama por caso, la función del dispositivo como parámetro aún tiene efecto de acuerdo con su propio alcance. Vea el ejemplo a continuación.
#test_b.py
import pytest
def test001(get_a):
    print(get_a)
    print('\n执行test001')

def test002(get_a):
    print(get_a)
    print('\n执行test002')

if __name__ == '__main__':
    pytest.main(['-s','test_b.py'])

#conftest.py
import pytest
@pytest.fixture(scope="function")
def get_a(get_b):
    a=get_b+2
    print('\n执行fixture函数>>>>>>>>get_a(function)')
    return a

@pytest.fixture(scope="module")
def get_b():
    b=2
    print('\n执行fixture函数>>>>>>>>get_b(module)')
    return b

resultados de ejecución de pytest:

============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: /Users/zy/PycharmProjects/learnpytest
collected 2 items

test_b.py 
执行fixture函数>>>>>>>>get_b(module)

执行fixture函数>>>>>>>>get_a(function)
4

执行test001
.
执行fixture函数>>>>>>>>get_a(function)
4

执行test002
.

============================== 2 passed in 0.01s ===============================

Supongo que te gusta

Origin blog.csdn.net/u011090984/article/details/122131018
Recomendado
Clasificación