Чи корисно використовувати методи тестування, де єдиною логікою є охоронці?


12

Скажіть, у мене такий метод:

public void OrderNewWidget(Widget widget)
{
   if ((widget.PartNumber > 0) && (widget.PartAvailable))
   {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

У моєму коді є кілька таких методів (передня половина виклику веб-служби асинхронізації).

Я обговорюю, чи корисно їх покрити одиничними тестами. Так, тут є логіка, але це лише логіка охорони. (Це означає, що я переконуюсь, що мені потрібні речі, перш ніж дозволити виклик веб-служби.)

Частина мене каже, "ви впевнені, що можете випробувати їх, але це не варто часу" (я вже за проектом, який вже за графіком).

Але інша сторона мене каже, якщо ви не підрозділите тест на них, а хтось змінить гвардійців, то можуть виникнути проблеми.

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

Наприклад, якщо моя служба бере на себе відповідальність перевірити наявність віджетів, я, можливо, більше не захочу цього охоронця. Якщо він проходить тест на одиницю, зараз я повинен змінити два місця.

Я бачу плюси і мінуси в обох напрямках. Тому я думав, що запитаю, що зробили інші.


17
Ви не робите «більше роботи» для обслуговуючого персоналу. Якщо вони змінюють логіку, вони повинні змінити відповідні одиничні тести. Ось як це працює. Я не бачу ваших мінусів: якщо ваш тест не вимагав змін, то він би нічого не тестував, чи не так? Ви також можете запитати, чи корисне тестування одиниць взагалі.
Андрес Ф.

9
Це поза темою, але я міняв би логіку, щоб викинути виняток, якщо номер частини дорівнює 0 або менше, або якщо частина недоступна, оскільки, на мою думку, це буде помилка, щоб хтось міг викликати цей метод за допомогою фіктивний віджет, мовчки маскуючи чергову проблему.
Матвій

2
@Matthew дуже хороший момент. Ця функція полягає. Іменування говорить вам, що ви щось замовите. І тоді це не так, але ви ніколи не дізнаєтесь, якщо ви не застосуєте ту саму логіку, що є всередині, яка ііолітує ДУХУ. Іншими словами: якщо дизайн буде змінено на більш правильний, це питання, можливо, не було б задано в першу чергу.
стихій

2
but it is not worth the time" (I am on a project that is already behind schedule).Ми - розробники програмного забезпечення. Єдиний раз, коли ми за графіком, це коли ми мертві :)
maple_shaft

Відповіді:


26

Частина мене каже, "ви впевнені, що можете випробувати їх, але це не варто часу" (я вже за проектом, який вже за графіком).

Це три дуже короткі тести. Ви витратили стільки часу, задаючи собі питання.

Але інша сторона мене каже, якщо ви не підрозділите тест на них, а хтось змінить гвардійців, то можуть виникнути проблеми.

Слухайте цю сторону.

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

Якщо ваш технічний супровід є гайкою TDD, ви ускладнюєте їх. Будь-яка зміна, яку я вношу, не маючи пов’язаної зміни або додавання тестів, призводить до того, що мені потрібно важко думати. Насправді я, мабуть, додав би тести, перш ніж продовжувати та робити зміни.

Перша частина вас просто невірна. Дайте другій частині погладити по спині і перестаньте думати про це.


+1 для лаконічності, хоча я теж написав відповідь хе
Джиммі Хоффа

3
+1. Так, якщо вимоги змінюються, деякі тести доведеться адаптувати.
Олів'є Якот-Дескомб

Хоча мені подобається те, що ви говорите, у мене в коді є багато випадків такого виклику (передня половина виклику асинхронізації). Тож це не просто 3 одиничні тести. І все-таки, якщо це "правильний" спосіб, то я хочу їх виконати.
Ваккано

@ Вакано: Чим більше їх потрібно писати, тим більше логічних шляхів у вас немає тестів і тим більш необхідним є їх написання.
pdr

9

Це спростило б тестування блоків, якби логіка захисту та власне впорядкування були окремими методами.

У Widgetкласі

public bool IsReadyForOrdering { get { return PartNumber > 0 && PartAvailable; } }

або еквівалентний метод деінде

public bool IsWidgetReadyForOrdering(Widget widget)
{
    return widget.PartNumber > 0 && widget.PartAvailable;
}

Метод замовлення

public void OrderNewWidget(Widget widget)
{
   if (IsWidgetReadyForOrdering(widget)) {
        WigdetOrderingService.OrderNewWidgetAsync(widget.PartNumber);
   }
}

Тепер тестування IsWidgetReadyForOrderingстало легко. Не думайте довго про це більше. Перевірте це!


1
На жаль, логіка стану у властивості .. -1, що має бути методом, і він повинен приймати PartNumber, PartAvailable завдяки своїй простоті. Зробіть його захищеним, якщо він не повинен бути частиною публічного API, але не властивістю. Також я взагалі не погоджуюся. Логіка охорони всередині методу абсолютно чудова, і в моїх очах краще, оскільки це такий маленький метод, що ви просто забруднюєте клас, щоб зробити вже і малий метод меншим. Додайте його до класу в цьому випадку, лише якщо це повторювана логіка.
Джиммі Хоффа

1
По-перше, це не відповідає на питання. По-друге, це неправда. У будь-якому випадку потрібно написати три тести. По-третє, він необов'язково піддає деталі реалізації коду виклику.
pdr

8
@JimmyHoffa: де ви бачите будь-яку загрозливу логіку у цій власності? Насправді, на прикладі показано, як відокремити логіку, що змінюється в державі (OrderNewWidget), від логіки, що не змінюється (ReadyForOrdering). І я переконаний, що вилучення навіть невеликих функцій поліпшить код, а не зробить його гіршим, як ви заявляєте. Так +1.
Doc Brown

2
Цей метод OrderNewWidget, ймовірно, є в іншому класі Widget, оскільки він має Widgetаргумент. Оскільки метод не має зворотного значення, тестування його не очевидно. Вам доведеться ввести WigdetOrderingService-mock, який відстежує OrderNewWidgetAsyncвиклик.
Олів'є Якот-Дескомб

2
@JimmyHoffa: власне, ваше визначення "без громадянства" означає "статичне" в C #. Таким чином, те, що ви говорите, - "властивості не повинні отримувати доступ до стану об'єкта". Але навіть тупі отримувачі отримують доступ до змінних стану, так що це означатиме "записувати лише статичні властивості" - що, здається, не має особливого сенсу.
Doc Brown

6

Якщо у вас немає часу у вашому графіку на тестування одиниць, але у вас є час відкласти для твердого використання QA, то запитайте, чи можете ви вкрасти частину цього часу QA для написання одиничних тестів, чи ви можете витратити частину періоду якості QA. робити одиничні тести або, можливо, просто мати справу з перевіреним кодом без підрозділу. На жаль, графіки, які непорушно змушують вас піти на поступки або працювати на смерть, я, як правило, пропоную перший варіант, оскільки другий призведе до того, що ви не зможете підтримати / правильне підтримання системи на термін її роботи.

Це сказав до вашого загального питання про тестування заяв охоронців; Так! Абсолютно тестові заяви охоронців! Ті , є важливими складовими поведінки цього методу, ви не хотіли б, щоб дізнатися, хто що - то робить незрозумілий баг-фікс і видалити ваші охоронець або зміни &&Ань ||б ви? Експертні тести забезпечать, що: а) ви фактично виправили логіку на ваших гвардіях; б) ніхто не порушує цю логіку пізніше, не отримуючи скарги, коли вони проводять тестові одиниці, говорячи, що це повинно бути саме так.


0

Наведені вище відмінні відповіді, і їхні пункти дуже важливі. Але одне, що, здається, було пропущено, - це те, що у вас є вичерпний набір одиничних тестів, вони читаються як надзвичайно детальна специфікація коду. Якщо ви пропустите перевірку перевірки лише тому, що код такий простий, важко зрозуміти, як це може піти не так, частина вашої специфікації відсутня. Якби я потрапив до команди, де ці тести були пропущені, я б припустив, що ваша служба не підтверджує свої аргументи.


-5

Код - код. Вам слід спробувати отримати 100% охоплення при тестуванні. Якби це не було важливо, його не було б там.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.