Вивчення TDD через інтенсивну практику

       Примітка від перекладача : мій досвід знайомства з розробкою через тестування багато в чому схожий з тим, що описує автор (хоча і почався на кілька років пізніше). Я починав вивчати TDD самостійно, на роботі, виправляючи баги і створюючи нові модулі з нуля. Ефект від застосування TDD справив на мене настільки сильне враження, що породив бажання ділитися вмінням застосовувати цю техніку з іншими. Я також проводив Code Retreat-и всередині і поза своєї компанії. І я бачу ті ж проблеми у своїх тренінгах — дуже складно взяти і «впихнути» розуміння суті TDD в чужі голови.
 
Тому в даній статті я бачу свіжий погляд на проблему, який, можливо, дасть новий поштовх у вивченні TDD мені і моїм колегам. Думаю, вона стане в нагоді і іншим зацікавленим розробкою через тестування. Буду радий побачити Ваші коментарі.

 
Я використовую TDD як інструмент для вивчення і викладання основ модульного дизайну, але мушу зауважити, що ефективність навчання сильно залежить від дисципліни студентів. Я хочу робити свою справу все краще і краще, і тому постійно шукаю нові способи планувати критичні кроки 1 у викладанні TDD. Думаю, я знайшов МІКРОТЕХНІКА, яка допомагає в цій справі, і хочу негайно поділитися їй з вами.
 
 

TL; DR?

Багато прихильників TDD рекомендують підхід під назвою «інтенсивна практика», але я здогадуюсь, що у Вас не буде можливості витрачати багато робочого часу на практику. Я раджу людям «застосовувати TDD усвідомлено», але до цих пір не знав хорошого способу досить доступно пояснити зміст цих слів, що знижувало цінність мого ради. Ви можете почати застосовувати обидва підходи (інтенсивний і усвідомлений) одночасно, якщо почнете виправляти баги через тести. Навіть якщо Ви досі не вмієте проектувати софт на експертному рівні, то, принаймні, Ви вже можете вчитися як експерт. І виправлення багів через тести дасть Вам природну і не надто ризиковану можливість робити це. У Вас буде можливість практикуватися в TDD усередині і усвідомлено. Якщо у Вас є можливість виправляти баги на роботі поодинці, то Ви можете використовувати ці практики, не привертаючи зайвої уваги, яке зазвичай виникає при розмовах про «інтенсивної практиці». Просто говорите всім, що Ви виправляєте баги. Це всім сподобається.
 
Вам всього лише треба почати з написання тесту, який буде падати до тих пір, доки Ви не виправите баг. Якщо Вам потрібно більше подробиць, перш ніж почати, продовжуйте читання.
 
 
 
Подробиці
Під час читання книги Sources of Power Гері Кляйна (Gary Klein), в якій описується, як люди вчаться приймати рішення, мою увагу привернула глава про інтенсивну практиці. (Я прокоментую кілька цитат зі 104-ї сторінки цієї книги.)
 
Оскільки ключем до ефективного прийняття рішень є побудова експертизи, одним з спокус буде створення тренінгу,-вчителя людей думати як експерти.
Мені видається, що безліч людей піддаються цій спокусі і будують свої тренінги так, щоб максимізувати обсяг інформації експертного рівня, якою вони можуть навантажити учасників. Я теж так робив, але зупинився, коли сам побував на одному з них звичайним учасником. Якщо Ви відкриєте кран і почнете заливати в мене десятки правил і висновків, я «переповнилася» всього за пару годин, а потім перестану слухати.
 
У більшості випадків це буде занадто довгим і дорогим задоволенням.
Ага.
 
Однак, якщо ми не можемо навчити людей думати як експерти, можливо, у нас вийде навчити їх вчитися як експерти.
Продовжуй…
 
Вивчивши літературу, я виявив кілька способів, як можуть навчатися експерти в різних областях:
 
     
Вони беруть участь в інтенсивній практиці так, що кожне практичне заняття має мету і оціночні критерії.
 Вони напрацьовують обширний пласт досвіду.
 Вони отримують зворотній зв'язок: точну, діагностує, і своєчасну.
 Вони збагачують свій досвід, проводячи «розбори польотів», щоб витягти уроки зі своїх помилок.
 
 
Щось з цього звучить знайомо, а щось являє собою нові можливості витягти більше з практик по TDD.
 
 

Три з чотирьох — не так вже і погано

Раніше я вже згадував про інтенсивну практиці. У «Don't Waste Your Golden Learning Opportunity!» я писав про те, що до нові практики можна розглядати як етюди. Ця метафора взята з музики, де етюди широко застосовуються для відпрацювання техніки. Спортсмени, в свою чергу, можуть думати про практику як про ігрову тренуванні. Але, так як більшість програмістів навряд чи будуть практикуватися поза рамками своєї денної роботи, є сенс розглянути такі режими практики, які можна застосовувати під час «звичайної роботи».
 
