Модификации файла модульного тестирования

Обычной задачей в программах, над которыми я работал в последнее время, является изменение текстового файла каким-либо образом. (Привет, я нахожусь в Linux. Все - файл. И я делаю крупномасштабного системного администратора.)

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

Я читал о модульном тестировании в Dive Into Python, и довольно ясно, что я хочу делать при тестировании приложения, которое преобразует десятичные числа в римские цифры (пример в DintoP). Тестирование прекрасно автономно. Вам не нужно проверять, что программа ПЕЧАТАЕТ правильную вещь, вам просто нужно убедиться, что функции возвращают правильный вывод на заданный вход.

В моем случае, однако, мы должны проверить, что программа корректно изменяет свою среду. Вот что я придумала:

1) Создайте «оригинал» файл в стандартном месте, возможно / tmp.

2) Запустите функцию, которая модифицирует файл, передав ему путь к файлу в / tmp.

3) Убедитесь, что файл в / tmp был изменен правильно; пройти / не пройти модульное тестирование соответственно.

Это кажется мне клёвым. (Становится еще круче, если вы хотите убедиться, что резервные копии файла созданы правильно и т. Д.) Кто-нибудь придумал лучший способ?

Ответы на вопрос(6)

которые просто хотят, чтобы способ проверки того, что запись кода в файлы работает правильно, есть & quot; fake_open & quot; это исправляет открытую встроенную часть модуля для использования StringIO. fake_open возвращает подсказку об открытых файлах, которые можно проверить в модульном тесте или doctest, и все это без необходимости использования реальной файловой системы.

def fake_open(module):
    """Patch module's `open` builtin so that it returns StringIOs instead of
    creating real files, which is useful for testing. Returns a dict that maps
    opened file names to StringIO objects."""
    from contextlib import closing
    from StringIO import StringIO
    streams = {}
    def fakeopen(filename,mode):
        stream = StringIO()
        stream.close = lambda: None
        streams[filename] = stream
        return closing(stream)
    module.open = fakeopen
    return streams

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

Я сделал это в Java, и я думаю, что это довольно просто в Python ... но это может потребовать разработки ваших классов / функций таким образом, чтобы было легко смоделировать использование реального файла.

Для этого вы можете попробовать передать потоки, а затем просто передать простой поток ввода-вывода, который не будет записывать в файл, или иметь функцию, которая действительно записывает эту строку в файл & quot; или "прочитать эту строку из файла", а затем заменить эту функцию в своих тестах.

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

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

Если это не сработает, вы можете написать свои сценарии, чтобы получить «root». путь в качестве аргумента.

В производственном запуске корневой путь - это просто /. Для тестирования вы создаете теневую среду в / tmp / test, а затем запускаете свои сценарии с корневым путем / tmp / test.

Filtering and Modifying content. These are "low-level" operations that don't really require physical file I/O. These are the tests, decision-making, alternatives, etc. The "Logic" of the application.

File system operations. Create, copy, rename, delete, backup. Sorry, but those are proper file system operations that -- well -- require a proper file system for testing.

Для этого вида тестирования мы часто используем «Mock». объект. Вы можете создать & quot; FileSystemOperations & quot; класс, который воплощает различные операции файловой системы. Вы проверяете это, чтобы убедиться, что оно выполняет базовое чтение, запись, копирование, переименование и т. Д. В этом нет никакой реальной логики. Просто методы, которые вызывают операции файловой системы.

Затем вы можете создать MockFileSystem, которая выводит различные операции. Вы можете использовать этот объект Mock для проверки других ваших классов.

В некоторых случаях все операции вашей файловой системы выполняются в модуле os. Если это так, вы можете создать модуль MockOS с фиктивной версией операций, которые вы фактически используете.

Поместите свой модуль MockOS наPYTHONPATH и вы можете скрыть настоящий модуль ОС.

Для производственных операций вы используете свою хорошо проверенную «Логику» классы плюс ваш класс FileSystemOperations (или настоящий модуль ОС)

Решение Вопроса

ся атаковать проблему тестирования, сказав «Давайте проверим, что она корректно изменяет свою среду», вы обречены на неудачу. У окружающей среды есть десятки, возможно даже миллионы потенциальных изменений.

Вместо этого посмотрите на части («единицы») вашей программы. Например, вы собираетесь иметь функцию, которая определяет, где находятся файлы, которые должны быть записаны? Каковы входы для этой функции? Возможно переменная окружения, возможно, некоторые значения читаются из файла конфигурации? Протестируйте эту функцию и на самом деле не делайте ничего, что изменяет файловую систему. Не передавайте это "реалистично" значения, передайте ему значения, которые легко проверить. Создайте временный каталог, заполните его файлами в своем тесте.setUp метод.

Затем проверьте код, который пишет файлы. Просто убедитесь, что он пишет правильное содержимое файла содержимого. Даже не пишите в настоящую файловую систему! Вам не нужно делать "подделку" для этого нужно просто использовать удобные PythonStringIO модули; они «настоящие» реализации "файла" интерфейс, они просто не те, в которые ваша программа будет писать.

В конечном итоге вам придется протестировать финальную функцию верхнего уровня "все на самом деле подключено к реальному", которая передает переменную реальной среды и файл конфигурации и собирает все вместе. Но не беспокойтесь об этом, чтобы начать. Во-первых, вы начнете подбирать трюки, когда будете писать отдельные тесты для небольших функций, и создание тестовых макетов, подделок и заглушек станет для вас второй натурой. С другой стороны: даже если вы не можете понять, как проверить этот вызов одной функции, у вас будет очень высокий уровень уверенности в том, что все, что она вызывает, работает отлично. Кроме того, вы заметите, что разработка, основанная на тестировании, заставляет вас делать свои API более понятными и гибкими. Например, гораздо проще протестировать то, что вызываетopen() метод на объекте, который пришел откуда-то абстрактно, чем тестировать то, что вызываетos.open на строку, которую вы передаете его.open метод является гибким; это может быть подделка, это может быть реализовано по-другому, но строка является строкой иos.open не дает вам никакой возможности узнать, какие методы вызываются на нем.

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

Ваш ответ на вопрос