Pytest, где хранить данные

функция тестирования мне нужно передать параметры и увидеть результат совпадает с ожидаемым.

легко, когда ответ функции - это просто небольшой массив или однострочная строка, которая может быть определена внутри тестовой функции, но предположим, что функция I test изменяет файл конфигурации, который может быть огромным. Или результирующий массив имеет длину 4 строки, если я определяю его явно. Где я храню, чтобы мои тесты оставались чистыми и простыми в обслуживании?

прямо сейчас, если это строка, я просто положил файл рядом с

3 ответов


у меня была аналогичная проблема однажды, когда я должен протестировать файл конфигурации против ожидаемого файла. Вот как я это исправил:

  1. создайте папку с тем же именем вашего тестового модуля и в том же месте. Поместите все ваши ожидаемые файлы в эту папку.

    test_foo/
        expected_config_1.ini
        expected_config_2.ini
    test_foo.py
    
  2. создайте приспособление, ответственное за перемещение содержимого этой папки во временный файл. Я использовал tmpdir приспособление для этого вопрос.

    from __future__ import unicode_literals
    from distutils import dir_util
    from pytest import fixture
    import os
    
    
    @fixture
    def datadir(tmpdir, request):
        '''
        Fixture responsible for searching a folder with the same name of test
        module and, if available, moving all contents to a temporary directory so
        tests can use them freely.
        '''
        filename = request.module.__file__
        test_dir, _ = os.path.splitext(filename)
    
        if os.path.isdir(test_dir):
            dir_util.copy_tree(test_dir, bytes(tmpdir))
    
        return tmpdir
    
  3. использовать новое приспособление.

    def test_foo(datadir):
        expected_config_1 = datadir.join('expected_config_1.ini')
        expected_config_2 = datadir.join('expected_config_2.ini')
    

помните: datadir аналогично tmpdir крепеж, плюс возможность работы с предполагаемое файлы, помещенные в папку с именем test модуль.


Если у вас есть только несколько тестов, то почему бы не включить данные в качестве строкового литерала:

expected_data = """
Your data here...
"""

Если у вас есть несколько, или ожидаемые данные действительно длинные, я думаю, что ваше использование светильников имеет смысл.

однако, если у вас много, то, возможно, другое решение было бы лучше. Фактически, для одного проекта у меня есть более ста входных и ожидаемых выходных файлов. Поэтому я построил свою собственную структуру тестирования (более или менее). Я использовал нос, но PyTest также будет работать. Я создал генератор тестов, который прошелся по каталогу тестовых файлов. Для каждого входного файла был получен тест, который сравнивал фактический вывод с ожидаемым (PyTest называет его настройка). Затем я задокументировал свою структуру, чтобы другие могли ее использовать. Чтобы просмотреть и/или отредактировать тесты, вы редактируете только входные и / или ожидаемые выходные файлы и никогда не просматриваете тестовый файл python. Чтобы разрешить различным входным файлам иметь разные параметры, я также создал YAML файл конфигурации для каждого каталога (JSON также будет работать, чтобы сохранить зависимости). Данные YAML состоят из словаря, где каждый ключ-это имя входного файла, а значение-словарь ключевых слов, которые будут переданы тестируемой функции вместе с входным файлом. Если вам интересно, вот исходный код и документация. Недавно я играл с идеей определения параметров как Unittests здесь (требуется только встроенный unittest lib), но я не уверен, что мне это нравится.


подумайте, действительно ли нужно протестировать все содержимое файла конфигурации.

Если необходимо проверить только несколько значений или подстрок, подготовьте ожидаемый шаблон для этой конфигурации. Тестируемые места будут помечены как "переменные" с некоторым специальным синтаксисом. Затем подготовьте отдельный ожидаемый список значений для переменных в шаблоне. Ожидается, что этот список может быть сохранен как отдельный файл или непосредственно в исходном коде.

пример шаблон:

ALLOWED_HOSTS = ['{host}']
DEBUG = {debug}
DEFAULT_FROM_EMAIL = '{email}'

здесь переменные шаблона помещаются внутри фигурных скобок.

ожидаемые значения могут выглядеть так:

host = www.example.com
debug = False
email = webmaster@example.com

или даже в виде простого списка, разделенного запятыми:

www.example.com, False, webmaster@example.com

затем ваш тестовый код может создать ожидаемый файл из шаблона, заменив переменные ожидаемыми значениями. И ожидаемый файл сравнивается с фактическим.

сохранение шаблона и ожидаемых значений отдельно имеет и преимущество, что вы можете иметь много наборов данных тестирования, используя один и тот же шаблон.

тестирование только переменные

еще лучший подход заключается в том, что метод генерации конфигурации создает только необходимые значения для файла конфигурации. Эти значения могут быть легко вставлены в шаблон другим методом. Но преимущество в том, что тестовый код может напрямую сравнивать все переменные конфигурации отдельно и в clear путь.

Шаблоны

хотя в шаблоне легко заменить переменные необходимыми значениями, есть готовые библиотеки шаблонов, которые позволяют делать это только в одной строке. Вот лишь несколько примеров:Джанго, Джимма, Мако