كيفية عدم تحرير اختبارات بايثون

وإخراج نتائج الاختبار خارج الكود. تتناول هذه المقالة الأتمتة وزيادة راحة الاختبار في Python.


صورة


تمهيدي


كان لدي مشروع قيد التطوير منذ عدة سنوات. لم تكن هناك اختبارات في المشروع. وأيضا لديه تبعيات نشطة على فرق أخرى ، مما أثر أيضا على النتيجة.


كان اختبار الانحدار أحد خطوات التطوير الأكثر ثقة. يكمن جوهرها في مقارنة البيانات المحسوبة مع آخر نتيجة طوباوية للبرنامج. 


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 :


...
def 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.



, . , . 


قد يكون من الضروري أيضًا إزالة العناصر المتغيرة باستمرار من البيانات مثل تاريخ التغيير الأخير. بحيث لا تخترق هذه التغييرات البيانات المخزنة.


استنتاج


كانت هذه نظرة عامة على اختبار وميزات مكتبة Python. سأكون سعيدا بالتعليقات والاقتراحات!


التثبيت: pip3 install testoot
التوثيق: https://testoot.readthedocs.io
كود المصدر: https://github.com/aptakhin/testoot


All Articles