zHz00 Untitled

четверг, 18 марта 2021
23:59 Идеальное и реальное в тестировании ПО
То, что я не применяю юнит-тесты, не значит, что я не тестирую ПО вообще.

Внёс правку, потыкал -- вроде работает. Обычно при тестировании используешь какие-то типовые значения, которые удобно вводить. Типовые -- это круглые. Но реальность не круглая.

Сохраняю в файл два графика, измеренные одновременно за 2 секунды. Всё замечательно работает. Когда начинаются эксплуатационные замеры, оказывается, что выходной файл периодически не открывается. Сначала я думал, что не открываются слишком длинные файлы, но это оказалось не так.

Для хранения у нас используется собственный формат данных, исторический. Функцию сохранения я взял готовую, написанную предками, и модифицировал под свои нужды. Утилита по считыванию доступна в исходных кодах, что позволило мне запустить отладку и посмотреть, где происходит сбой. Причина оказалась простой -- для второго графика сбивается смещение внутри файла, поэтому он начинает считываться с места, где мусор. Но почему это происходит?

ОКАЗАЛОСЬ

Что когда время некруглое, то в графиках может оказаться разное число точек, которое отличается на единицу. При этом вычисление числа точек для поля "число точек" происходит один раз и по одной формуле, а фактическая запись точек делается в другом месте -- и формула там уже другая. Когда время круглое и количество точек одинаковое -- формулы дают одинаковый результат. А когда время некруглое -- числа разные.

***

Я сам мало знаю о модульном тестировании, но может быть, кто-нибудь из читателей знает? Как вы боретесь с подобными ситуациями? Практикуется ли в модульном тестировании рандомизация входных параметров от запуска к запуску чтобы ловить такие ошибки?

@темы: Программирование, Борьба с техникой

URL
Hамедни был на лобном месте. Получил в лоб. Больше не пой...
Да, если кто не знает ещё... В Краснодаре есть служба т...
Судя по тому как все тормозит, сервер додумался. Ну и в...
http://hsm.com.ua/ Стоит попробовать выделить текст....
Вот тебе и зае*ись!.. Кстати, следующим папой римски...
С 6-го по 11-е мая в районе Абинска будет фестиваль возду...

19.03.2021 в 17:42

19.03.2021 в 17:42
Не уверен, что до конца понял ситуацию. Что за «поле «число точек», и как оно влияет на запись/чтение? У вас в формате нет заголовка, который гласил бы «в этом файле N точек», и читающая сторона сама рассчитывает N?

-- Minoru
URL

19.03.2021 в 17:50

19.03.2021 в 17:50
У меня фреймворк рандомизирует идентификаторы в базе данных, например. Но в самих тестах я ленюсь и леплю статические значения, которые удобно проверять)
URL

19.03.2021 в 18:06

19.03.2021 в 18:06
Minoru

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

Xersareeth, какой фреймворк?
URL

19.03.2021 в 18:15

19.03.2021 в 18:15
zHz00, ruby on rails
URL

19.03.2021 в 19:00

19.03.2021 в 19:00
Окей, понятно. Безотказных способов избежать этой проблемы я не знаю, но есть пара мыслей, как снизить вероятность на такое наткнуться.

Раз это легаси, то имело бы смысл сначала покрыть код тестами, а уже потом что-то менять. Полезно чем-нибудь измерять покрытие и стремиться довести его до 100% — в погоне за последними процентами обычно приходится читать код и плотно думать, и ты мог бы либо просто угадать, что баг существует, либо заметить, что количество точек рассчитывается в двух разных местах (и по-разному).

Ты мог бы нечаянно написать тесты только для случая, когда в файлах равное количество точек, и таким образом прозевать баг (покрытие 100%, а баг есть!). От такого тебя бы спасло ревью кода: второй разработчик мог бы усомниться, почему ты тестируешь только этот случай, и вы бы вскрыли существование бага.

В конце концов, да, ты мог бы написать рандомизированные тесты. Посмотри на rapidcheck и генераторы в Catch2. Для Си я подобных библиотек не знаю. Но там придётся писать генераторы реалистичных данных, для сложных форматов это будет тяжёлой задачей. Кроме того, чем крупнее генератор, тем больше возможностей закодировать в него какие-нибудь предпосылки, например, что в файлах всегда одинаковое количество точек :)

Пользуюсь на практике всеми тремя методами, но баги все равно лезут :(

-- Minoru
URL

19.03.2021 в 19:29

19.03.2021 в 19:29
Xersareeth, веб-приложения делаешь? Или RoR только для тестирования?

Minoru, спасибо за комментарий. За уточнениями я тебе в жаббер написал.
URL

19.03.2021 в 20:34

19.03.2021 в 20:34
zHz00, У меня на RoR веб-интерфейс к базе. А раз уж я его уже использую, то и тестирование в нём запускаю.
URL

20.03.2021 в 11:30

20.03.2021 в 11:30
Поищи по словам property based testing. Вполне возможно, это то, что нужно тебе в этом месте. Важно перед использованием именно серьёзно вкурить и понять матчасть, что именно надо проверять при подобном тестировании.

Мне было лень заморачиваться с библиотеками и я в своём js коде, где подобное требовалось (пара функций - генератор и парсер токенов), набил пачку массивов возможных входов для каждого аргумента, потом сделал на коленке генератор декартова произведения, запускал функцию на каждой строчке и после проверял инварианты выхлопа.
Ну типа так:

В принципе вместо массивов и декартова произведения можно наколхозить генератор рандомных значений с заданными разумными границами для каждого аргумента.
URL
Добавить комментарий

Расширенная форма

Подписаться на новые комментарии