Към съдържанието
wannacode

Защо програмите грешат

Накратко: Човек прави грешка, грешката оставя дефект в изискването или в кода, а дефектът, който се изпълни, става отказ, който клиентът вижда. Тестването търси отказите, но не може да докаже, че дефекти няма.

Проблем

Кой сгреши?

Магазинът пуска промо код „ЕСЕН10“: 10 € отстъпка, веднъж на клиент. След седмица счетоводството вижда клиент, който го е ползвал в три поръчки. 30 € вместо 10 €.

Програмистът казва: „Направих го както пише“. В изискването пише „веднъж на поръчка“. Анализаторът казва: „Така ми го каза собственикът“. Собственикът е сигурен, че е казал „на клиент“.

Кой сгреши? Въпросът е грешен. По-полезно е да видиш, че това са три различни неща, които стават едно след друго.

Идеята

Грешка, дефект, отказ

  • Грешка (error, mistake) е човешко действие: някой разбира, пише или прави нещо погрешно. Анализаторът записва „на поръчка“.
  • Дефект (defect, също bug или fault) е недостатък в работен продукт, оставен от грешката. Дефектът тук е в изискването. После се пренася и в кода, защото програмистът вярно прави написаното.
  • Отказ (failure) е моментът, в който системата прави нещо различно от очакваното, докато работи. Клиентът ползва кода три пъти.

Посоката е винаги тази: грешка → дефект → отказ. Клиентът вижда само отказа. Тестването започва от него и върви назад.

Не всеки дефект става отказ. Ако никой не опита кода втори път, дефектът си стои, без да се вижда.

По-точно, за любопитните

Така ги дава програмата ISTQB CTFL v4.0.1 (раздел 1.2.3, „Грешки, дефекти, откази и коренни причини“). Отказ може да дойде и от условията на средата, без човешка грешка: радиация или електромагнитно поле могат да повредят фърмуера. В магазина това е рядкост.

На работа думата „бъг“ значи и трите, и затова разговорите се объркват. „Има бъг в промо кода“ може да е отказът, който клиентът е видял, или редът в кода, който го причинява.

Идеята

Коренната причина

Защо анализаторът сгреши? Защото клиентът го каза по телефона и никой не го записа. Нямаше и пример: „Мария поръчва днес с кода и утре пак. Какво става?“ С такъв пример „веднъж на клиент“ и „веднъж на поръчка“ щяха да дадат различни отговори на глас.

Това е коренната причина (root cause): защо изобщо е станала грешката. Да се поправи изискването и кодът оправя този дефект. Да се поправи коренната причина (изискванията се пишат с примери и собственикът ги потвърждава) пази и от следващите от същия вид.

Целта на анализа не е да се намери виновен. Целта е процесът да не позволява грешката втори път.

Пробвай

Подреди веригата

Подреди от причината до това, което вижда счетоводството.

  1. Клиентът казва по телефона „кодът важи веднъж на клиент“, никой не го записва
  2. Клиент ползва кода в три поръчки и взима три намаления
  3. Изискването казва „веднъж на поръчка“
  4. Анализаторът пише по памет „веднъж на поръчка“

Пробвай

Грешка, дефект или отказ?

1. В изискването за връщане пише „до 14 дни“, без да казва от кога.
2. Програмистът е уморен и пише „отказвай над 11 бройки“ вместо „над 10“.
3. Клиент слага 11 бройки от един продукт в количката и поръчва.
4. Поръчка, която вече е изпратена, може да се откаже, защото в кода липсва проверка на състоянието. Досега никой не се е опитал.

Идеята

Тестов случай

Как се хваща отказът преди клиента? Пускаш системата в определено положение, правиш нещо и сравняваш с това, което трябва да стане. Записано, това е тестов случай (test case):

Част За промо кода
Предусловия Клиентът вече е ползвал „ЕСЕН10“ в една платена поръчка.
Вход и действия Нова поръчка за 40 €, със същия код.
Очакван резултат Кодът се отказва: „Кодът вече е ползван“. Сумата остава 40 €.