Я і сам вивчав спершу підхід «спочатку тести» (test-first), а потім і «розробку через тести» (test-driven) в гарячці щоденної роботи, коли час обмежений, і від мене чекають реальних результатів. Зараз, озираючись назад, я розумію, що робив три з чотирьох речей, які Кляйн перераховує в якості джерел навчання експертів.
 
 
     
Я напрацьовував обширний пласт досвіду, використовуючи TDD для написання майже всього мого робочого коду в період з початку 2000-го року і до мого відходу з IBM в листопаді 2001-го.
 Я отримував точну, діагностують і своєчасну зворотний зв'язок, задаючи тисячі питань і беручи участь у серйозних дискусіях в різних поштових розсилках. (Тоді ще не було StackOverflow.) Я також відповідав на безліч питань інших людей, що вимагало від мене читання, написання та покращення великої кількості коду.
 Відповідаючи на питання в списках розсилки, на конференціях, на зустрічах користувачів, я часто торкався старих тем знову і знову, що дозволяло відточувати мої старі відповіді, а також випробовувати нові осяяння. Весь цей досвід з часом перетворився на мою першу книгу: JUnit Recipes: Practical Methods for Programmer Testing .
 
Але навіть тоді, коли я практикувався інтенсивно і усередині (і навіть усвідомлено), я не заходив так далеко, щоб сформулювати явну мету і оцінний критерій для моїх практичних занять. Точніше, часом заходив, але частіше немає. Як правило, я не ставив таких цілей явним чином, а якщо ставив, то це відбувалося випадково. Зараз же настав час згадати мій колишньої досвід і витягти з нього новий урок.
 
 

Інтенсивна практика TDD

Якщо Ви хочете попрактикувати в TDD як в інструменті якісного проектування програмних систем, спробуйте зайнятися цим на роботі.
 
Візьміться виправити небудь баг. Швидше за все, Ви вже знаєте, як виправляти баги, використовуючи принцип «спершу тести» (test-first), але про всяк випадок я коротко опишу цей процес:
 
 
     
Напишіть інтеграційний тест, який падає через цього бага. Тест не обов'язково повинен проходити до кінця, але Ви можете продовжити його так далеко, як Вам потрібно. Головне, щоб б він падав через існуючого бага.
 Починайте писати все менші і менші (більше сфокусовані) тести, які наближають Вас до місця розташування бага. Можете використовувати для цього прийом «лещата Саффа» (Saff Squeeze ) або будь-який аналогічний. Можете навіть використовувати відладчик, якщо хочете.
 Зупиніться тоді, коли у Вас є мінімальний тест (або кілька тестів, якщо у бага є кілька причин), який описує суть помилки, що викликає цей баг.
 Виправте помилку, упевніться, що всі тести проходять, і потім закомітьте всі Ваші зміни.
 Налийте собі кухоль кави.
 
А тепер давайте повернемося до чотирьох пунктів Кляйна і подивимося, як цей метод допоможе Вам вчитися проектування софта на експертному рівні.
 
 Чи схоже це на інтенсивну практику? Так. Коли я сідаю виправляти баг цим методом, я ставлюся до нього як до можливості потренуватися в написанні тестів, можливості вчитися менше покладатися на відладчик і відстеження коду в голові, можливості вчитися краще виражати і документувати (через тести) моє знання про код, який я отлаживаемого.
 
 Чи є у мене ясна мета та оціночні критерії? Я бачу ясну мету: виправити баг, навчитися писати тести, навчитися писати більш сфокусовані тести, а також задокументувати придбане знання про код, щоб це знання не випарувалося до того моменту, коли я буду відправляти свої зміни до загального репозиторій. А в якості оціночних критеріїв я можу вибрати щось з наступного:
 
 
     
Наскільки легко мені повернутися до цих тестів через якийсь час після виправлення бага і зрозуміти, що я робив?
 Наскільки легко комусь іншому прочитати мої тести і зрозуміти, що я робив?
 Наскільки легко мені переміщатися від великих тестів до менших?
 Чи втрачається якась інформація, коли я переходжу від великих тестів до менших?
 Наскільки я впевнений, що цей конкретний баг не повториться?
 Наскільки спокійно і комфортно я себе відчуваю під час боротьби з багом?
 
