четверг, 25 февраля 2021 г.

[prog.flame] Тесты как показатель качества?

Сегодня хочется поговорить об одном найденом на просторах Twitter-а высказывании:

В FB уже немного обстебал это изречение. Но тема поднята такая, которую можно обсудить и вполне себе серьезно.

Прежде чем пуститься в рассуждения, сделаю два постулата. Насколько они соответствуют действительности и совпадают с представлениями читателей об окружающей действительности пусть каждый решает сам. Я излагаю собственную точку зрения, которую никому насильно не навязываю и соглашаться с которой не призываю.

Итак:

Качество -- это оценка ценности некоторого изделия.

Тест -- это оценка пригодности некоторого изделия к выполнению своей основной функции (одной из функций).

Соответственно, качество и тесты -- это про разное.

А теперь позвольте растечься мыслею по древу...

Качество как оценка ценности

Оценивая какой-то предмет, например, обычный слесарный молоток, мы можем говорить о высоком или невысоком качестве его изготовления, обсуждая при этом металл, из которого сделана голова молотка, и его состояние, материал, форму и размер рукоятки, её гладкость/шероховатость... И уже исходя из этой оценки мы можем делать выводы о стоимости молотка или о своей готовности платить назначенную за молоток цену.

Важно отметить, что оценка качества -- это отнюдь не бинарное деление на "качество есть" или "качества нет". Как правило, подразумевается наличие нескольких уровней этого самого качества. Именно это позволяет нам говорить "высшее качество", "вполне нормально", "ширпотреб" и/или "совсем дешманское качество".

Это дает нам возможность выстроить шкалу оценок и давать конкретным изделиям оценки на основании этой шкалы. Вроде "качество изготовления этого молотка 8 из 10, а вот этого всего 3 из 10".

Мы можем выбирать критерии для "градуирования" нашей шкалы, делать интегральные оценки и вводить те или иные коэффициенты для увеличения/уменьшения вклада конкретного параметра в итоговую оценку.

Например, у критерия "материал рукоятки" будет один вес, а у критерия "гладкость рукоятки" -- другой.

Т.е. "качество" -- это количественный и измеримый показатель. Который не обязательно должен иметь дискретные значения (вроде "хорошо", "средне", "плохо"), он вполне может быть и дробным значением (вроде 8.85 баллов из 10 возможных).

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

Тесты как оценка пригодности к использованию

Если мы говорим о мейнстриме и о массовом производстве ПО, где практически не применяется формальная верификация и автоматические доказательства корректности реализации, то у нас нет других способов проверить работоспособность написанного ПО кроме тестирования.

Не суть важно, будут ли это unit-тесты, интеграционные тесты, выполняемые вручную тестовые сценарии или же все это вместе взятое.

Важно то, что пока мы не прогнали тесты мы не можем быть уверены в том, что наше ПО работает.

Ну вот вообще.

Мы можем что-то предполагать.

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

Но проверить это при обычной разработке мы можем лишь одним способом: тестированием.

Соответственно, тесты говорят разработчику не о том, насколько хорошо работает его ПО. А о том, работает ли оно вообще или нет.

Когда вообще можно говорить о качестве?

Говорить о качестве можно лишь тогда, когда оцениваемый предмет выполняет возложенную на него функцию. Т.е. молотком, каким бы хорошим или плохим он не был бы, можно забивать гвозди.

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

Только когда оцениваемый предмет может применяться по прямому назначению мы можем оценивать его качество. Только в этом случае оценки "хороший молоток" или "плохой молоток" имеют смысл. Только в этом случае мы можем уходить в детали вроде "хорошее дерево на рукоятке, рукоятка удобной формы, хорошо отшлифована" или "рукоятка слишком скользкая чтобы быть удобной".

Другими словами, тест -- это определение, молоток ли нам достался или нет.

А качество -- это насколько мы довольны молотком.

Т.е. тесты -- это всего лишь фундамент, наличие которого позволяет завести разговор о качестве. Есть тесты? Отлично, давайте теперь смотреть что у нас с качеством. Нет тестов? Говорить попросту не о чем.

Давайте ближе к теме разработки софта

Если же речь идет о программном обеспечении (ПО) и это ПО проваливает тесты, то здесь мы как раз сталкиваемся со штукой, которая не работает, не выполняет свою основную функцию.

