Я тестирую класс, который ничего не делает? - PullRequest
4 голосов
/ 14 июля 2009

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

class DummyLog(object):
    def insert_master_log(self, spec_name, file_name, data_source,
                          environment_name):
        pass
    def update_master_log(self, inserts, updates, failures, total):
        pass

С одной стороны, я, вероятно, должен был бы отпустить это, а не тестировать, так как на самом деле нет никакого кода для тестирования. Но потом, мой «инфицированный тестом» инстинкт говорит мне, что это оправдание и что простота класса означает, что я должен быть больше готов проверить его. У меня просто не получается подумать, что тестировать.

Есть идеи? Или я должен просто отпустить это и не писать никаких тестов?

Ответы [ 15 ]

12 голосов
/ 15 июля 2009

Если вы не будете тестировать, как вы узнаете, что это ничего не значит? :)

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

4 голосов
/ 15 июля 2009

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

На практике это означает:

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

Не запускать этот тест на DummyLog; используйте его как общий тест и запустите на всех регистраторах. Когда вы добавите другой метод в настоящий класс Log через год и забудете добавить его в DummyLog, тест заметит. (Конечно, если вы не забыли добавить общий тест для метода, но, надеюсь, добавление теста должно быть привычным, даже если вы забудете о связанных классах.)

4 голосов
/ 15 июля 2009

Если не получится. Нечего проверять.

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

3 голосов
/ 15 июля 2009

Будьте прагматичны, здесь нечего проверять.

2 голосов
/ 15 июля 2009

Очевидно, он что-то делает, иначе вы бы этого не написали.

Я собираюсь догадаться, что он предназначен для отражения интерфейса вашего реального класса журналирования. Итак, проверьте, что он имеет тот же интерфейс, что он принимает те же аргументы. Вы, вероятно, измените свою регистрацию, забыв обновить манекен. Если это кажется избыточным, ЭТО ЕСТЬ, потому что они, вероятно, должны просто наследоваться от одного и того же интерфейса.

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

2 голосов
/ 15 июля 2009

Если кому-то интересно, вот тест, который я закончил писать:

def test_dummy_loader():
    from loader_logs import DummyLog
    from copy import copy
    dummy = DummyLog()
    initial = copy(dummy.__dict__)
    dummy.insert_master_log('', '', '', '')
    dummy.update_master_log(0, 0, 0, 0)
    post = copy(dummy.__dict__)
    assert initial == post

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

2 голосов
/ 15 июля 2009

Зависит от вашей теории.

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

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

1 голос
/ 15 июля 2009

Этот DummyLogger - это то, что в шаблоне дизайна называется «Нулевой объект». Подкласс вашего реального Logger от этого, создайте некоторый тест для реального Logger и затем используйте тот же тест, но с DummyLogger.

class TestLogger(unittest.TestCase):
   def setUp(self):
       self.logger = RealLogger()
   def test_log_debug ..
   def test_log_error ..

class TestNullLogger(TestLogger):
   def setUp(self): 
       self.logger = DummyLogger()

Но, как многие предполагали, тебе это не понадобится. Когда он тормозит, исправьте его.

1 голос
/ 15 июля 2009

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

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

1 голос
/ 15 июля 2009

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

Вы никогда не знаете, что кто-то может отредактировать класс в будущем и заставить его выбросить исключение или что-то странное!

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

Тем не менее, было бы катастрофически, если бы этот класс бросил исключение? Я предполагаю, что это будет одна из тех ошибок, которые без юнит-теста будут обнаружены только в поле.

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