Не знаю, назвете Ви ці критерії досить ясними, але від них, принаймні, вже можна відштовхуватися. Можливо, разом ми зможемо виробити більш вдалі оціночні критерії.
 
 Чи допоможе це мені напрацювати великий пласт досвіду? Допоможе, якщо я виправлю таким чином 50 багів в перебігу декількох наступних місяців. Як мінімум, якщо я вирішу виправляти всі баги таким чином, я неухильно напрацювала істотний обсяг досвіду. Особливо якщо я буду виправляти баги в усіх частинах системи. А вже тим більше, якщо в декількох системах.
 
 отримаю я точну, діагностує, своєчасну зворотний зв'язок? Думаю, так. Кожен раз, коли я пишу новий тест, він або пройде, або впаде. Тому я, принаймні, можу зрозуміти, що почав наближатися до зламаної частини коду. Я не можу бути впевнений на 100%, що я знайшов той шматок коду, який викликає падіння, поки мої тести не стануть досить маленькими, щоб довести це тим чи іншим способом, і я поступово рухаюся в цьому напрямку.
 
 Чи допоможе це мені переглянути мій старий досвід, щоб отримати нові осяяння? Та й немає. Ні, тому що (як я сподіваюсь) мені не доведеться виправляти один і той же баг двічі; але так, тому що я працюю таким чином з кожним новим багом, так що мені доведеться стикатися з тими ж частинами системи по багато разів. Чим більше багів я виправляю в якій-небудь частині системи, тим більше можливості у мене буде повернутися до моїм минулим тестам і порівняти свій новий досвід зі старим. Якщо я витрачу трохи часу, порівнюючи, що я роблю по-іншому в порівнянні з минулими разами, то це дасть мені можливість отримати нові осяяння.
 
Так що, мені здається, що подібний метод виправлення багів допоможе практикується вчитися як експерт (принаймні, в даній інтерпретації як методу, так і моделі навчання експертів, описаної Кляйном). Просто спробуйте самі і оцініть цей підхід.
 
 

За межами роботи з багами

Як можна використовувати TDD для вивчення принципів модульного дизайну на експертному рівні? Я повинен згадати одну часто зустрічається недбалість на цьому шляху. Це не те щоб серйозна недбалість, скоріше наслідок благих намірів і в той же час нерозуміння. Я завжди вважав використання «усвідомленого підходу» особливо важливим. Тому, коли хто-небудь починає заявляти, що розробка через тести «не працює» або «заподіює страждання» або «шкодить», я включаюся в дискусію і раз за разом повторюю одну й ту ж ідею:
 
Правила нічого не роблять самі; все роблять люди. TDD, як і будь-яка інша практика, вимагає від практикуючого включати мізки. Він повинен вправлятися усвідомлено.
Це було вірно, але досить марно… до сьогоднішнього дня. Я впевнений, що Кляйн відкрив мені більш точний і застосовний у справі спосіб пояснювати, що таке «усвідомлена практика». Я збираюся використовувати його в моїх тренінгах, починаючи з сьогоднішнього дня. Схоже, я неявно використовував його у вивченні TDD (і модульного дизайну), але до цих пір у мене не було легко запам'ятовується способу його сформулювати. Спасибі, Гері Кляйн.
 
 

Як практикуватися в TDD «усвідомлено»

Візьміть паузу в декілька секунд і подумайте про те, коли і як Ви збираєтеся вивчати TDD. На якому коді? У який час? У яких умовах? Не обов'язково жорстко обмежувати себе цими правилами, але вони допоможуть упорядкувати процес. Дуже важливо визначити для себе, в яких випадках Ви готові використовувати TDD, а в яких ні. Визначте це, поки що, тільки для себе. Домовитися з колегами можна і пізніше 2 .
 
Як тільки Ви визначили рамки, в яких Ви будете вправлятися в TDD, Ви можете задати собі цілі і критерії оцінки для цих тренувань. Підкине кілька ідей.
 
 
Цілі для тренувань по TDD
 
     
Створіть через тести точку інтеграції з бібліотекою, з якою Ви не працювали раніше.
 Відокремте кілька більшу частину Вашого коду від інтеграції з фреймворком.
 Напишіть поменше тестів, які вимагають фреймворк-орієнтованої бібліотеки тестування (наприклад, Robolectric, NUnitASP, rspec-rails, or JSFUnit), і побільше тестів, які використовують звичайні бібліотеки тестування (звичайні JUnit, RSpec або pytest).
 Зменшіть час, який потрібен на створення наступного тесту.
 
 