Ну действительно, предположим, что у нас есть реализация SHA1, которая проваливает какой-то тест. Ведь этот проваленный тест ставит крест на возможности использования данной реализации. Что означает, что у нас этой самой реализации и нет. Точно так же, как и в случае молотка без ручки: что-то в нашем распоряжении есть, но применять по прямому назначению мы это не можем.

Если тесты не про качество, то что тогда про качество?

Итак, успешно пройденные тесты дают возможность поговорить о качестве ПО.

Но что тогда будет определять качество?

А это уже зависит от самого ПО и от предъявляемых к нему требований.

Это может быть скорость отклика. Пропускная способность. Потребление ресурсов. Общее время, требуемое на выполнение задачи. Точность получаемых результатов. Масштабируемость. Простота конфигурирования и использование. И т.д., и т.п.

Грубо говоря, если вы делаете софт для перекодирования видео, то качество вашего ПО будет тем выше, чем быстрее вы это перекодирование выполняете, чем менее мощное оборудование вам для этого требуется, чем лучше результирующая картинка и т.д.

Но все, конечно же, куда сложнее

Если не брать совсем уж тривиальное и маленькое ПО, то в современном мире программные системы -- это комплексы из разных модулей с кучей разной функциональности. Огромной кучей разной функциональности.

Из чего естественным образом проистекает два очевидных следствия.

Во-первых, всё тестами не покроешь.

Во-вторых, 100% успешное прохождение всех тестов -- это благородная цель, но далеко не всегда достижимая.

В разработке ПО, зачастую, ситуация такая же, как и с ремонтом: нельзя закончить, можно лишь остановить. Так что при выпуске очередной версии временами приходится принимать волевое решение: выкатываем то, что есть сейчас (то, что будет на момент времени Ч), несмотря на существующий процент проваленных тестов. Тоже самое, в принципе, происходит и со списком фич в backlog-е.

Так что в реальной жизни мы можем время от времени оказываться в ситуации, когда мы знаем, что наше ПО в таких-то и таких-то условиях ведет себя неправильно. Т.е., иногда оно не выполняет свою функцию, т.е. непригодно к использованию.

Но мы идем на это потому, что подобные проблемы не являются критичными и затрагивают лишь небольшой процент пользователей.

Да, это неприятно. Но не смертельно.

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

Вместо заключения

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

Вероятно, здесь есть две проблемы. Во-первых, я как-то не так проинтерпретировал сказанное. Во-вторых, автор высказывания мог неудачно сформулировать свою мысль, т.к. твиттер, с его короткими сообщениями накладывает гораздо более жесткие требования к авторам. И справиться с этими требованиями не так-то просто.

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


Так же напомню, что если кто-то хочет воспользоваться моим опытом в разработке ПО, то сейчас это можно сделать.

2 комментария:

Maxim Shulga (aka MaxBeard) комментирует...

Качество просто чуть более многогранная сущность.
С точки зрения пользователя:
Качество — это пригодность к использованию. Делает ли данный продукт то, в чем я нуждаюсь, облегчает ли он мою работу, могу ли я его использовать так, как мне удобно.

С точки зрения разработчика:
Качество — это соответствие специфицированным и собранным требованиям. Делает ли данный продукт все то, что указано в требованиях.

А есть еще такое.
Пример характеристик качества программного продукта:
- функциональность
- производительность
- стабильность
- удобство использования
- безопасность

Но есть еще, например, качество программного кода:
- Понятность
- Изменяемость
- Тестируемость
- Поддерживаемость

Именно поэтому тесты применимы не ко все аспектам качества. Для меня проблема в твите - это то, что сами по себе тесты код не улучшают (если говорить о качестве кода, а не качестве продукта).

eao197 комментирует...

> Качество — это пригодность к использованию.

Ну вот я как раз с этим не согласен. Свое мнение описал в посте, так что не буду повторяться.

Тут еще другой аспект можно затронуть, что "тесты" -- это тоже зонтичное понятие. Т.к. тесты, которые показывают корректность работы, -- это одно. Это как раз бинарная штука.

Но есть, скажем, тесты производительности. Или тесты масштабируемости. Которые, скорее, являются экспериментами по измерению какой-то величины. Что явно отнюдь не бинарная штука.

В своем посте я сосредоточился именно на тестах корректности.