Дефрагментация мозга. Софтостроение изнутри | страница 20
Из элементов стандартизации точно присутствуют коды валют по ISO 4217[18] и, частично, список служб, к которым компонент может обращаться (см., например, каталог служб Financial API). Интерфейс самого компонента не стандартизован, для возможной его замены в будущем без последующей структурной перекройки вашего приложения потребуется обернуть компонент в адаптер (привет, шаблоны!). Это поможет избежать реструктуризации при замене, но не гарантирует работоспособность на том же входном наборе.
Теперь оценим количество состояний, которые необходимо охватить для полноты модульного тестирования, раз уж мы следуем логике разработки «железа». ISO 4217 даёт список из 164 валют. Предположим, что наши входные данные:
• имеют только два знака после запятой;
• значения положительные;
• максимальная величина – 1 миллион;
• дата конвертации всегда текущая;
• мы используем только 10 валют из 164.
Несложный комбинаторный подсчёт показывает, что даже такой сильно урезанный входной набор характеризуется количеством размещений из 10 по 2, помноженным на 100 миллионов входных значений (1 миллион с шагом 0,01):
10>2 × 100 000 000 = 10 000 000 000.
То есть для обеспечения полноты тестирования нашего входного набора потребуется 10 миллиардов проверок! Сравните, например, с микросхемой дешифратора, преобразующего входное 4-разрядное двоичное значение в сигнал на одном из 16 выходов. Входных наборов будет всего 16, а таблица истинности состоит из 16>2 = 256 значений.
На практике программист применит допустимую эвристику и будет тестировать, например, только несколько значений (один миллион, ноль, случайная величина из диапазона) для нескольких типовых конвертаций из 100 возможных, дополнительно проверяя допустимую точность значений на входе. При этом формальный показатель покрытия модульными тестами по-прежнему будет 100 %…
Но это ещё не всё. Микросхема работает с заданной тактовой частотой. Если, например, частота равна 1 МГц, то подав на вход набор значений, вы гарантированно через одну микросекунду получите результат на выходе.
Если же вы подадите набор значений на вход нашего компонента, то время отклика будет неопределённым. Может быть, программа отработает за секунду.
Может быть, зависнет навечно, если не предусмотрен тайм-аут. А если несколько параллельных запросов?
Поэтому вдобавок к модульному тесту необходимо программировать тест производительности (нагрузочный), который тем не менее не гарантирует