Тестът с curl тества не това, което трябва
Заявка към брояча, която пристига без идентификация на браузър, записва в две от дванадесетте места, до които обикновено стига едно преброено посещение. Отговорът е 200. Връща се валидно изображение на брояч. Никъде нищо не казва, че десет от дванадесетте са пропуснати.
За какво е филтърът и какво струва
Броячите тук отделят роботите от хората, а разделянето става по идентификацията, която клиентът сам посочва за себе си. Списъкът с признаци е кратък и нарочно недвусмислен, и curl/ е в него. Също и празната идентификация, с довода, че заявка изобщо без user agent не е браузър.
И двете са правилни. Услугата не греши, когато смята голото curl за робот; то наистина е робот. Проблемът е, че човекът, който пуска curl, обикновено не проверява дали разпознаването на роботи работи. Той проверява дали броенето работи, а неусетно е поискал пътя за роботи.
Какво получава: общият брой посещения за деня нараства с едно, колоната за роботи нараства с едно, и това е всичко. Няма ред за уникален посетител, значи нищо за посетителите. Няма запис в списъка на онлайн посетителите. Няма страница, държава, браузър, операционна система, устройство, час. Частите от системата, които някой наистина би искал да провери, са точно частите, които не са се изпълнили.
Грешката няма симптом
На тази част си струва да се спрем. Тест, който не измерва нищо, обикновено сам се издава: грешка, празен резултат, нула там, където трябва да има число. Тук отговорът е 200. Тялото е истинско изображение на брояч, 3 361 байта. Числото на картинката дори се е увеличило, защото общият брой посещения е едно от двете неща, които наистина са се случили.
Така пробата изглежда успешна. Всичко, което следва от нея — „пътят на броенето работи“, „новата колона се записва“, „промяната не е счупила нищо“ — е извод от изпълнение, което е пропуснало по-голямата част от кода, който е трябвало да провери.
Случи се, докато пишехме това
Първата версия на измерването зад тази публикация поиска /c/<number>. Това не е адресът на изображение на брояч; истинският съдържа дизайна и разширение, /c/<number>-<design>.png. Заявката върна 404.
Скриптът изписа три пъти: записва в 0 от 12 места. Което е вярно и което на пръв поглед изглежда точно като работещ филтър за роботи. 404 беше в изхода, в същата таблица, един ред над нулите. Една минута остана непрочетено, защото нулите бяха интересната част и съвпадаха с очакваното.
Това е същата грешка като тази, за която е публикацията, едно ниво по-нагоре: измерване, което дава правдоподобен отговор по причина, която никой не е проверил. Хваната беше само защото скриптът броеше редове в дванадесет таблици, вместо да се довери на заявката — неуспешна заявка и филтрирана заявка изглеждат еднакво отвън.
Какво да се прави вместо това
Изпращайте идентификация на браузър. Един флаг, -A с истински низ за user agent, и същата заявка записва в десет от дванадесетте места вместо в две.
И бройте нещо от другата страна. Кодът на отговора казва, че заявката е пристигнала; не казва нищо за това какво е направила. За всичко, при което смисълът е в страничния ефект — брояч, опашка, ред в дневник, ред някъде в таблица — пробата трябва да гледа страничния ефект. Преброяването преди и след във всяка засегната таблица отне тук двадесет реда и два пъти превърна двусмислен резултат в недвусмислен: веднъж за филтъра, веднъж за 404.
Две от дванадесетте места останаха празни дори с идентификация на браузър: колоната за роботи, съвсем правилно, и списъкът с препращащи сайтове, който не записа изпратения препращащ сайт. Второто не е обяснено тук, защото още не е проследено. Споменаваме го, защото алтернативата е да публикуваме таблица с единадесет реда и да я наречем дванадесет.