Методологія: Написання тестових одиниць для іншого розробника


28

Я думав про розробку програмного забезпечення та написання тестових одиниць. У мене з’явилася така ідея:

Припустимо, у нас є пари розробників. Кожна пара відповідає за частину коду. Один з пари реалізує функцію (код запису), а другий записує для неї одиничні тести. Тести пишуться після коду. У моїй ідеї вони допомагають один одному, але працюють досить окремо. В ідеалі вони працювали б над двома аналогічними розмірами, а потім обмінялися на підготовку до тесту.

Я думаю, що ця ідея має деякі переваги:

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

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

Які недоліки цієї ідеї? Це вже описується як якась невідома мені методика і використовується при розробці програмного забезпечення?

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


17
Ви просто описуєте QA нижче за течією на рівні одиниці. Якщо у вас є пари людей, які працюють над чимось, ви спробували фактичне програмування пар з TDD?
jonrsharpe

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

14
Ця критика не має сенсу, і ваша пропозиція не вирішує цю проблему.
jonrsharpe

5
@franiis Я бачив, як колеги пишуть assert trueяк тести і називають це день, тому що кожен тест проходив. Пропав один важливий крок: тести повинні спочатку провалитися, і їх потрібно пройти, змінивши код, а не тести.
Ерік Думініл

6
@franiis TDD побудований навколо ітерації. Написати невдалий тест. Напишіть код, що робить тест зеленим. Рефактор. Напишіть невдалий тест. Напишіть код, що робить тест зеленим. Рефактор. Здається, що ви пропускаєте частину "повторіть, поки у вас не будуть тести, які покривають усі ваші вимоги". Але найбільша проблема у вас, здається, полягає в тому, що "тести" розглядаються як щось, що ви повинні мати, тому що хтось це сказав, а не тести як корисний інструмент для розробників . Якщо ви не можете змусити людей піклуватися про якість (та правильність) коду, це ваша проблема, і саме з цього слід почати.
Луань

Відповіді:


30

Загальний підхід використання пар для розподілу зусиль для написання виробничого коду та написання пов'язаних з ним одиничних тестів не є рідкістю. Я навіть особисто поєднувався таким чином раніше з гідним успіхом. Однак суворий рядок між кодом, який пише виробничий код, і тим, хто пише тестовий код, не обов'язково може дати результати.

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

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

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


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

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

3
Практика парного програмування полягає не в швидкості, а в якості. Пара TDD - це якість, яка приносить швидкість завершення, що приводить до зниження витрат на розробку. Це просто наша галузь, яка вивчає те, що масони знали за тисячоліття: ваша стіна буде побудована краще за менший час, з меншими зусиллями і меншими витратами, якщо ви витратите трохи часу на встановлення спочатку рядкового рядка і правила муляра, а потім закладіть свої цеглини, ніж якщо ви кладете свою цеглу і намагаєтесь згодом підлаштовуватися під рівнем спирту та молотка. І отримати допомогу в справах.
Лоран LA RIZZA

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

@ThomasOwens: Ну, вартість якості сприймається лише, а не реальна. Після того, як ваш тест пройде (і ви виправили свій код), сценарій, описаний вашим тестом, буде виконаний і забезпечений, і ви отримаєте впевненість, що він працює так, як очікувалося. Це зроблено, і ви можете рухатися далі. Якщо ви рухаєтесь далі без певності, що код працює, ви просто прийняли борг, який вам доведеться виконати перевірки пізніше. Заборгованість коштує, а не відсутність боргів. Я маю на увазі, що "майбутнє", про яке ви говорите, - це як тільки пройде ваш перший тест.
Лоран LA RIZZA

37

Основна проблема вашої ідеї полягає в тому, що ви не можете просто писати тести на будь-який код. Код повинен бути перевіреним.

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

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


Спасибі. але загальна критика TDD полягає в тому, що код іноді / часто пишеться, щоб зробити тести «зеленими» - це не бути добре. Якщо тести не перевіряють деякий аспект коду, його можна опустити в коді. Пізніше тест написання може допомогти цьому (я погоджуюсь, що після введення коду можуть бути потрібні деякі зміни, але розробники повинні в майбутньому навчитися писати більш тестовий код).
franiis

1
@franiis впевнений, головна проблема полягає не в тому, що ви пишете тести після, а в поєднанні цього робити, а не бути тією ж людиною, яка написала код.
Еван

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

25
@franiis: "Якщо тести не перевіряють якийсь аспект коду, його можна опустити в коді." - У цьому вся суть. Тести - це кодування вимог у вигляді виконуваних прикладів. Якщо для нього немає тесту, то для нього немає жодної вимоги, і для нього не повинно бути коду .
Йорг W Міттаг

