Архив за Сентябрь, 2011

У вас минус три новых сообщения. Продолжение детектива.

Среда, Сентябрь 21st, 2011

эта заметка местами похожа на триллер, местами на детектив, а местами на комедию :)

Исходная статья была опубликована в панбагоне два года назад. Алексей  провел замечательное исследование и очень красиво все изложил. Статья - шикарный материал для самообучения тестировщиков. Рекомендую.

Но почему бы не сделать пересмотр дела?
Отряхнем пыль с книги Андрея Георгиевича Орлова  “Записки автоматизатора. Профессиональная исповедь” и откроем главу про типичнейшие ошибки, допускаемые программистам. Надеюсь, автор не сильно обидится на меня за рекламу его замечательной книги.

Грабли классические

Суббота, десять вечера. Из продовольственного магазина, в котором внедряется пилотный проект складской системы, звонит кладовщик. Едва не плача, он сообщает, что принял товар на склад, а секции его выдать не может, поскольку товар пропал. А если его срочно не продать, то он протухнет.
Приезжаю. Пытаюсь найти товар на складских карточках. Действительно, найти не получается. А приходная накладная есть. В ней все правильно. Смотрю отчет по товародвижению - в нем все на месте. Проверяю суммарные остатки по складу - накладная учтена. То есть товар на складе есть, а вот найти его нельзя. Правда, на этом складе уже восемь тысяч карточек, так что визуально товар не обнаружить, если даже он есть. Уточняю, что делал кладовщик.
- Это новый товар. Я его сначала завел по бумажной накладной в справочник номенклатуры, потом ввел саму накладную. А потом посмотрел на сам товар и понял, что это тефтели, а не котлеты, как написано в накладной.
- И как ты поступил?
- Исправил запись в справочнике номенклатуры. А в накладной все изменилось само.
- Кажется, я понял, - отвечаю я, подумав. - Смотри, - и набираю в строке поиска “котле”. Экран прокручивается, и на нем подсвечивается строчка “Тефтели”. За спиной раздается восхищенное “Ой”, но я в это время уже представляю, что я сделаю с разработчиками в понедельник.
Но воскресенье, предшествующее встрече, их спасает. Я не только никому ничего не пытаюсь оторвать, я даже могу разговаривать, используя только слова литературного русского языка:
- Вы что, название товара записываете на складской карточке?
- Мы только первые пять символов записываем, чтобы поиск шел быстрее.
Тут я становлюсь даже ласковым:
- А что вы делаете, если складские карточки уже созданы, а я наименование в номенклатурном справочнике поменяю?
- Кажется, ничего не делаем.
- То есть если я завел на склад “котлеты”, а потом исправил в справочнике номенклатуры название на “тефтели”, то что я увижу на карточке?
- “Тефтели”.
- А искать мне что нужно?
- “Котлеты”… Наверное, это не совсем правильно…
- Не совсем правильно?
- Согласен, это совсем неправильно. Мы к следующему обновлению переделаем…

Я начал именно с примера, чтобы не пугать читателя высоконаучными словами. Но в приведенном случае были нарушены принципы проектирования баз данных, описанные в классических работах 1970-х годов. Таблица базы “Складские карточки” не находится в третьей нормальной форме. Про это уже столько понаписано, что мне и добавить нечего. Появление новых СУБД и новых способов поддержания зависимостей в базе данных совершенно ничего не меняет: грабли продолжают работать даже при использовании триггеров и джобов (заданий, запускаемых автоматически в определенные моменты суток или через определенные временные интервалы).
Все попытки поддерживать целостность и непротиворечивость данных не на уровне схемы базы, а с помощью программных примочек натыкаются на одно практически непреодолимое препятствие: в достаточно сложных системах вы просто забываете это сделать для некоторых вариантов работы.
Кстати, неумелое использование перечисленных инструментов, на мой взгляд, приводит к последствиям более страшным, чем их полное неиспользование.

Финит а ля комедия. Я готов поставить 10 к 1, что программисты  Invision Power Board денормализовали БД. Иногда это можно делать. Но в этом случае Гигиена Разработки ПО просто таки требует прописать риски соответствующие этой денормализации и аккуратно их обработать. В конкретно этом случае я бы рекомендовал привести БД к нормальной форме и выкинуть часть кода по изменению значения поля. Код локализуется  легко, исправляется тоже тривиально. А возможные проблемы производительности можно при желании полечить кешированием. Это если бы я участвовал в проектировании.

У тестировщика, нашедший ошибку последовательность действий другая. При обнаружении ошибки такого класса нет смысла искать последовательность действий для воспроизведения дефекта. Вероятность того, что проблема именно в денормализации достаточно велика. Зачем тратить время? Его и так не хватает. Соответственно, в зависимости от политики доступа к коду (разрешен ли white box), тестировщик или сам проверяет БД или пишет предположение о денормализации с просьбой проверки БД. Далее ведущий тестировщик, имеющий смежную специализацию (а ведущий тестировщик не может не иметь хоть какой-то смежной специальности) в проектировании может предложить архитектору варианты решений:

  • Нормализация с вычисткой кода. Быстро, просто, соответствует рекомендациям, но нужно посмотреть изменение производительности.
  • Реинжиниринг требований и тщательная проверка всех операций, связанных с личными сообщениями. Очень трудоемко и очень долго.
  • Ежедневный (в момент минимум нагрузки) пересчет этого поля. Решение компромиссное и как всякий компромисс наихудшее.

Тестировщик не должен настаивать на архитектурном решении, но может их предложить. Если его квалификация это позволяет.

И напоследок процитирую отрывок из другой, не менее замечательной книги Б.С. Ванштейна “Ловушки Ферзьбери”:

 - Зачем все эти красоты, когда после 8. Фd5 черные сразу должны сдаться?

***

- Знаете, я тоже заметил, но мне интересно было погонять короля по всей доске, а так в один ход, как-то скучновато. 

- Вот и мне тогда это казалось интересным, но сейчас - немного даже стыдно. Читаю в переводах: “una bonita combination”, “een prachtige kombinatie” … А чего тут “бонита”, чего “прахтиге”? Пошел ферзем на d5 - и дело с концом!