Як видалити функцію чи функцію при використанні TDD


20

У текстах про TDD я часто читаю про "видалити дублювання" або "покращити читабельність" під час кроку рефакторингу. Але що змушує мене видалити невикористану функцію?

Наприклад, скажімо, що існує клас Cз методами a()та b(). Зараз я думаю, що було б непогано мати метод, f()який вводиться в життя C. Фактично f()замінює всі виклики b()за винятком одиничних тестів, які визначені / описані b(). Він більше не потрібен - за винятком тестів.

Це збереження, щоб просто видалити b()і всі тести, які його використовували? Це частина "покращення читабельності"?


3
Просто додайте ще один тест, щоб перевірити, чи функція не існує, а потім перейдіть до виправлення несправних тестів;)
Filip Haglund

@FilipHaglund Залежно від мови це може бути можливим. Але як кодова документація це виглядатиме дивно.
TobiMcNamobi

1
Просто для тих, хто може не знати краще: @ коментар FilipHaglund, очевидно, жарт. Не робіть цього.
жито

Відповіді:


16

Так, звісно. Найпростіший код для читання - це той, якого там немає.

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


@ jpmc26 Спритний, чоловіче, спритний! :-)
TobiMcNamobi

1
"Найпростіший код для читання - це той, якого немає там." - Я
повішу

27

Видалення відкритого методу не є "рефакторингом" - рефакторинг змінює реалізацію, продовжуючи проходити існуючі тести.

Однак видалення непотрібного методу - цілком розумна зміна дизайну.

TDD певною мірою це підкреслює, оскільки, переглядаючи тести, ви можете помітити, що це тестування непотрібного методу. Тести керують вашим дизайном, адже ви можете перейти "Подивіться, цей тест не має нічого спільного з моєю метою".

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

Існує два підходи до видалення методу; обидва працюють за різних обставин:

  1. Видаліть метод. Дотримуйтесь помилок компіляції, щоб видалити будь-який залежний код і тести. Якщо ви впевнені, що постраждалі тести є одноразовими, введіть свої зміни. Якщо ні, відкатуйтесь.

  2. Видаліть тести, які ви вважаєте застарілими. Запустіть весь тестовий набір із покриттям коду. Видаліть методи, які не використовували тестовий набір.

(Це передбачає, що ваш тестовий набір має почати добре).


10

Фактично f () замінює всі виклики на b () за винятком одиничних тестів, які визначали / описували b ()

IMHO типовий цикл TDD виглядатиме так:

  • написати невдалі тести для f () (ймовірно, виходячи з тестів для b ()): тести червоніють

  • реалізуйте тести f () ->, стають зеленими

  • refactor : -> видалити b () і всі тести для b ()

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


4

Так.

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


9
Ви пропустили частину "як".
JeffO

2

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

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

Лінія міркувань, як правило , працює для мене є те , що в момент , коли я помітив , що f()зробив b()застарілим, тому b()має бути , по крайней мере застарілим, і я шукаю , щоб знайти всі дзвінки b()з метою заміни їх дзвінків f(), I врахуйте також код тесту . Зокрема, якщо b()це більше не потрібно, я можу і повинен видалити його одиничні тести.

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

Цикл червоний / зелений / рефактор прямо не вказує на видалення тестів. Крім того, видалення b()порушує відкритий / закритий принцип , так як очевидно , ваш компонент є відкритим для модифікації. Тож якщо ви хочете сприймати цей крок як щось поза простою TDD, продовжуйте. Наприклад, у вас може бути якийсь процес для оголошення тесту «поганим», який можна застосувати в цьому випадку для видалення тесту на тій підставі, що він перевіряє те, чого там не повинно бути (непотрібна функція b()).

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

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


2

Завжди потрібно пам’ятати про те, що зараз ми використовуємо КОДОВІ РЕПОЗИТОРІЇ з ВЕРСІЙНИМ КОНТРОЛЮМ. Цей видалений код насправді не зник ... він все ще є десь у попередній ітерації. Тож видуйте! Будьте ліберальні за допомогою клавіші видалення, тому що ви завжди можете повернутися назад і отримати той дорогоцінний елегантний метод, який, на вашу думку, може бути корисним колись… якщо це коли-небудь настане. Це там.

Звичайно, це суперечить загрозі негараздів та небезпеці невідповідних випусків ... зовнішніх програм, які покладаються на реалізацію вашого інтерфейсу, які тепер осиротіли вашим (раптово) застарілим кодом.


Видалення коду взагалі не є проблемою. Я люблю видаляти, щоб видалити лінії, функції або ... ну, цілі модулі! Якщо можливо. І я роблю це все з TDD або без нього. Але: Чи є точка в робочому процесі TDD, де (не-дублі) код видаляється? Якщо ні, то все одно буде видалено. Але чи є? Це було моє питання.
TobiMcNamobi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.