Най-важната част е очакваният резултат, и той идва от изискването, не от програмата. Ако го препишеш от това, което програмата прави днес, тестът ще потвърди и грешките ѝ.

В модула за сценарии същият случай ще се пише като „Дадено … Когато … То …“. Идеята е същата: начало, действие, очакване.

По-точно, за любопитните

Речникът на ISTQB определя тестовия случай като набор от предусловия, входове, действия (където има), очаквани резултати и следусловия, направен по тестово условие. Тестово условие е това, което проверяваш („промо кодът важи веднъж на клиент“), а тестовите случаи са конкретните примери за него. Тук тестов случай е нещо, което може да изпълни и човек. Тестовете в кода от другите курсове са същата идея, написана за машина.

Идеята

Тестът показва, не доказва

Магазинът има 200 теста за количката и всички минават. Значи ли това, че количката е без дефекти?

Не. Значи, че тези 200 случая работят. Пробвай да ги изброиш всичките: 10 бройки от всеки от 500 продукта, с промо код или без, с всяка сума, с всеки начин на доставка. Комбинациите са повече, отколкото ще пуснеш за живота си.

Това е първият от седемте принципа на тестването (testing principles): тестването може да покаже, че дефекти има, но не и че ги няма. Тестът, който минава, намалява вероятността за скрит дефект. Не я прави нула.

Идеята

Още шест принципа, шест истории

2. Изчерпателното тестване е невъзможно. Всички комбинации на количката не могат да се пуснат. Затова се избират най-важните: по риск, по граници (49,99 €, 50,00 €), по техниките от модула „Техники за тестов дизайн“.

3. Ранното тестване спестява време и пари. Въпросът „а при точно 50 €?“ на срещата струва минута. След пускането струва поправка, нов тест, нова версия и сърдити клиенти.

4. Дефектите се трупат на едно място. Повечето дефекти в магазина са в промо кодовете и в отказа на поръчка: там, където правилата са много. Там тестваш повече.

5. Тестовете се изтъркват. Едни и същи тестове, пускани месеци наред, хващат само това, което са хващали. Новите дефекти са другаде. Тестовете се обновяват и се добавят нови.

6. Тестването зависи от контекста. Магазин и софтуер за болница не се тестват еднакво. Дори уебсайтът и мобилното приложение на един магазин имат различни рискове.

7. Заблудата за липса на дефекти. Система без известни дефекти пак може да е грешна: ако прави написаното, а написаното не е нужното. Тук верификацията мина, а валидирането не е правено.

По-точно, за любопитните

Принципите са от ISTQB CTFL v4.0.1, глава 1.3. На английски: testing shows the presence, not the absence of defects; exhaustive testing is impossible; early testing saves time and money; defects cluster together; tests wear out; testing is context dependent; absence-of-defects fallacy.

В по-старите програми петият се казваше „парадоксът на пестицида“ (pesticide paradox): като насекомите, които свикват с отровата. Натрупването на дефекти (четвъртият) е пример за принципа на Парето: малка част от модулите държи голяма част от дефектите.

Упражнение

Кой принцип?

1. Познай принципа. Всяка история е от магазина. Кой от седемте принципа описва?

1. Магазинът тества количката с Chrome на компютър. Мобилното приложение на същия магазин тества с телефони, слаба мрежа и прекъсване по средата на плащането.
2. Седем от десетте дефекта за последната година са в промо кодовете. Тестерът започва новия цикъл от тях.
3. Набор от 40 теста за доставката минава зелен вече година. Миналия месец излязоха три отказа при доставка до офис, който тестовете не покриват.
4. Новата страница за плащане е без нито един известен дефект. Клиентите обаче се отказват, защото иска регистрация преди плащането.
5. Въпросът „а при точно 50 €?“ се задава на срещата за изискването. Поправката отнема една минута, вместо седмица след пускането.

Тест

Провери се

1. Коя е правилната посока?
2. Всичките 200 теста минават. Какво можеш да кажеш?
3. Кое НЕ е част от тестовия случай?
4. Дефект в кода, който никога не се изпълнява, е…
5. Защо се търси коренната причина?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·