Оціночні критерії для тренувань по TDD.
 
     
Чи зробив я цю частину системи більш простий, ніж зазвичай?
 Чи є імена в цій частині системи більш зрозумілими іншим, чи допомагають вони зрозуміти, як змінювати цей код?
 можу я розширити цю частину системи, просто додаючи новий код, а не змінюючи існуючий?
 Чи залежить код, необхідний для налаштування оточення моїх тестів, тільки від тих частин системи, які я тільки що створив?
 Якщо мій тест містить декілька перевірок, припускаю я, що вони сильно пов'язані один з одним?
 Чи достатньо швидко проходять мої тести? Або вони хоча б стали швидше, ніж раніше?
 
Якщо ми посидимо разом хоча б десять хвилин, то напевно придумаємо ще дюжину подібних корисних критеріїв. Виберіть кілька і тримайте їх в голові протягом наступного сеансу програмування, під час якого Ви будете відпрацьовувати TDD.
 
А мені дозвольте перейти до питання отримання нових осяянь зі старого досвіду , тому що я часто стикаюся з цим, навчаючи інших і практикуючись з ними. Щоб переробляти свій досвід, не обов'язково самому проводити якісь заняття. Можна, наприклад, просто відповідати на чужі запитання. Наприклад, я раз за разом відповідаю на одні й ті ж питання, що приходять різними людьми. (Зазвичай я терпіти не можу повторюватися, але зараз я зрозумів, що ці повторення насправді набагато цінніше.) Чим більше я відповідаю на ці питання, тим більше я рефлексую над моїм розумінням. Згодом мої ідеї стикаються з різноманітними новими іспититаніямі і або зміцнюються, або дають життя новим, більш вдалим. Я також приймаю участь в Code Retreat-ах спеціально для того, щоб працювати над одними і тими ж невеликими завданнями знову і знову з новими людьми. Щороку я відчуваю нові осяяння, працюючи над грою «життя».
 
А зараз я хотів би перейти до одного важливого пункту в моделі Гері Кляйна, до пункту, який сподвиг мене написати цю статтю саме сьогодні.
 
 

Обширний пласт досвіду

Я роками описував TDD як «техніку для навчання проектуванню», в якій ми можемо використовувати механізм, схожий з механізмом напрацювання мовних навичок. Як Ви вчилися говорити на своїй рідній мові? Швидше за все, це виглядало якось так:
 
     
Спочатку, протягом довгого часу. Ви тільки слухали промову людей навколо Вас.
 У якийсь момент Ви почали говорити дуже прості фрази.
 Коли ви почали вимовляти ці фрази, Ви помічали, як оточуючі реагують на Вашу мову.
 Іноді Вас поправляли, пояснюючи, що треба говорити так, а не отак.
 З цих пояснень Ви витягували правила і принципи побудови «правильних» фраз.
 Ви спиралися на ці правила і принципи в побудові нових пропозицій.
 
І цей процес йшов, не припиняючись. Мова, на якому Ви розмовляєте, перетворився на інструмент безперервного спілкування з іншими людьми, що включає експерименти, оцінку, взаємний вплив, спроби виправлень, вилучення нових правил і принципів… — і так до самої смерті.
 
На мій погляд, TDD дозволяє вивчати дизайн коду аналогічним чином. Він дозволяє вийти за межі звичайного програмування, надаючи програмісту можливість оцінювати код в критеріях високого рівня, а-ля «я легко можу протестувати це», або «я можу відокремити цей код з його контексту, щоб запускати в ізольованому оточенні» або «я можу додати нове поведінку через додавання коду, а не через зміну існуючого ». Ви можете заперечити, що такі оцінки можна отримати, навіть просто читаючи й обговорюючи код, але саме TDD мотивує програміста вести діалог з кодом, обмірковувати «як має поводитися цей шматок?» Або «як мені слід спроектувати цю частину?» З різних сторін. Я думаю, що такий діалоговий стиль створення коду дозволяє напрацьовувати досвід куди ефективніше і швидше, ніж традиційний підхід «пиши багато, читай рідко». Як мінімум, TDD мотивує програміста бачити код під різними точамі зору.

Головну роль в цьому підході відіграє рефакторінг. Під час рефакторинга потрібно оцінити існуючий код, зрозуміти і виявити його проблеми, запропонувати спосіб його поліпшення, а потім змінити відповідно з цим способом. (Не хотілося б мені проводити великий рефакторінг без тестів, а якби я не писав тести в першу чергу, то навряд чи б їх набралося досить багато, щоб я відчував себе досить впевнено при рефакторінгу.) Процес рефакторинга дозволяє програмісту бачити різні варіанти дизайну одного і того ж коду, кожен з яких може або мати певні проблеми, або не мати; це дозволяє порівнювати різні варіанти дизайну і вибирати з них найбільш гідні. У програміста з'являється можливість порівнювати стану «до» і «після» рефакторинга й оцінювати, який ефект дають його поліпшення коду.

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


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

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.