C贸mo no editar pruebas de Python

Y saque los resultados de la prueba fuera del c贸digo. Este art铆culo trata sobre la automatizaci贸n y el aumento de la comodidad de las pruebas en Python.


imagen


Introductorio


Ten铆a un proyecto que ha estado en desarrollo durante varios a帽os. No hubo pruebas en el proyecto. Y tambi茅n ten铆a dependencias activas de otros equipos, lo que tambi茅n influy贸 en el resultado.


La prueba de regresi贸n fue uno de los pasos para un desarrollo m谩s seguro. Su esencia est谩 en comparar los datos calculados con el 煤ltimo resultado canonizado del programa. 


python . .


:


  • . , Python xml, json . , textwrap.dedent.
  • . .
  • . , . . .


, . testoot 3.4+.


.  .


foo . :


def foo():
    return {'a': 1}

def test_simple(testoot: Testoot):
    testoot.test(foo())

pytest:


pytest -s tests

. . testoot Testoot .


:


def foo():
    return {'a': 2}

def test_simple(testoot: Testoot):
    testoot.test(foo())

AssertionError :


...鈥╠ef test_simple(testoot: Testoot):
>       testoot.test(foo()))

cls = <class 'testoot.ext.pytest.PytestComparator'>, test_obj = {'a': 2}, canon_obj = {'a': 1}

    @classmethod
    def compare(cls, test_obj: any, canon_obj: any):
        """Compares objects"""
>       assert test_obj == canon_obj
E       AssertionError


. - .


--canonize.


pytest -s tests --canonize

, pytest ( --verbose ):


tests/test_console/test_console.py [tests/test_console/test_console.py::test_simple]
{'a': 2} == {'a': 1}
~Differing items:
~{'a': 2} != {'a': 1}
~Use -v to get the full diff
Canonize [yn]? y
.

. .


. : 


  • pickle. Python. VCS pickle
  • bytes. , .
  • str. utf-8 , .
  • json . json, , .

, VCS .


. .


def test_filename(testoot: Testoot):
    d = Path(testoot.storage.root_dir / 'hello.json')
    d.write_text('{}')

    testoot.test_filename(str(d))


Testoot. :


import pytest

from testoot.ext.pytest import PytestContext
from testoot.ext.simple import DefaultBaseTestoot
from testoot.pub import AskCanonizePolicy, PickleSerializer, \
    LocalDirectoryStorage, ConsoleUserInteraction, Testoot

@pytest.fixture(scope='module')
def base_testoot():
    regress = DefaultBaseTestoot(
        storage=LocalDirectoryStorage('.testoot'),
    )
    regress.storage.ensure_exists()
    yield regress

@pytest.fixture(scope='function')
def testoot(base_testoot, request):
    fixture = Testoot(base_testoot, PytestContext(request))
    yield fixture

DefaultBaseTestoot . Testoot (scope='function'). pytest request , .


DefaultBaseTestoot BaseTestoot -: .testoot pickle-, --canonize.


-:


regress = DefaultBaseTestoot(
    serializer=JsonSerializer(),
)

. pytest :


class PytestComparator(Comparator):
    @classmethod
    def compare(cls, test_obj: any, canon_obj: any):
        """Compares objects"""
        assert test_obj == canon_obj

PytestContext(request, serializer=BinarySerializer(), comparator=PytestComparator()). :


def test_str(testoot: Testoot):
    result = 'abc'
    regress.test(result, serializer=StringSerializer(), comparator=PytestComparator())

, BaseTestoot.



, . , . 


Tambi茅n puede ser necesario eliminar elementos que cambian constantemente de los datos, como la fecha del 煤ltimo cambio. Para que tales cambios no penetren los datos almacenados.


Conclusi贸n


Esta fue una descripci贸n general de las pruebas y caracter铆sticas de la biblioteca para Python. Estar茅 encantado de comentarios y sugerencias!


Instalaci贸n: pip3 install testoot
Documentaci贸n: https://testoot.readthedocs.io
C贸digo fuente: https://github.com/aptakhin/testoot


All Articles