2013-09-23 3 views
39

Должны ли вы тестировать простые свойства класса, утверждая, что значение задано и получено? Или это действительно просто модульное тестирование языка?Должны ли вы испытывать простые свойства?

Пример

public string ConnectionString { get; set; } 

Тест

public void TestConnectionString() 
{ 
    var c = new MyClass(); 
    c.ConnectionString = "value"; 

    Assert.Equal(c.ConnectionString, "value"); 
} 

Я предполагаю, что я не вижу значение в этом.

+12

Кажется совершенно бессмысленным для меня. –

+1

Если бы вы делали что-то другое, кроме как просто устанавливали его, я бы сказал «да». Но то, что вы делаете, бессмысленно. – gleng

+4

Рассмотрите красивую и чистую статью Марка Симана [Тестовый тривиальный код] (http://blog.ploeh.dk/2013/03/08/test-trivial-code/) –

ответ

37

Я бы предположил, что вам абсолютно необходимо.

  • Что такое автоматическое свойство сегодня может в конечном итоге, поле подложки поставил против него завтра, а не ты ...

  • Аргумент, что «вы просто тестирования компилятора или основа "- это немного солома imho; то, что вы делаете, когда вы проверяете авто-свойство, с точки зрения вызывающего, тестирует публичный «интерфейс» вашего класса. Вызывающий не имеет понятия, является ли это свойством auto с созданным фреймворком хранилищем или если в геттере/сеттере имеется миллион строк сложного кода. Поэтому вызывающий абонент тестирует договор , который подразумевает свойство, - что если вы положите X в коробку, вы можете получить X позже.

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

  • Испытание, подобное этому, может потребоваться через минуту, чтобы написать, так что это не совсем обременительно; и вы можете легко создать шаблон T4, который будет автоматически генерировать эти тесты для вас с небольшим отражением. Я на самом деле работаю над таким инструментом на данный момент, чтобы спасти нашу команду. Некоторые из них:

  • Если вы делаете чистую TDD, это заставляет вас остановиться на мгновение и подумать о том, лучше всего сделать (подсказка: это часто не)

  • не Хотели бы вы иметь тест авансовые регрессии, так что, когда FNG делает что-то вроде этого:


//24-SEP-2013::FNG - put backing field for ConnectionString as we're now doing constructor injection of it 
public string ConnectionString 
{ 
    {get { return _connectionString; } } 
    {set {_connectionString="foo"; } }//FNG: I'll change this later on, I'm in a hurry 
} 

///snip 

public MyDBClass(string connectionString) 
{ 
    ConnectionString=connectionString; 
} 

Вы мгновенно знаете, что они что-то сломали?

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

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

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

EDIT: в соответствии с различными разговоры на эту тему, я хотел бы отметить, что тест на свойство чтения-записи до смешного прост:

[TestMethod] 
public void PropertyFoo_StoresCorrectly() 
{ 
    var sut = new MyClass(); 
    sut.Foo = "hello"; 
    Assert.AreEqual("hello", sut.Foo, "Oops..."); 
} 

редактировать: И вы даже можете сделать это в одна строка в соответствии с маркой Seeman's Autofixture

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

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

редактировать (опять!): Как было отмечено в комментариях, и это правильно, такие вещи, как сгенерированных моделей DTO и тому подобное, вероятно, исключения к вышесказанному, потому что они просто тупые старые ведра для сдвига данных где-то еще, плюс, поскольку инструмент создал их, обычно их бессмысленно тестировать.

/EDIT

+2

Было бы очень приятно, если бы люди с downvoting оставили бы какой-то комментарий относительно того, почему им не понравился принятый ответ ... –

+0

Я собираюсь сделать некоторые предположения здесь по возможным причинам, но реальная проблема, с которой вы столкнулись мало что касалось модульного тестирования. Если вы позволите такой ошибке перейти на репо, а не на корабль к клиенту, никакое количество тестов не поможет. Если такое происходит, это проблема процесса ** ** - отсутствие (или неаккуратного) аудита кода, отсутствие надлежащего контроля, отсутствие достойной автоматизации, отсутствие ручных тестеров. Единичные тесты * могли помочь *, но основная проблема кроется в другом месте. Кроме того, модульные тесты для autoproperties - это много кода шаблона для поддержания ... который никогда не бывает хорошим. –

+0

@jimmy_keen - но модульное тестирование * является частью процесса, на который вы ссылаетесь *; в моем случае это была небольшая компания с 3 разработчиками и слишком много работы. Не было никаких проверок кода или ручных тестеров.Вы можете критиковать это из башни из слоновой кости, если хотите (и я бы согласился с вами на теоретическом уровне), тем временем назад в реальном мире у нас была работа, чтобы делать и счета платить ... так что я не вижу, как мои ответ неверен, потому что это доказуемо правильно, что если бы я * написал единичный тест, проблема не * выскользнула бы в дикую природу. И как 3-строчный тестовый метод «много шаблонов»? –

3

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

+0

Я бы согласился, но я слышал, что некоторые действительно напрягаются. Я мог видеть свойство getter, в котором была какая-то логика. – Sam

+3

@ Да, это может быть реалистично, но это не тот пример, который вы дали. Автоматическое свойство, подобное тому, которое вы предоставили, не имеет значения при его тестировании. Если в нем много работы, вы можете спорить об этом. –

+0

@Sam, в этом случае, когда в нем есть логика, тогда его можно считать приемлемым для проверки, но это было бы бессмысленно иначе. –

32

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

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

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

EDIT: Согласно моему разговору с автором принятого ответа на этот вопрос, я хотел бы добавить следующее.

Я могу оценить, что пуристы TDD скажут, что вам нужно проверить автоматические свойства. Но, как разработчик бизнес-приложений, мне нужно взвешивать, разумно количество времени, которое я мог потратить на написание и выполнение тестов на «тривиальный» код, например, на автоматические свойства по сравнению с тем, как долго он мог бы разумно исправить проблему, которая может возникнуть из не тестирование. В личном опыте большинство ошибок, возникающих при изменении тривиального кода, тривиальны, чтобы исправить 99% времени. По этой причине я бы сказал, что положительные результаты только модульного тестирования неязыковых спецификаций перевешивают негативы.

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

+3

+1 Кроме того, вы косвенно проверяете эти свойства. Например. если они не рассматриваются в других тестах, тогда они не нужны. – Finglas

+0

-1; со всем уважением и не желая превращать это в религиозные дебаты, но модульные тесты служат многим целям поверх простых методов тестирования, не в последнюю очередь из которых служит регрессионным тестовым пунктом, чтобы вы рано ломались об изменениях. Конечно, наличие общедоступных свойств R/W в классе вполне может быть настоящим WTF, но если ваш дизайн требует его, то вам действительно нужно будет его тестировать ... никто из нас не может предсказать, какие изменения могут быть внесены кто-то еще в наш код через 6 месяцев. –

+2

Я бы сказал, что в случае встроенной функции языка (в этом случае автоматические свойства) нет необходимости самостоятельно тестировать ее, поскольку она не служит цели, кроме как проверить те функции, которые, как вы знаете, будут работать. Если у вас есть это свойство в среде разработчиков, которые все работают с TDD-практиками, тогда они будут знать, что если они изменят поведение этого свойства в любой момент, добавить в модульный тест тогда, когда он больше не соответствует языку Спецификация. – BenM

1

Если свойства не выполняют никакой другой логики, то нет.

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

3

Вы придерживаетесь строгих правил TDD или нет?

Если да, то вы абсолютно должны писать тесты на публичные геттеры и сеттеры, иначе как вы узнаете, правильно ли вы их внедрили?

Если нет, вы, вероятно, должны написать тесты. Хотя реализация тривиальна сегодня, не гарантируется, что она останется такой, и без теста, охватывающего функциональность простой операции get/set, когда будущее изменение в реализации нарушает инвариант «свойства настройки Foo со значением Bar, приводит к getter для свойства Foo, возвращающего значение Bar, «модульные тесты будут продолжать проходить. Сам тест также тривиально реализован, но защищен от будущих изменений.

2

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

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

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

+0

Другой способ поставить то, что вы говорите, - «Насколько вам уверен, что код работает». –

1

Согласно книге The Art of Unit Testing With Examples in .NET, юнит тест охватывает не любой тип кода, он фокусируется на логического кода. Итак, что такое логический код?

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

Выполняет ли простой геттер/сеттер любую логику?Ответ:

Свойства (добытчиками/сеттеры в Java) являются хорошими примерами кода, обычно не содержат какой-либо логики, и поэтому не требует тестирования. Но не обращайте внимания: как только вы добавите какую-либо проверку внутри объекта, вам нужно будет убедиться в том, что логика протестирована.

0

Мой ответ, который находится из прежней точки зрения диспетчера тестов и в настоящее время является менеджером по разработке (отвечающим за доставку программного обеспечения во времени и качестве). Я вижу, что люди упоминают прагматизм. Прагматизм не является хорошим консультантом, потому что он может сочетаться с лени и/или временным давлением. Это может привести вас к неправильному пути. Если вы упомянете прагматизм, вы должны быть осторожны, чтобы сохранить свои намерения на пути профессионализма и здравого смысла. Это требует смирения принять ответы, потому что они могут не так, как вы хотите услышать.

С моей точки зрения, что является важным являются следующие:

  • вы должны найти дефект как можно раньше. Для этого вам необходимо применить надлежащую стратегию тестирования. Если это тестовые свойства, вам необходимо проверить свойства. Если нет, то не делайте этого. Оба стоят с ценой.
  • Ваше тестирование должно быть простым и быстрым. Чем больше часть (единица измерения, интеграция и т. Д.) Кода, проверенного временем сборки, тем лучше.
  • вы должны сделать анализ основных причин, чтобы ответить на приведенные ниже вопросы и сделать вашу организацию защищенной от текущего типа ошибки. Не волнуйтесь, появится другой тип дефекта, и всегда будут извлечены уроки.
    • Какова основная причина?
    • как этого избежать в следующий раз?
  • Другой аспект - это затраты на создание/поддержание тестов. Не тестировать свойства, потому что они скучны для поддержания и/или у вас есть сотни свойств, это смешно. Вы должны создавать/применять инструменты, которые делают деревообрабатывающую работу вместо человека. В общем, вы всегда должны улучшить свою среду, чтобы быть более эффективной.
  • что другие говорят, что это нехороший советник - неважно, было ли это сказано Мартином Фаулером или Симаном - среда, в которой они находятся. Я почти уверен, что вы не такие, как вы. Вы должны использовать свои знания и опыт настроить то, что хорошо для вашего проекта, и как сделать его лучше. Если вы применяете вещи, потому что они были произнесены людьми, которых вы уважаете, даже не задумываясь об этом, вы окажетесь в глубоких бедах. Я не говорю, что вам не нужны советы и/или помощь другим людям или мнение, вы должны применять здравый смысл для их применения.
  • TDD не отвечает на два важных вопроса, однако BDD дает вам ответы на вопросы ниже. Но, если вы будете следовать только одному, у вас не будет своевременной доставки и качества. Так что неважно, являетесь ли вы пуристским парнем TDD или нет.
    • что необходимо проверить? (он говорит, что все должно быть проверено - неправильный ответ, на мой взгляд)
    • , когда тестирование должно быть завершено?

В целом, нет хорошего ответа. Просто другие вопросы, на которые вы должны ответить, чтобы получить эту временную точку, где вы можете решить, нужно ли это или нет.

Смежные вопросы