3
Іншою стороною того, що сказав @ JörgWMittag, було б: якщо ваші тести "не перевіряють важливого коду", вам потрібно виправити свої тести. Це буде так само правдиво у вашій системі, як і у традиційному TDD.
бта

15

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

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

Так, так, мати друге розробник, писати додаткові одиничні тести, має сенс, але не писати виключно одиничні тести .


7

Здається, існує можливість виникнення будь-якої з наступних ситуацій - все це небажано:

Плутанина

Як констатував Юан, CUT може знадобитися змінити, щоб зробити його тестуваним. Причина змін не завжди очевидна для розробника (і може спричинити незгоду), саме тому тести пишуться першими.

Суперечка

Розробник A, можливо, заповнив свій код і захоче його перевірити. Розробник B також може розвиватися, і тому він може схилити паркувати свій код для участі в одиничних тестах.

Контекстна комутація

Навіть якщо розробник B готовий стримувати свою розробку, щоб перевірити код, написаний розробником A - зміна активності приходить до вартості.


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


4

Якщо використовується в поєднанні з парним програмуванням і TDD, це називається Шаблон Ping Pong :

  • A пише новий тест і бачить, що він провалюється.
  • B реалізує код, необхідний для проходження тесту.
  • Б пише наступний тест і бачить, що він провалюється.
  • A реалізує код, необхідний для проходження тесту.

І так далі. Реконструкція проводиться, коли виникає потреба того, хто їздить.

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

У будь-якому разі: Ви можете багато чого навчитися, протестуючи нові способи ведення справ, навіть якщо вони не є на 100% ефективними. Ви можете протестувати його та поділитися своїм реальним життєвим досвідом


3

Я пізно заходжу на цю вечірку, але, думаю, мені є що додати.

Це вже описується як якась невідома мені методика і використовується при розробці програмного забезпечення?

Ви описуєте рівне тестування .

Припустимо, у нас є пари розробників.

Ах, добре програмування .

Кожна пара відповідає за частину коду. Один з пари реалізує функцію (код запису), а другий записує для неї одиничні тести. Тести пишуться після коду. У моїй ідеї вони допомагають один одному, але працюють досить окремо.

Це не парне програмування.

В ідеалі вони працювали б над двома аналогічними розмірами, а потім обмінялися на підготовку до тесту.

Це, безумовно, Peer Testing. Ось документ ACM про це . Я це зробив. Я працював там, де це було формальною частиною процесу експертного огляду . Це корисно, але це, звичайно, не призначено для першого тестування, і це звичайно не класичне програмування пар.

Інша назва цього тестування - Whitebox Testing . Хоча це визначення не стосується того, хто проводить тестування так само, як і того, що тестеру доводиться бачити внутрішню роботу речі, яку вони тестують, на відміну від тестування Black Box, де вони бачать лише те, що відбувається і що виходить. Чорний ящик, як правило, робить QA.

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

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

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


Дякую за відгук та вказуєте мені на Peer Testing (я прочитаю про це).
franiis

1

Я робив DDT (тестування на основі розробки, т.к. тести за кодом), програмування пар та програму TDD для червоно-зеленого рефактора протягом декількох років. Щоб відповісти на ваші твердження по пункту:

тести написані кимось, хто більше може ознайомитись з реалізацією

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

робота повинна бути виконана трохи швидше, ніж парне програмування (дві функції одночасно)

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

і тести, і код мають відповідальну особу за це

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

код перевіряється щонайменше двома людьми

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

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

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

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


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

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

Я намагаюся пояснити обґрунтування того, що "робота повинна бути зроблена трохи швидше", яка, здавалося, вас бентежить. Моє переживання, як правило, повільніше, хоча я все ще думаю, що воно того варте (бажано, як для індивідуальної роботи, так і для тестування ОП). Якщо вам швидше, тим краще.
Яків Райхле

1

Я думаю, що ця ідея має деякі переваги:

Нехай пробігаються через них по черзі.

тести написані кимось, хто може дізнатися більше про реалізацію,

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

робота повинна бути виконана трохи швидше, ніж парне програмування (дві функції одночасно)

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

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

і тести, і код мають відповідальну особу за це,

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

код перевіряється щонайменше двома людьми

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

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

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

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

XP прямо говорить, що всі практики XP створені для посилення один одного, прикриваючи дефекти один одного. Не слід слухати критику будь-якої практики XP, відокремленої від інших. Жодна практика не є досконалою, TDD не є досконалим, програмування пар не є ідеальним, володіння колективним кодом не є ідеальним, але всі вони охоплюють один одного.

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