Модуль модульного тестирования записи в Python - PullRequest
1 голос
/ 12 января 2010

Я пишу оболочку для ConfigParser в Python, чтобы обеспечить простой интерфейс для хранения и получения настроек приложения.

Оболочка имеет два метода, read и write, и набор свойств для различных настроек приложения.

Метод write - это просто оболочка для метода ConfigParser 'write с добавлением также создания объекта файла, необходимого для ConfigParser. Это выглядит так:

def write(self):
    f = open(self.path, "w")
    try:
        self.config_parser.write(f)
    finally:
        f.close()

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

Второй тест довольно легко выполнить с помощью фиктивного объекта. Но вызов open делает все немного сложнее. В конце концов мне нужно создать объект файла для передачи в парсер конфигурации. Тот факт, что файл будет фактически создан при запуске этого кода, не делает его очень полезным для модульного теста. Есть ли какая-то стратегия создания файла-макета? Можно ли каким-то образом протестировать этот кусок кода? Или это слишком просто для тестирования?

Ответы [ 3 ]

6 голосов
/ 12 января 2010

Во-первых, вам на самом деле не нужно юнит-тестирование open(), поскольку вполне разумно предположить, что стандартная библиотека верна.

Далее, вы не хотите манипулировать файловой системой, чтобы получить open(), чтобы сгенерировать нужную ошибку, потому что тогда вы не юнит-тестирование, вы проводите функциональный / интеграционный тест, включая файловую систему. .

Таким образом, вы можете заменить open() в глобальном пространстве имен на суррогат, который просто вызывает IOError. Хотя, возможно, нужно убедиться, что вы положили вещи обратно, если выполнение продолжается.

Но, в конце концов, какое значение имеет тест? В этом фрагменте кода так мало вашей собственной системы. Даже замена open() на самом деле просто оказывается тестом, который говорит «работает ли оператор try и finally в Python?»

Мое предложение? Просто добавьте заявление в строку документации, которая записывает ваши ожидания. «Вызывает IOError, если файл не может быть записан». Тогда двигайся дальше. Вы можете добавить модульный тест позже, если этот метод приобретает некоторую сложность (и достоинства для тестирования).

4 голосов
/ 12 января 2010

На самом деле, только open может вызвать исключение в вашем коде. Документы для write () ничего не говорят об исключениях. Возможно, только ValueError или что-то для плохого указателя файла (в результате сбоя открытия, что не может быть здесь).

Сделать IOError для open легко. Просто создайте файл в другом месте и откройте его для записи там. Или вы можете изменить разрешения для этого, чтобы у вас не было доступа.

Вы, возможно, захотите использовать здесь выражение with, и оно само обработает закрытие.

В Python 2.5 вам нужна первая строка. В более поздних версиях это вам не нужно.

from __future__ import with_statement # python 2.5 only

def write(self):
    with open(self.path, 'w') as f:
        self.config_parser.write(f)

Метод записи гарантированно будет вызван, если open завершится успешно, и не будет вызван, если open вызовет IOError. Я не знаю, зачем вам нужен тест, чтобы узнать, была ли вызвана запись. Код говорит, что это так. Не переусердствуйте с тестированием. ;)

2 голосов
/ 12 января 2010

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

Тем не менее, модульные тесты - не единственный мой инструмент, и эта функция достаточно проста для анализа и «доказать» & dagger; , что она работает.

& dagger; Менее строго, чем хотелось бы математикам, я уверен, но достаточно хорошо для меня.

...