Как изменяются юнит-тесты, когда базовый класс вытесняется? - PullRequest
8 голосов
/ 11 апреля 2011

Это отчасти продолжение этого вопроса .

Я не уверен, что это лучший способ задать этот вопрос, поэтому я попробую небольшой рассказ, чтобы установить сцену:

Когда-то существовал класс «А», у которого был класс модульного тестирования «ATests», отвечающий за тестирование его поведения через открытый интерфейс.Некоторое время они жили счастливо вместе, а затем произошло изменение, и появился класс «В», который, как оказалось, имел много общего с классом «А», поэтому был введен базовый класс.

Публичное поведение базового класса уже охвачено тестами для класса A. Итак, вопрос в том, что будет дальше?

• Нужно ли классу B иметь тесты для общего (поведение базового класса)?Кажется, что поведение является частью B, поэтому его следует протестировать, но должны ли эти тесты использоваться совместно с тестами для класса A?Для базового класса?Если да, какой лучший способ поделиться?

• Нужны ли модульные тесты новому базовому классу, или это нормально для базовых классов, которые будут проверены с помощью тестов их детей?Имеет ли значение, является ли базовый класс абстрактным?

• Достаточно ли того, чтобы классы A и B были производными от базового класса и «доверяли» модульным тестам базового класса для проверки общего поведения (тактесты не должны быть воспроизведены в дочерних классах)?Тесты для A & B должны только проверять их новое / измененное поведение?

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

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

Ответы [ 3 ]

4 голосов
/ 11 апреля 2011

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

Обратите внимание на часть «данного времени». Если время является проблемой (и это всегда так), тестирование базового класса или унаследованных функций, вероятно, будет иметь более низкий приоритет. Но тестирование - это отличная прививка против вас, и она делает вас более уверенным при последующем рефакторинге, так что вы только сокращаете себя, своих клиентов и / или ваших сопровождающих, не предоставляя настолько полный охват, сколько у вас есть время.

Однако вполне приемлемо закладывать такие повторяющиеся вещи на специальных тестировщиков или команду QA, если они у вас есть. Но иногда покупайте им пиво :-) Они заставляют вас выглядеть лучше!

3 голосов
/ 11 апреля 2011

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

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

0 голосов
/ 11 апреля 2011

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

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

Затем производные классы будут тестировать оставшиеся открытые методы в своем собственном наборе тестов.

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

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