Разберем на примере: есть у нас какой-нибудь массив, и есть к нему тест кейс, что при добавлении нового элемента размер массива увеличивается на единицу, подгоняя его под тест можем дойти до такого кода:
def add(element) {
size++;
}
<pre>
Тест кейс проходит на ура, но от реальности далековато.
Это называется плохое покрытие.
То есть покрыт побочный функционал, но главный не покрыт.
Естественно, абсолютно все не покроешь, но все ключевые моменты должны быть оттестированы.
Покрытие, я уверяю вас, тут будет 100%. Тут дело в том, что данный код, подогнан под данный тест кейс и точка.
Уверяю вас, что в разработке случается такое, когда некоторые личности, несмотря на то, что на один и тот же юнит (класс\метод\строчку кода и т.д) могут быть десятки тест кейсов, все равно умудряются подогнать кусок кода для того, что бы он проходил тесты.
В итоге получаем 100500 тест кейсов, близкое к 100% покрытие кода, но открываешь некоторые методы и от ужасаешься от количества костылей. А некоторые еще и с комментариями // for blaBlabalaBlablabla test
Вот обратите внимание:
— формулировка задачи: «нужно сделать добавление элемента в массив»
— тест-кейс: «при добавлении элемента длина массива увеличится на единицу».
Видите разницу?
Там обязательно должен быть тест на то, что этот элемент попал в массив, а вместо этого проверяется увеличение длины.
Вот за это мне нравится схема BDD и записи как в том же RSpec или Cucumber.
Вы описываете задачу почти на русском языке и это становится тестом. Здесь сразу было бы видно, что написана фигня, не имеющая отношения к делу.
думаю, что проблема в том, что для реальной задачи (сложнее, чем добавление элемента в массив) не так-то просто подобрать все возможные тест-кейсы. Закрадется какой-нибудь маленький нюанс, который просто никому не придет в голову, и ни описание на человеческом языке, ни проверки другими специалистами ничего не выявят, пока не случится реальность.
Разработка авиационного софта не допускает таких выкрутасов. Изменение кода будет проверено как минимум еще 1-2 инженерами, которые будут проверять только соотвествие кода требованиям, но не тесту. Если код не будет соответсвовать требованиям — он не пройдет. Если будут изменены требования, то в процесс ревью будут втянуты как минимум еще 2 человека: специалист по верификации и специалист по безопасности.
Никто с этим не спорит. Думаю, что в боинге или аирбасе такое вряд ли допустимо, там на каждом уровне перепроверяют все раз по двадцать. Да и менеджера нет который подбегает и кричит: «Бросай все, тут надо вот заплить XXX еще вчера надо было, ты почему с работы вообще вовремя ушел?! Запиливай давай прямо сейчас».
Может немного не в тему, но мне вспомнился один анекдот:
Преподаватель студентам-программистам:
— Код программы надо писать так, чтобы не бояться за его работоспособность. Представьте, что вы разработали систему автопилота самолета. Проходит некоторое время и вы собираетесь лететь в другой город. Садитесь в самолет, выходит стюардесса и объявляет, что этот самолет оборудован новейшей системой автопилота, разработанной компанией %company_name%. Вы понимаете, что это ВЫ ее писали. Какова будет ваша реакция?
Все в аудитории, кроме одного парня, сказали, что откажутся лететь на этом самолете и немедленно покинут борт самолета.
Только один парень сказал, что останется. Потому что, если систему писал именно он, то самолет вообще с места не тронется и бояться нечего.
Особенно если разработка еще продолжается. Почувствовать, как система ведет себя «в поле», понять, во что реально воплотилось запрограммированное поведение, а заодно и попытаться угадать, какие куски кода сейчас работают, и что и почему они делают — должно быть интересно.
Правда, когда я смотрел фильм, про который было известно, что в создании использовался наш сканер, то почти не следил за сюжетом, а пытался увидеть характерные артефакты на элементах пейзажа. Не увидел — художники поработали хорошо :)
кусок анекдота:
Повар: я всегда пробую все новые блюда первый.
Архитектор мостов: я всегда стою под мостом когда по нему первый раз едет поезд.
Программист: нууу, я могу рядом постоять…
Представьте, что у Вас написана уйма тест кейсов. Затем Вы начинаете генерировать случайные строки текста до тех пор пока одна из них не скомпилируется в программу, которая пройдет все Ваши тесты.
Представляете что оно Вам там нагенерит? Осмелитесь ли Вы сесть в самолет, в который «зашита» такая программа?
2 варианта:
— тесты предусматривают действительно 100% покрытие всех ситуаций — что нереально — но можно безопасно садиться в самолет
— нет, потому что там халтура.
А давайте я чуть по-другому сформулирую. У нас есть тест-кейсы, которые описывают все возможные ситуации, которые могут произойти, и то, что должно происходить при них, а потом constraint solver генерирует код, удовлетворяющий этим параметрам. Почему бы и нет?
«Тестами». Constraint solver не будет хорошо работать на тестах с фиксированными данными; ему нужны параметрические тесты ≅ уравнения, которыми непрерывную функцию задать элементарно.
Ничего сверхъестественного.
Требования описывают поведение системы в нештатных ситуациях. Инженеры групп верификации пишут миллион тест кейсов по ним. Пишутся тесты для нештатной нагрузки, прогоняются сначала на эмуляторе, потом на реальном железе. Реальное железо при этом тоже находится под управлением виртуальной машины, ибо самолет нам никто не даст.
Слабых мест достаточно: на что-то не было требования, какое-то требование неполно покрылось тестами, какие-то тесты проседают от недостатка соответствия окружения реальному железу. Поверьте, сертификация действительно весьма сурова, но сроки срываются сплошь и рядом.
А учитывая, что программный код имеет тенденцию быть использованным бесчестное количество раз и, будучи написанным единожды, может всплыть в абсолютно неожиданных проектах, быдлокодерство даже в самой завалящей никому-не-нужной-кроме-нашей-фирмы программе это преступление.
Реюз кода в авионике это нормально: считается (и абсолютно заслуженно), что код, имеющий большое количество часов налета, безопаснее полностью нового. Другое дело, что реюз должен быть крайне аккуратным
На это есть класс софта (точнее систем), называемый life-critical (навигация, реанимация, аэс и аналогичные), к которому подпускаются только команды уровней эдак CMM4-CMM5.
Если кто-то из заказчиков такого класса поручил кодировать быдлу, то по статье «попил с отягчающими» его можно решительно четвертовать.
Если это про.б команды уровня CMM5, то казнить либо сертификатора, давшего недакватный уровень команде, либо ответственных на строне подрядчика, сфальсифицировавших сертификацию в придачу к «преступной халатности».
В общем, тут вопрос в неразрывном делегировании ответственностей — пассажиры перевозчику, перевозчик производителям, производители субподрядчикам, и т.д.
Виновный (не крайний) всегда существует.
Но это всё касается life-critical.
Остальные системы не так опасны и там можно применять прогрессивные методици разработки ;-)
Управление компьютером может быть вдвойне ненадежным, потому что программу пишет человек или группа людей. Это если говорить о «классическом» программировании. В ответственных применениях программное обеспечение верифицируется с помощью специальных математических средств. Но, к сожалению, пока не всегда есть возможность использовать верификацию, а иногда и просто невозможно.
Верифицировать можно не только при помощи математических средств.
Есть несколько стандартов, которые помогают при помощи различных мер снизить интенсивность отказов до некоторого определенного значения.
Да, возможно. Но для программного обеспечения, используемого в ответственных применениях, недопустимо иметь шанс отказа, по крайней мере в программе. Она либо работает, либо нет. А использование отладки или других подходов/стандартов показывает наличие ошибок, а не их отсутствие.
Не бывает продуктов без ошибок :)
Вопрос тут в допустимом и недопустимом риске. Если отказала программа — плохо, но не страшно, если не привело к страшным последствиям.
Есть целое направление, в котором исследуются подобные вопросы — функциональная безопасность. Основная идея в том, что мы не можем сделать абсолютно надежный продукт, но можем снизить интенсивность отказов до определенного уровня (не абстрактного, а заданного в самом начале создания продукта) при помощи конкретного набора мер.
Продуктов без ошибок не бывает, так это комплексное устройство (если мы говорим о электронном изделии). А программы без ошибок бывают. Еще раз скажу, что если мы говорим в контексте «классического» программирования, где постоянно отлавливаем ошибки в приложении — тут да, можно каких угодно вероятностей насчитать. Но если говорим о логическом управлении — тут ошибок не должно быть. Например, сейчас активно развивается направление автоматного программирования, для которого существуют различные методики верификации.
> Но если говорим о логическом управлении — тут ошибок не должно быть
А как это можно подтвердить, что нет ошибок? :)
К тому же — они все равно будут. Есть занятная работа у QXN про гейзенбаги, где утверждается, что когда несколько потоков работает, программа (на практике) получается недетерминированной. Теоретически, доказать отсутствие ошибок можно, но на практике — маловероятно.
навскидку, http://spinroot.com — тут можете писать модели на c-подобном языке, и проверять их корректность. в принципе, ничего вам не мешает рассматривать потом эти модели как программы, и просто запускать их
http://www.prismmodelchecker.org — верификация вероятностных моделей. можете попробовать закодировать там вероятностный протокол (например, Zeroconf или CSMA-CA) и проверить его корректность
http://uppaal.org — а тут можете рисовать автоматные модели в удобном редакторе, а потом проверять корректность их поведения. отлично подходит для систем, работающих в реальном времени (со всякими таймаутами и прочим). ничто вам не мешает генерировать код на основе этих моделей (слышал, есть средства для этого). так что для последователей «активно развивающегося» автоматного программирования — самое оно
и да, за каждым из этих средств стоит много-много теории :)
Это доказывается для машины тьюринга? А как быть для реального компьютера, где ячейка памяти может поменять бит? Или сбой вычислений из-за того, что в корпус самолета ударила молния?
Есть способ устранения таких проблем — полное исключение общей памяти (чтобы процессы не могли портить данные другу), стандартизированные способы коммуникаций между процессами (чтобы не передать управление в случайную точку процедуры), отсутствие побочных эффектов функций (исключение ситуации гонки).
Это реализовано в Erlang`e — в итоге миллионы процессов работают параллельно, управляют сложными системами с аптаймом 99.999999999%.
Чёт вы явно с девятками пошутили. Каждая девятка увеличивает стоимость системы раз в пять-десять. Да и то ваш животворящий ерланг не вытянет надёжность целой системы выше надёжности рейда или хаба, в некоторых находящихся вне зоны полномочий ответственных за систему, но влияющих на неё.
У хостеров публичная информация о надёжности их сервиса предоставлена в таких единицах. Предполагается, что система должна работать бесперебойно (в отношении хостинг-серверов так и есть), соответственно, процент показывает, насколько хорошо это предположение удалось воплотить.
В % от общего времени работы.
Вот работала у вас железяка из 100 минут ровно 99 — значит аптайм 99%.
Если вы скажете, что ваша система работала 99 часов, то это еще ни о чем не говорит — может она проработала 99 часов из 1000 — значит заказчику нужно 10 таких систем, чтобы закрыть все это время.
Я понимаю, откуда возник ваш вопрос — скорее всего вы привыкли видеть строку вида
«2:06PM up 63 days». Я говорю про аптайм — какую часть ожидаемого времени она проработала.
Таки допустимо. Стандарт Do-178 чётко оговаривает допустимую вероятность отказа для каждого типа систем, в том числе и программных. Собственно, чтобы снизить вероятность ошибок, используется резервирование и использование компонентов от разных производителей.
Подобные системы для бортовых компьютеров, как я слышал, пишутся различными компаниями на различных языках программирования, чтобы исключить пересечение ошибок. Те. вероятность ошибки (могу оказаться нубом в теорвере, сорри):
1-(1-X1)*(1-X2)*(1-X3), где Хn — вероятность ошибки в какой-либо с систем.
*сорри, наоборот, Xn — вероятность отсутствия ошибки в строке кода. Грубо говоря сколько процентов кода разработчик пишет без багов.
Например, будем считать разработчиков таких систем очень надёжными, делающими ошибки лишь в 5% кода (много это или мало?), тогда:
1-(1-0.95)^3=0.000125 (1 ошибка на 10000 строк кода).
по-моему 3 катастрофы подтверждают надежность компьютера как центрального элемента управления летательным аппаратом.
А вот вам список авиакатастроф на территории СНГ, где в 95% случаев виной есть человек http://www.mak.ru/russian/investigations/investigations.html
Техника очень редко подводит, поэтому задача авиации ныне — как только возможно минимизировать участие человека в процессе управления, оставить ему лишь контролирующую роль.
Одно из принципиальных отличий эйрбаса от боинга в том, что в эйрбасе компьютер первичен, т.е. пилот не просто физически не может делать многие вещи — компьютер ему не даст и отключить его нельзя. В этом компьютере еще много таких «прикольных» процедур, когда пилот не в состоянии повлиять на ситуацию.
Это отражает общий тренд.
Пилоты все больше летают на самолете как на симуляторе — тем самым теряют летные навыки. А значит их полет на компьютере может оказаться более безопасным.
Кто-то несогласен?
Кстати, могу порекомендовать очень классный журнал — бывший военный летчик, сейчас гражданский пилот и очень хорошо пишет — читается на одном дыхании: letchikleha.livejournal.com/
Эта фраза как раз у него взята — а он человек в теме.
Ну это понятно — слишком дорого учить пилота авиалайнера, как пилота истребителя. Когда стоимость подготовки боевого пилота чуть ли не догоняет стоимость истребителя. Ну хорошо, пусть не истребителя, но штурмовика.
Десяток лет обучения и нехилый отсев… Слишком дорогое удовольствие ;)
Оставайтесь пристегнутым во время всего полета, а не только при взлете/посадке. Головой багажную полку можно пробить не только из-за ошибки системы, но и скажем из-за попадания в воздушную яму.
Там в отчёте, кстати, есть целое исследование на тему как пристёгивать ремень, на какое место и насколько туго.
Некоторые пассажиры, несмотря на то что были пристёгнуты, умудрялись вылететь из кресла.
Я кстати выработал в себе привычку оставаться прстегнутым в полете, после того как прочитал "Раздумья ездового пса" Ершова.
На юге посветлело. Фронт кончался, проглянула полоска вечерней зари, и мы приняли решение идти домой по трассе Канск — Красноярск.
Где-то в районе Заозёрного дорогу нам ещё преграждал небольшой хвост, как раз на нашей высоте, и мы запросили снижение с 1200 до 900 м, норовя поднырнуть. Уже прямо по курсу виден был закат, и только этот хвост, южная оконечность фронта, вуаль, вроде бы ничем не угрожающая нам, тянулась на юг ещё километров на полсотни.
Мы снизились; получалось, что пройдём как раз под нижней кромкой. Командир из осторожности снизился ещё на пятьдесят метров, хотя в этом и не виделось особой нужды.
Какой-нибудь километр пути. Десять секунд — и мы на свободе: дальше чисто, оранжевый закат на полнеба; а на севере…но мы уже убежали.
Хорошо, что мы выработали привычку в полёте быть всегда пристёгнутыми. Самолёт выдернуло из-под нас так резко, что мелочь из незастёгнутого кармана рубашки фонтаном брызнула в потолок и разлетелась по кабине. Грузный командир пушинкой взлетел под потолок, выпустив штурвал, но удержался не слишком затянутым ремнём; я пристегнулся потуже и усидел, а вот слабо затянувший ремень бортмеханик от рывка растянул поясницу. Вдобавок ещё два амбарных замка — от входной двери и двери пилотской кабины, — болтающиеся на трубке его сиденья, сгуляли в потолок и оттуда рикошетом проехались ему по лысине. Радист не пострадал, упёршись ногами в перегородку своей тесной каморки.
Самолёт провалился всего-то метров на пятьдесят. Акселерометра на нем не было, и не известно, какую отрицательную перегрузку выдержало его толстое крыло.
И все. Радист сходил в салон. Пассажиры сидели очень смирно. Глаза у всех были круглые, а лица мокрые от пота и очень грязные: от броска сорвало и перевернуло панели пола, и вся грязь и пыль, взлетевшая с них, медленно оседала на лица разом взмокших людей. Парень на последнем кресле засунул руку под ремень своей подруги и до посадки не отпускал.
Этим уже ничего насчёт ремней объяснять не надо.
Кстати очень хорошо человек про авиацию пишет, всем рекомендую, кто не знаком.
>>Кстати очень хорошо человек про авиацию пишет, всем рекомендую, кто не знаком.
Это точно. Взахлеб читал. Отлично описывает теоретическую часть, перемежжая все это историями из своей практики.
+1 читал с большим удовольствием. На всю жизнь запомнил понятие «Рубеж». Это граница, которую рассчитывается до взлета, не помню уже, штурман или второй пилот вычисляют. При разгоне самолета, после того, как сказано слово «Рубеж», чтобы не случилось, хоть взрыв в салоне, хоть отказ двигателя, будут взлетать, так как это означает, что для остановки полосы уже не хватит. До этого момента при ЧП будут тормозить.
Вы, вероятно, путаете с ВПР — высота принятия решения. Такая действительно есть, но не при взлёте, а при посадке: на ВПР командир корабля обязан принять и озвучить решение — продолжать ли посадку, или уходить на второй круг.
Перед каждым взлётом рассчитываются три скорости: V1, Vr и V2. V1 — это скорость принятия решения о взлёте, как описано выше, Vr — скорость подъёма передней стойки шасси и V2 — скорость отрыва самолёта
Летание по интуиции, нестрогое выполнение правил, советский CRM, «профессионализм» (излишняя уверенность в собственных умениях, которая приводит к катастрофам).
В конце концов, насколько я помню (читал много лет назад), он пишет, что сам несколько раз чуть не попадал в катастрофу, но каждый раз проносило.
Это было на истрибителе с аппаратурой от Мотороллы в районе Мертвого моря(уровень которого ниже уровня океана), программистам просто в голову не могло прийти что истрибитель будет летать ниже уровня океана.
Значит хреново была поставлена задача.
В требованиях к самолету должно было быть написано:
— допустимый диапазон высоты полета над уровнем моря, м: от –420… до 15000
Не знаю, как там кто ставит задачи и пишет код, а я всегда проверяю входные данные на допустимость. Тем более, когда на входные данные нужно делить. И это я пишу банальный код для микроконтроллеров, управляющих безделушками типа сервомашинок, LCD, SD-карточки и пр. Если бы я писал жизненно важный код, у меня, пожалуй, код проверок был бы больше по объёму, чем основной.
Как минимум, продолжение полёта. Естественно, я сейчас не могу сказать, чтобы именно я бы написал в такой ситуации, потому уже что знаю, что означает -100 метров.
Не зря говорят всегда — не выпендривайтесь, оставайтесь пристегнутыми в течение всего полета. Часто попадаются соседи по креслу, которые демонстративно отстегивают ремень, как только гаснет табло «пристегните ремни»…
Блок-схема и графики в JPG? Мне внезапно покажется страшным летать на современных самолётах, если так сохранил кто-то, занимающий высокие места в авиации.
Как человек, занимающийся разработкой и верификацией авиационного софта, испытываю крайнюю степень изумления от комментариев людей, которые пытаются проецивать разработку энтерпрайз систем на разработку life-critical систем.
Поверьте, процесс разработки этого софта гарантирует крайне высокие показатели по отказоустойчивости бортовых систем. Почему произошел этот отказ — наверное надо разбираться, хотя виновного нам не назовут, естественно.
Могу сказать только одно: по официальным данным начиная с 90х благодаря введению квалификационных требований к процессу разработки бортового ПО ни одной аварии по вине сбоя ПО не произошло.
Главный докуент — DO-178B, но его вы вряд ли сможете найти в открытом доступе. Он собственно описывает цели, которые должны быть достигнуты в процессе разработки.
А вот методы как таковые не описаны нигде. Это — одна из проблем компаний, которые только начинают по этому стандарту работать: там и так много бюрократии, да еще и непонятно как эту бюрократию реализовывать.
Не понимаю. О какой ошибке речь?
Алгоритм, проверяющий данные от реальных датчиков, и принимающий решения в терминах «случайный сбой/частые сбои/вообще неисправный датчик» только на основе этих данных, по своей природе является эвристическим. Он использует какую-то оценку вероятностей тех или иных сценариев (или классов сценариев), которые смогли предусмотреть разработчики. Как и всякую эвристику, этот алгоритм можно обмануть. И даже заставить отключить исправный датчик, если неисправный его хорошо обдурит своими данными. Эвристический алгоритм может быть более или менее надежным, но абсолютно надежным он не будет. И более того, чем лучше он работает в типичных ситуациях, тем более катастрофическим будет результат, когда ситуация выходит за пределы его применимости. Так что какие тесты? Какие проверки? Они, конечно, необходимы, но описанных в статье ситуаций они не исключат. И то, что «в новой версии прошивки эта проблема была устранена», оптимизма у меня не вызывает. Потому что могла появиться другая, более вероятная ситуация, при которой новый алгоритм (являющийся, как и старый, правильным), приведет к столь же непредсказуемому поведению.
Алгоритмическая ошибка привела к аварии самолёта