
Анатомія доведення ПЗ до досконалості: як код-рев'ю зловило те, що не змогли тести
Упродовж усієї серії GeekBye v2 повторюється те саме: виправлення проходить кожен тест на машині розробника, а потім код-рев'ю доводить, що воно б не спрацювало майже ні в кого. Ось робочий процес за дев'ятьма релізами — ворота рев'ю, відлови на етапі виправлення і дисципліна «протестуй до відвантаження», яка перетворює «у мене працює» на «працює».
За кілька тижнів GeekBye випустило дев'ять релізів — з v2.0.0 по v2.0.11 — і ця серія розповіла історію кожного з них. Прочитайте їх разом, і випливає патерн цікавіший за будь-який окремий баг: знову і знову виправлення проходило кожен тест на машині розробника, а код-рев'ю доводило, що воно б не спрацювало майже в усіх інших.
Цей зазор — між «у мене працює» і «працює» — і є тим місцем, де насправді живе надійність. Ось робочий процес, який його закриває, і покажчик на кожен реліз, який він створив.
Патерн: зелені тести, неправильна відповідь
Ось три найнаочніші випадки із серії, бо вони роблять абстрактне конкретним.
- У виправленні захоплення на кількох моніторах (v2.0.10) перша реалізація прив'язувала захоплення екрана до вікна-оверлея застосунку. Воно пройшло тестування — на машині розробника з одним монітором. Рев'ю розсудило, де цей оверлей насправді живе (на основному дисплеї, завжди, якщо тільки ви фізично його не перетягнете) і довело, що «виправлення» розв'язалося б назад на неправильний монітор майже в кожного реального користувача. Правильний якір — курсор — вийшов із цього міркування, а не з прогону тесту.
- У релізі з резервним каналом при блокуванні WebSocket (v2.0.8) рев'ю виявило, що саме той
403, який повертає блокуючий проксі, класифікувався як фатальна помилка автентифікації — тож резервний канал, заради запуску якого функція й існувала, ніколи не міг спрацювати. Функція б відвантажилася, пройшла тести щасливого шляху і не зробила нічого для своєї справжньої аудиторії. - У виправленні тайм-ауту простою (v2.0.9) перша версія ставила позначку годинника «ще живий» усередині шляху коду, який частина транскриптів законно пропускає — репліки іншого співрозмовника. Рев'ю спіймало, що майбутня зміна могла б тихо знову ввести рівно той баг, який лагодили, і позначку перенесли в безумовне місце, з тестом, який її там утримає.
Жоден із них не був спійманий запуском коду. Усі вони були спіймані рецензентом, який міркує про те, чому код працює — і знаходить випадок, де він не працює.
Три частини воріт
Робочий процес за серією не мудрований. Це три звички, застосовувані без винятків.
1. Рев'ю міркує про коректність, а не просто запускає код. Тест, що проходить, доводить, що код працює для випадку, про який ви подумали. Рев'ю — це друга, змагальна модель системи, яка питає про який випадок ви не подумали? — другий монітор, корпоративний проксі, транскрипт, що пропускає гілку, клієнт на одну версію позаду. Крок рев'ю в цій серії часто був незалежним рецензентом-агентом, якому доручали спростувати виправлення, а не благословити його. У цій рамці весь сенс: рецензент, який намагається зламати ваше міркування, знаходить діру, повз яку рецензент, що намагається його схвалити, прослизає поглядом.
2. Кожне виправлення поведінки відвантажується з тестом, що пришпилює точний збій. Не тестом, що функція працює — тестом, що цей конкретний баг мертвий. 403 від заблокованого проксі має провалитися в резервний канал; справжній 403 автентифікації — ні. Годинник активності має поставити позначку на транскрипті, який пропускає атрибуцію. Ці тести існують, аби баг не зміг тихо повернутися за пів року, коли хтось рефакторитиме поруч — збій прибитий до підлоги.
3. Збірка нотаризується і перевіряється до відвантаження. Кілька із цих виправлень пройшли від діагнозу до підписаного, нотаризованого, автооновлюваного релізу за один день. Ця швидкість безпечна лише тому, що ворота дисципліновані: діагностика доводить першопричину (реліз із дозволом на мікрофон відвантажив свою діагностику першою), тест пришпилює виправлення, рев'ю спростовує міркування, і лише тоді виходить справжня нотаризована збірка. Строгість — це те, що робить швидкість безпечною, а не те, що з нею розмінюється.
Чому для AI-застосунку це важливіше
Є причина, чому ця дисципліна не підлягає обговоренню саме для інструмента на кшталт GeekBye. Кілька найгидкіших багів у серії були тихо-неправильними, а не гучними падіннями: скриншот, що згодував ШІ неправильний монітор (v2.0.10), транскрипція, зміщена до сміттєвих термінів, так що «speak» вийшло як ім'я (v2.0.11), асистент, що відповідає в неправильному режимі без способу це побачити (v2.0.3 + v2.0.5). Коли ваш застосунок згодовує контекст моделі, неправильний вхід видає впевнено неправильний вихід і ніде жодної помилки. Не можна витестувати вихід зі збоїв, які не кидають винятків. З них треба виміркувати — а рівно для цього й потрібні ворота рев'ю.
Серія, по порядку
Кожен із них — самодостатній розбір одного релізу. Прочитані від початку до кінця, вони — анатомія переведення продукту з «працює» у «заслуговує на довіру».
- Чого насправді варта версія 2: 206 комітів чесних станів — v2.0.0. Фундамент: ніколи не показуй стан, який неправда.
- День, коли наш застосунок задудосив сам себе — v2.0.1 + v2.0.4. Стартовий затор завантажень, що розтоптав наш власний бекенд, і драбина живучості, яку він змусив.
- Спокійне ПЗ: виправлення мерехтіння і чип режиму відповіді — v2.0.3 + v2.0.5. Релізи без функцій, що купували довіру по одній деталі за раз.
- Ваш застосунок на Mac забуває доступ до мікрофона за кожного запуску — v2.0.6. macOS App Translocation і відвантаження діагностики до виправлення.
- Одна CSS-змінна, п'ять раундів рев'ю і тулчейн Swift, який збрехав — v2.0.7. Рівномірна напівпрозорість і бінарник, що змінив розмір, бо документація розійшлася зі скриптом-енфорсером.
- Жива транскрипція, коли фаєрвол блокує WebSocket — v2.0.8. Резервний канал на чистому HTTPS і
403, який сховав би його від нього самого. - Чому ваш AI-нотатник перестає записувати посеред зустрічі — v2.0.9. Таймер простою, що чув лише вас, і падіння, яке могло заблокувати ваш робочий стіл.
- Чому запис екрана захоплює не той монітор — v2.0.10. Баг неправильного дисплея і виправлення, яке пройшло на одному моніторі і провалилося б на двох.
- Чому AI-транскрипція недочуває технічні терміни — v2.0.11. Зміщення мовлення до вашого словника — і регресія, яка зробила гірше, перш ніж стало краще.
Висновок
Досконалість — не стан, якого досягають; це ворота, які тримають. Дев'ять релізів і ті самі три питання за кожного: про який випадок ти не подумав, чи пришпилений точний збій тестом і чи вийшла насправді справжня підписана збірка? Ніщо з цього не гламурне. Усе це — причина, чому GeekBye v2 відчувається спокійним. Якщо ти будуєш ПЗ — AI чи інше — переносна частина не в якомусь одному виправленні. Вона у звичці ставитися до зеленого набору тестів як до початку суперечки, а не її кінця.
Кожен реліз вище доступний через автооновлення. Про продукт, у який складаються ці виправлення, дивись що нового в GeekBye v2.