ПОЗНАВАТЕЛЬНОЕ Сила воли ведет к действию, а позитивные действия формируют позитивное отношение Как определить диапазон голоса - ваш вокал
Игровые автоматы с быстрым выводом Как цель узнает о ваших желаниях прежде, чем вы начнете действовать. Как компании прогнозируют привычки и манипулируют ими Целительная привычка Как самому избавиться от обидчивости Противоречивые взгляды на качества, присущие мужчинам Тренинг уверенности в себе Вкуснейший "Салат из свеклы с чесноком" Натюрморт и его изобразительные возможности Применение, как принимать мумие? Мумие для волос, лица, при переломах, при кровотечении и т.д. Как научиться брать на себя ответственность Зачем нужны границы в отношениях с детьми? Световозвращающие элементы на детской одежде Как победить свой возраст? Восемь уникальных способов, которые помогут достичь долголетия Как слышать голос Бога Классификация ожирения по ИМТ (ВОЗ) Глава 3. Завет мужчины с женщиной 
Оси и плоскости тела человека - Тело человека состоит из определенных топографических частей и участков, в которых расположены органы, мышцы, сосуды, нервы и т.д. Отёска стен и прирубка косяков - Когда на доме не достаёт окон и дверей, красивое высокое крыльцо ещё только в воображении, приходится подниматься с улицы в дом по трапу. Дифференциальные уравнения второго порядка (модель рынка с прогнозируемыми ценами) - В простых моделях рынка спрос и предложение обычно полагают зависящими только от текущей цены на товар. | Лекция №6 Конфигурационное управление ПроблемаВсем известно, что на крупных промышленных предприятиях, в магазинах, книжных издательствах и пр. существуют склады. Основная задача склада – обеспечить хранение и доступ к материальным активам: товарам, изделиям, книгам и пр. То есть различных материальных активов становится так много, что необходима специальная служба по их учету. Оказывается, что не достаточно складывать, например, все, имеющиеся в книгоиздательстве книги в специальную комнату и выдавать их владельцам тиража, когда они за ним придут. Книг оказывается очень много, а процедура выдачи тиража – не совсем тривиальной. Нужно, чтобы владелец принес большое количество сопроводительных документов, и все они должны быть проверены перед выдачей книг. А на самом складе необходимо поддерживать порядок, чтобы было возможно быстро найти нужные книги (как показывает опыт, они могут там довольно долго находиться). Еще более сложная процедура работы с книгами в библиотеке – там добавляются еще каталоги, распределенные книжные хранилища, необходимость поддерживать хорошее состояние книг, а также контролировать возврат их в библиотеку после определенного срока. Аналогичным образом работает склад на любом заводе, фабрике и т.д. Рассмотрим теперь проект по разработке программного обеспечения. Что в нем является аналогом материальных активов на обычном производстве? Определенно, не столы и стулья, которыми пользуются разработчики. И даже не компьютеры, запчасти к ним и прочее оборудование. Учета и контроля, сродни складскому, требуют файлы проекта. В программном проекте их очень много – сотни и тысячи даже для относительно небольших проектов. Ведь создать новый файл очень легко. Многие технологии программирования поддерживают стиль, когда, например, для каждого класса создается свой отдельный файл. Файл– это виртуальная информационная единица. В чем главное отличие файла от материальных единиц учета? В том, что у файла может быть версия, и не одна, и породить эти версии очень легко – достаточно скопировать данный файл в другое место на диске. В то время как материальные предметы существуют на складе сами по себе, и для них нет понятия версии. Да, может быть несколько однотипных предметов, разных заготовок изделия различной степени готовности. Но все это не то….. А версия файла – это очень непростой объект. Чем одна версия отличается от другой? Несколькими строчками текста или полностью обновленным содержанием? И какая из двух и более версий главнее, лучше? К этому добавляется еще и то, что многие рабочие продукты могут состоять из набора файлов, и каждый из них может иметь по несколько версий. Как собрать корректную версию продукта? В итоге в программном проекте начинают происходить мистические и загадочные события. Тщательно оттестированная программа на показательных испытаниях не работает Функциональность, о которой долго просил заказчик и которая была, наконец, добавлена в продукт, и новая версия торжественно отослана заказчику, таинственным образом исчезла из продукта. На компьютере разработчика программа работает, а у заказчика – нет…. Разгадка проста – все дело в версиях файлов. Там, где все хорошо, присутствуют файлы одной версии, а там, где все плохо – другой. Но беда в том, что "версия всего продукта" – это абстрактное понятие. На деле есть версии отдельных файлов. Один или несколько файлов в поставке продукта имеют не ту версию – все, дело плохо. Необходимо управлять версиями файлов, а то подобная мистика может стать огромной проблемой. Она серьезно тормозит внутреннюю работу. То разработчики и тестеры работают с разными версиями системы, то итоговая сборка системы требует специальных усилий всего коллектива. Более того, возможны неприятности на уровне управления. Различные курьезные ситуации, когда заявленная функциональность отсутствует или не работает (опять не те файлы послали!), могут сильно портить отношения с заказчиком. Недовольный заказчик может потребовать даже денежной компенсации за то, что возникающие ошибки слишком по долгу исправляются. А будет тут не долго, когда разработчики не могут воспроизвести и исправить ошибку, так как не могут точно определить, из каких же исходных текстов была собрана данная версия! Итак, становится понятно, что в программных проектах необходима специальная деятельность по поддержанию файловых активов проекта в порядке. Она и называется конфигурационным управлением. Выделим две основные задачи в конфигурационном управлении – управление версиями и управление сборками. Первое отвечает за управление версиями файлов и выполняется в проекте на основе специальных программных пакетов – средств версионного контроля. Существует большое количество таких средств – Microsoft Visual SourceSafe, IBM ClearCase, cvn, subversion и др. Управление сборками – это автоматизированный процесс трансформации исходных текстов ПО в пакет исполняемых модулей, учитывающий многочисленные настройки проекта, настройки компиляции, и интегрируемый с процессом автоматического тестирования. Эта процедура является мощным средством интеграции проекта, основой итеративной разработки. Единицы конфигурационного управления Так чем же мы управляем в рамках этой деятельности? Любыми ли файлами, которые имеются в проекте? Нет, не любыми, а только теми, которые изменяются. Например, файлы с используемым в проекте покупным ПО должны себе спокойненько покоиться на CD-дисках или в локальной сети. Книги, документы с внешними стандартами, используемыми в проекте (например, в телекоммуникациях очень много разных стандартов на сетевые интерфейсы) и пр. также должны просто храниться там, где каждый желающий их может взять. Как правило, такой информации в проекте немного, но, разумеется, она должна быть в порядке. Однако ради этого специальный вид деятельности в проекте не нужен. Итак, конфигурационное управление имеет дело с меняющимися в процессе продуктами, состоящими из наборов файлов. Такие продукты принято называть единицами конфигурационного управления (configuration management items). Вот примеры: – пользовательская документация; – проектная документация; – исходные тексты ПО; – пакеты тестов; – инсталляционные пакеты ПО; – тестовые отчеты. У каждой единицы конфигурационного управления должно быть следующее. Структура – набор файлов. Например, пользовательская документация в html должна включать индекс-файл и набор html-файлов, а также набор вынесенных картинок (gif или jpeg-файлы). Эта структура должна быть хорошо определена и отслеживаться при конфигурационном управлении – что все файлы не потеряны и присутствуют, имеют одинаковую версию, корректные ссылки друг на друга и т.д. Ответственное лицо и, возможно, группу тех, кто их разрабатывает, а также более широкую и менее ответственную группу тех, кто пользуется этой информацией. Например, определенной программной компонентой могут в проекте пользоваться многие разработчики, но отвечать за ее разработку, исправление ошибок и пр. должен кто-то один. Практика конфигурационного управления – кто и в каком режиме, а также в какое место выкладывает новую версию элемента конфигурационного управления в средство управления версиями, правила именования и комментирования элемента в этой версии, дальнейшие манипуляции с ним там и пр. Более высокоуровневые правила, связанные, например, с правилами изменения тестов и тестовых пакетов при изменении кода. Однако, где-то здесь лежит водораздел между конфигурационным управлением и иными видами деятельности в проекте Автоматическая процедура контроля целостности элемента – например, сборка для исходных текстов программ. Есть не у всех элементов, например, может не быть у документации, тестовых пакетов. Элементы конфигурационного управления могут образовывать иерархию. Пример представлен на рис. 6.1.  Рис. 6.1. Управление версиями Управление версиями файлов.Поскольку программисты имеют дело с огромным количеством файлов, многие файлы в один момент могут быть необходимы нескольким людям и важно, чтобы все они постоянно составляли единую, как минимум, компилирующуюся версию продукта, необходимо, чтобы была налажена работа с файлами с исходным кодом. Также может быть налажена работа и с другими типами файлов. В этой ситуации файлы оказываются самыми младшими (по иерархии включения) элементами конфигурационного управления. Управление версиями составных конфигурационных объектов. Понятие "ветки" проекта. Одновременно может существовать несколько версий системы – и в смысле для разных заказчиков и пр. (так сказать, в большом, настоящем смысле), и в смысле одного проекта, одного заказчика, но как разный набор исходных текстов. И в том и в другом случае в средстве управления версиями образуются разные ветки. Остановимся чуть подробнее на втором случае. Каждая ветка содержит полный образ исходного кода и других артефактов, находящихся в системе контроля версий. Каждая ветвь может развиваться независимо, а может в определенных точках интегрироваться с другими ветвями. В процессе интеграции изменения, произведенные в одной из ветвей, полуавтоматически переносятся в другую. В качестве примера можно рассмотреть следующую структуру разделения проекта на ветки. V1.0 – ветвь, соответствующая выпущенному релизу. Внесение изменений в такие ветви запрещены и они хранят образ кода системы на момент выпуска релиза. Fix V1.0.1 – ветвь, соответствующая выпущенному пакету исправлений к определенной версии. Подобные ветви ответвляются от исходной версии, а не от основной ветви и замораживаются сразу после выхода пакета исправлений. Upcoming (V1.1) – ветвь, соответствующая релизу, готовящемуся к выпуску и находящемуся в стадии стабилизации. Для таких ветвей, как правило, действуют более строгие правила и работа в них ведется более формально. Mainline – ветвь, соответствующая основному направлению развития проекта. По мере созревания именно от этой ветви отходят ветви готовящихся релизов. WCF Experiment– ветвь, созданная для проверки некоторого технического решения, перехода на новую технологию, или внесения большого пакета изменений, потенциально нарушающих работоспособность кода на длительное время. Такие ветви, как правило, делаются доступными только для определенного круга разработчиков и убиваются по завершению работ после интеграции с основной веткой. Управление сборкамиИтак, почему же процедура компиляции и создания exe dll файлов по исходникам проекта – такая важная процедура? Потому что она многократно в день выполняется каждым разработчиком на его собственном компьютере, с его собственной версией проекта. При этом отличается: набор подпроектов, собираемых разработчиком; он может собирать не весь проект, а только какую-то его часть; другая часть либо им не используется вовсе, либо не пересобирается очень давно, а по факту она давно изменилась; отличаются параметры компиляции. При этом если не собирать регулярно итоговую версию проекта, то общая интеграция может выявить много разных проблем: несоответствие друг другу различных частей проекта; наличие специфических ошибок, возникших из-за того, что отдельные проекты разрабатывались без учете параметров компиляции (в частности, переход в Visual Studio c debug на release версию часто сопровождается появлением многочисленных проблем). В связи с этим процедуру сборки проекта часто автоматизируют, то есть выполняют не из среды разработки, а из специального скирпта – build-скрипта. Этот скрипт используется тогда, когда разработчику требуется полная сборка всего проекта. А также он используется в процедуре непрерывной интеграции (continues integration) – то есть регулярной сборке всего проекта (как правило – каждую ночь). Как правило, процедура непрерывной интеграции включает в себя и регрессионное тестирование, и часто – создание инсталляционных пакетов. Общая схема автоматизированной сборки представлена на рис. 6.2.  Рис. 6.2. Тестировщики должны тестировать по возможности итоговую и целостную версию продукта, так что результаты регулярной сборки оказываются очень востребованы. Кроме того, наличие базовой, актуальной, целостной версии продукта позволяет организовать разработку в итеративно-инкрементальном стиле, то есть на основе внесения изменений. Такой стиль разработки называется baseline-метод. Понятие baselineBaseline – это базовая, последняя целостная версия некоторого продукта разработки, например, документации, программного кода и т.д. Подразумевается, что разработка идет не сплошным потоком, а с фиксацией промежуточных результатов в виде текущей официальной версии разрабатываемого актива. Принятие такой версии сопровождается дополнительными действиями по оформлению, сглаживанию, тестированию, включению только законченных фрагментов и т.д. Этот результат можно посмотреть, отдать тестеровщикам, передать заказчику и т.д. Baseline служит хорошим средством синхронизации групповой работы. Baseline может быть совсем простой – веткой в средстве управления версиями, где разработчики хранят текущую версию своих исходных кодов. Единственным требованием в этом случае может быть лишь общая компилируемость проекта. Но поддержка baseline может быть сложной формальной процедурой, как показано на рис. 6.3.  Рис. 6.3. Baseline может также поддерживаться непрерывной интеграцией. Важно, что Baseline (особенно в случае с программными активами) не должна устанавливаться слишком рано. Сначала нужно написать какое-то количество кода, чтобы было что интегрировать. Кроме того, вначале много внимания уделяется разработке основных архитектурных решений, и целостная версия оказывается не востребованной. Но начиная с какого-то момента она просто необходима. Какой этот момент – решать членам команды. Наконец, существуют проекты, где автоматическая сборка не нужна вовсе – это простые проекты, разрабатываемые небольшим количеством участников, где нет большого количество исходных текстов программ, проектов, сложных параметров компиляции. Лекция № 7 Тестирование Управление качеством Стандартизация в современном бизнесе и промышленности. Развитие мирового рынка привело к тому, что многие товары и услуги стали распространяться по всему миру, стали развиваться глобальные сервисы, в частности, телекоммуникационные, банковские. Для того, чтобы устранить технические барьеры промышленности, торговле и бизнесе, которые возникли вследствие того, что в разных странах для одних и тех же технологий и товаров действовали разнородные стандарты, стали создаваться национальные и международные комитеты по стандартизации. Остановимся на самых известны международных комитетах. 1. 1865 год – образован комитет, который ныне называется ITU (International Telecommunication Union). Сейчас штаб-квартира в Женеве (Швейцария), а ITU является часть ООН. Его основная задача – стандартизация телекоммункационных протоколов и интерфейсов с целью поддержания и развития глобальной мировой телекоммуникационной сети. Самыми известными стандартами ITU являются: ISDN (цифровая телефонная связь, объединяющая телефонные сервисы и передачу данных), ADSL (широко известная модемная технология, позволяющая использовать телефонную линию для выхода в Интернет, не блокируя при этом обычного телефонного сервиса), OSI (модель открытого 7-уровневого сетевого протокола, на которой базируются все современные стандартные сетевые интерфейсы и протоколы; также является стандартом ISO), языки визуального проектирования телекоммуникационных систем, SDL и MSC, влившиеся позднее в UML. Многие стандарты ITU переводятся на русский язык и превращаются в российские стандарты в виде ГОСТов. 2. 1946 год – создана организация ISO (International Organization for Standardization). Цель – содействие развитию стандартизации, а также смежных видов деятельности в мире с целью обеспечения международного обмена товарами и услугами, способствование и развитие сотрудничества в интеллектуальной, научно-технической и экономической областях. К настоящему времени создано около 17 000 стандартов в самых разных областях промышленности – продовольственные и иные товары, различное оборудование, банковские сервисы и т.д. Вот некоторые стандарты. Серия стандартов ISO 9000. Направлены на стандартизацию качества товаров и услуг. Определение качества, определение системы поддержки качества на всех жизненных фазах изделия, товара, услуги (проектирование, разработка, коммерциализация, установка и обслуживание), описание процедур по улучшению деятельности компании, промышленного производства. ISO/IEC 90003:2004 – адаптация стандартов ISO 9000 к производству ПО в русле обеспечения качества в жизненном цикле ПО. ISO 9126:2001 – определение качественного ПО и различных атрибутов, описывающих это качество. Многие стандарты ISO переводятся на русский язык и превращаются в российские стандарты в виде ГОСТов. Имеется много стандартов в области информационных технологий, а также несколько – в области программной инженерии. На соответствие стандартам ISO существует сертификация. В частности, компании сертифицируются на соответствие стандартам ISO 9000, то есть на качественный процесс разработки ПО. 3.1988 год, образование организации ETSI (European Telecommunications Standards Institute), штаб-квартира в г. София Антиполис (Франция). Является независимой, некоммерческой, организацией по стандартизации в телекоммуникационной промышленности (изготовители оборудования и операторы сети) в Европе. Самые известные стандарты – GSM, система профессиональной мобильной радиосвязи TETRA. Остановимся теперь на ряде комитетов, непосредственно связанных с разработкой ПО. 4.1984 год – создание SEI (Software Engineering Institute) на базе университета Карнеги-Меллон в г.Питсбурге (США). Инициатор и главный спонсор – министерство обороны США. Основная задача – стандартизация в области программной инженерии, выработка критериев для сертификации надежных и зрелых компаний (что в первую очередь интересует Минобороны США для выполнения его заказов). Самые известные продукты – стандарт CMM, CMMI, разработки в области семейства программных продуктов (product lines). Эти продукты шагнули далеко за пределы военных разработок США, их использование и развитие стало международной деятельностью. Некоторые продукты SEI стандартизованы также ISO. На соответствие CMM/CMMI проводится сертификация. 5.1963 год – создание IEEE (Institute of Electrical and Electronics Engineers). Ведет историю с конца XIX века, в контексте промышленной стандартизацией в США. Сейчас IEEE международная некоммерческая ассоциация специалистов в области техники, мировой лидер в области разработки стандартов по радиоэлектронике и электротехнике. Штаб-квартира в США, существуют многочисленные подразделения в разных странах, включая Россию. IEEE издаёт третью часть мировой технической литературы, касающейся применения радиоэлектроники, компьютеров, систем управления, электротехники, в том числе (январь 2008) 102 реферируемых научных журнала и 36 отраслевых журналов для специалистов, проводит в год более 300 крупных конференций, принимала участие в разработке около 900 действующих стандартов. 6.1989 год – группа американских IT-компаний (в том числе Hewlett Packard, Sun Microsystems, Canon) организовали OMG (Object Management Group). Сейчас включает около 800-т компаний членов. Основное направление - разработка и продвижение объектно-ориентированных технологий и стандартов, в том числе для создания платформо-независимых программных приложений уровня предприятий. Известные стандарты CORBA, UML, MDA. Все эти комитеты и организации включают программную инженерию в сферу своей деятельности, сотрудничают, выпускают совместные стандарты, используют наработки друг друга и т.д. Стандартизация качества. С точки зрения тестирования ПО нас интересует в этих стандартах стандартизация качества (как контекст тестирования) – сначала выпускаемой продукции, а потом и процессов по ее разработки. Здесь срабатывает идея о том, что качественного результата не создать без качественного процесса. Обеспечение качества является более общим контекстом для тестирования. Качество продукта или сервиса, предназначенного потребителю, определяется в стандарте ISO 9000:2005 как степень соответствия его характеристик требованиям - обязательным или подразумеваемым. Методы обеспечения качества ПО.Не претендуя на абсолютную полноту, перечислим различные способы контроля качества, используемые на практике при разработке ПО. – Наладка качественного процесса, другими словами совершенствование процесса. Для комплексного улучшения процессов в компании (подход technology push) компаниями-разработчиками ПО используются стандарты CMM/CMMI, а также по стандартам серии ISO 9000 (с последующей официальной сертификацией). Применяются и локальные стратегии, менее дорогостоящие и более направленные на решение отдельных проблем (подход organization pull). – Формальные методы1) – использование математических формализмов для доказательства корректности, спецификации, проверки формального соответствия, автоматической генерации и т.д.: - доказательство правильности работы программ, - проверка на моделях определенных свойств (model cheking), - статический анализ кода по дереву разбора программы (например, проверка корректности кода по определенным критериям – аккуратная работа с памятью, поиск мертвого кода и пр.), - модельно-ориентированное тестирование (model-based testing): автоматическая генерация тестов и тестового окружения по формальным спецификациям требований к системе) и т.д. На практике применяются ограниченно из-за необходимости серьезной математической подготовки пользователей, сложности в освоении, большой работы по развертыванию. Эффективны для систем, имеющих повышенные требования к надежности. Также имеются случаи эффективного использования средств, основанных на этих методах, в руках высококвалифицированных специалистов. – Исследование и анализ динамических свойств ПО. Например, широко используется профилирование – исследование использования системой памяти, ее быстродействие и др. характеристик путем запуска и непосредственных наблюдений в виде графиков, отчетов и пр. В частности, этот подход используется при распараллеливании программ, при поиске "узких" мест. Еще пример – область, называемая "моделирование и анализ производительности" (performance modeling and analysis). Здесь моделируется нагрузочное окружение системы (число одновременных пользователей системы, сетевой трафик и пр.) и наблюдается поведение системы. – Обеспечение качества кода. Сюда относится целый комплекс различных мероприятий и методов. Вот некоторые, самые известные из них. – Разработка стандартов оформления кода в проекте и контроль за соблюдением этих стандартов. Сюда входят правила на создание идентификаторов переменных, методов и имен классов, на оформление комментариев, правила использования стандартных для проекта библиотек и т.д. – Регулярный рефакторинг для предотвращения образования из кода "вермишели". Существует тенденция ухудшения структуры кода при внесении в него новой функциональности, исправления ошибок и пр. Появляется избыточность, образуются неиспользуемые или слабо используемые фрагменты, структура становится запутанной и трудной для понимания. Рефакторинг – это регулярная деятельность по переписыванию кода, но не с целью добавления новой функциональности, а для улучшения его структуры. Рефакторинг появился в контексте "гибких" методов, в данный момент активно поддерживается различными средами разработки ПО. – Различные варианты инспекции кода, например, техника peer code review. Последняя заключается в том, что код каждого участника проекта, выборочно, читается и обсуждается на специальных встречах (code review meetings), и делается это регулярно. Практика показывает, что в целом код улучшается. – Еcть еще такой подход, как "вычитка" кода, используемый, например, при разработке критических систем реального времени. Ею занимаются также разработчики, но их роль в данном проекте – вычитка, а не разработка. Тестирование. Самый распространенный способ контроля качества ПО, представленный, фактически, в каждом программном проекте. Тестирование Тестирование –это проверка соответствия между реальным поведением программы и ее ожидаемым поведением в специально заданных, искусственных условиях. Разберем это определение по частям. Ожидаемое поведение программы. Исходной информацией для тестирования является знание о том, как система должна себя вести, то есть требования к ней или к ее отдельной части. Самым распространенным способом тестирования является тестирование методом черного ящика, то есть когда реализация системы недоступна тестеровщикам, а тестируется только ее интерфейс. Часто это закрепляется и организацией коллектива – тестеровщики оказываются отдельными сотрудниками и в некоторых компаниях они даже принципиально не общаются с разработчиками, чтобы минимально знать реализационных деталей и максимально полно выступить в роли проверяющей инстанции. Существует тестирование методом белого ящика, когда код программ доступен тестеровщикам и используется в качестве источника информации о системе2). Его схема представлена на рис. 7.1.  Рис. 7.1. На этом рисунке видно, что на основе требований к системе создается реализация и тестовая модель системы. Тестирование есть сопоставление двух этих представлений с целью выявить их несоответствия. Чем независимее друг от друга будут эти представления, тем больше прока от их сопоставления. Иначе, если тестеровщики существенно используют информацию о реализации системы при составлении тестов, то они могут невольно внести в тесты ошибки реализации. Найденное при тестировании несоответствие – это еще не ошибка, поскольку сами тестеровщики могли неправильно понять требования, в тестах и средствах тестирования могли быть ошибки. Данный подход закрепляется также и в организации коллективов программистов - тестеровщики, как правило, отделены от разработчиков. Это разные люди, несовместимые роли в MSF. Авторы слышали рассказ об одной американской компании где разработчики и тестеровщики сидели на разных этажах, ходили в разной одежде (тестеровщика в костюмах, разработчики – в свитерах) и начальство не поощряло нерабочие отношения между этими группами. Это, конечно же, крайность, но она еще раз подчеркивает, как важно, чтобы точка зрения на систему у тестеров отличалась от точки зрения разработчиков. Но, конечно, и та и другая должны исходить из общего видения системы – ее требований. Специально заданные, искусственные условия, – те условия, где осуществляется тестирование. При этом ключевым аспектом здесь является наличие тестов – воспроизводимых шагов манипуляции с системой, приводящих к ее некорректной работе. Концепция теста очень важна, так как необходимо не просто обнаружить некорректное поведение системы, а создать и зафиксировать алгоритм воспроизведения ошибки – чтобы повторить его для разработчика или чтобы разработчик сам смог воспроизвести ошибку. Если ошибка не воспроизводится, то нет возможности ее исправить. Тесты могут быть "ручными" и автоматизированными. "Ручной" тест – это последовательность действий тестеровщика, которую он (или разработчик) может воспроизвести и ошибка произойдет. Как правило, в средствах контроля ошибками такие последовательности действий содержатся в описании ошибки. Автоматический тест – это некоторая программа, которая воздействует на систему и проверяет то или иное ее свойство. Автоматический тест, по сравнению с "ручным", можно легко воспроизводить без участия человека. Можно создавать наборы тестов и прогонять их часто, например, в режиме регрессионного тестирования. Кроме того, автоматические тесты можно генерировать по более высокоуровневым спецификациям, например, по формально описанным требованиям к системе. А, например, тесты для компиляторов можно генерировать по формальному описанию языка программирования. Таким образом, преимущества автоматических тестов перед "ручными" очевидны. Поговорим теперь о трудностях автоматического тестирования. Во-первых, для того, чтобы тесты автоматически запускать, нужны соответствующие программные продукты, которые также являются неотъемлемой частью специально заданных, искусственных условий, которые мы сейчас обсуждаем. Их будем называть инструментами тестирования. В их задачу входит запуск теста на системе, "прогон" целого пакета тестов, а также анализ получившихся результатов и их обработка. Кроме того, немаловажной задачей инструментов тестирования является обеспечение доступа теста к системе через некоторый ее интерфейс. Доступ к системе может оказаться затруднительным, например, в силу политических обстоятельств, когда сторонними разработчиками делается подсистема некоторой стратегической системы, и доступ к этой объемлющей системе у разработчиков сильно ограничен. Или в силу аппаратных ограничений – трудно "залезть" на "железку", где работает целевой код системы. Кроме того, часто трудно "бесшовно" тестировать систему, оказывая на нее минимальное воздействие и добираясь при этом до всех аспектов ее функционирования. В целом, настройка и развертка готовых, сторонних тестовых инструментов часто оказывается дорогостоящей и непростой задачей. Разработка своих собственных тестовых инструментов также непроста. Во-вторых, часто возникает проблема ресурсов для автоматического тестирования. Особенно при автоматической генерации тестов: часто есть возможность автоматически сгенерировать очень большое количество тестов, так что если их еще выполнять регулярно, в режиме непрерывной интеграции, то не хватит имеющихся системных ресурсов. При этом качество тестирования может оказаться неудовлетворительным – ошибки находятся редко или вообще не находятся. Дело в том, что количество всех возможных состояний программной системы очень велико, и тестирование не может покрыть их все. На практике, в реальных проектах, определяют критерии тестирования, которые определяют ту "планку" качества, которую необходимо достичь в этом проекте. Ведь хорошее качество стоит дорого и очевидно, что разное ПО имеет разное качество, например, система управления ядерным реактором и текстовый редактор. На практике, часто, качество ПО определяется бюджетом проекта по его разработке. Далее, в силу ограниченности ресурсов на тестирование часто целесообразно бывает определить те аспекты ПО, которые наиболее важны -как для общей работоспособности системы, так и для заказчика. Например, при тестировании Web-приложения, предоставляющего услугу по созданию объявлений о продаже недвижимости, такими критериями были: правильность переходов сложного мастера – в частности, в связи с возможностью переходов назад;целостность введенных пользователем данных о создаваемых объявлениях. Наконец, кроме ограничения количества тестов их отбора важным является их прогон на некоторых (не на всех возможных!) входных данных. Часто здесь применяют принцип факторизации – множество всех возможных входных значений разбивают на значимые с точки зрения тестирования классы и "прогоняют" тесты не на всех возможных входных значениях, а берут по одному набору значений из каждого класса. Например, тестируют некоторую функцию системы на ее граничные значения – очень большие значения параметров, очень маленькие и пр. Часто факторизацию удобно делать, исходя из требований к данной функции, также бывает полезно посмотреть на ее реализацию и "пройтись" тестами по разным ее логическим веткам (порождаемым, например, условными операторами). Виды тестирования. Не претендуя на полноту, выделим следующие виды тестирования. – Модульное тестирование - тестируется отдельный модуль, в отрыве от остальной системы. Самый распространенный случай применения – тестирования модуля самим разработчиком, проверка того, что отдельные модули, классы, методы делают действительно то, что от них ожидается. Различные среды разработки широко поддерживают средства модульного тестирования – например, популярная свободно распространяемая библиотека для Visual Studio NUnit, JUnit для Java и т.д. Созданные разработчиком модульные тесты часто включаются в пакет регрессионных тестов и таким образом, могут запускаться многократно. – Интеграционное тестирование – две и более компонент тестируются на совместимость. Это очень важный вид тестирования, поскольку разные компоненты могут создаваться разными людьми, в разное время, на разных технологиях. Этот вид тестирования, безусловно, должен применяться самими программистами, чтобы, как минимум, удостовериться, что все живет вместе в первом приближении. Далее тонкости интеграции могут исследовать тестеровщики. Необходимо отметить, что такого рода ошибки – "ошибки на стыках" - непросто обнаруживать и устранять. Во время разработки все компоненты все вместе не готовы, интеграция откладывается, а в конце обнаруживаются трудные ошибки (в том смысле, что их устранение требует существенной работы). Здесь выходом является ранняя интеграция системы и в дальнейшем использование практики постоянной интеграции. – Системное тестирование – это тестирование всей системы в целом, как правило, через ее пользовательский интерфейс. При этом тестеровщики, менеджеры и разработчики акцентируются на том, как ПО выглядит и работает в целом, удобно ли оно, удовлетворяет ли она ожиданиям заказчика. При этом могут открываться различные дефекты, такие как неудобство в использовании тех или иных функций, забытые или "скудно" понятые требования. – Регрессионное тестирование – тестирование системы в процессе ее разработки и сопровождение на регресс. То есть проверяется, что изменения системы не ухудшили уже существующей функциональности. Для этого создаются пакеты регрессионных тестов, которые запускаются с определенной периодичностью – например, в пакетном режиме, связанные с процедурой постоянной интеграции. – Нагрузочное тестирование – тестирование системы на корректную работу с большими объемами данных. Например, проверка баз данных на корректную обработку большого (предельного) объема записей, исследование поведение серверного ПО при большом количестве клиентских соединений, эксперименты с предельным трафиком для сетевых и телекоммуникационных систем, одновременное открытие большого числа файлов, проектов и т.д. – Стрессовое тестирование – тестирование системы на устойчивость к непредвиденным ситуациям. Этот вид тестирования нужен далеко не для каждой системы, так как подразумевает высокую планку качества. – Приемочное тестирование – тестирование, выполняемое при приемке системы заказчиков. Более того, различные стандарты часто включают в себя наборы приемочных тестов. Например, существует большой пакет тестов, поддерживаемых компанией Sun Microsystems, которые обязательны для прогона для всех новых реализаций Java-машины. Считается, что только после того, как все эти тесты успешно проходят, новая реализация вправе называться Java. Работа с ошибкамиМежду программистами и тестеровщиками необходим специальный интерфейс общения. Ведь ошибок находится много, их исправление требует времени, и их исправления разработчиками тестеровщики должны удостовериться, что они действительно исправлены. Кроме того, менеджерам нужна статистика по найденным и исправленным ошибкам – это хороший инструмент контроля проекта. Все это изображено на рис. 7.2. Чтобы справиться с этим потоком информации и обеспечить необходимые в работе, удобные сервисы, существует специальный класс программных средств – средства контроля ошибок (bug tracking systems).  Рис. 7.2. Как правило, описание ошибки в системе контроля ошибок имеет следующие основные атрибуты: – ответственного за ее проверку – тестеровщика, который ее нашел и который проверяет, что исправления, сделанные разработчиком, действительно устраняют ошибку; – ответственного за ее исправление – разработчика, которому ошибка отправляется на исправление; – состояние, например, ошибка найдена, ошибка исправлена, ошибка закрыта, ошибка вновь проявилась и т.д. Этот список существенно дополняется в различных программных средствах контроля ошибок, но это основные атрибуты. Использование этих систем давно стало общей практикой в разработке ПО, наравне со средствами версионного контроля и многими иными инструментами. Они включают в себя: – базу данных для хранения ошибок; – интерфейс к этой базе данных для внесения новых ошибок и задания их многочисленных атрибутов, для просмотра ошибок на основе различных фильтров – например, все найденные ошибки за последний месяц, все ошибки, за которые отвечает данный разработчик и т.д.; –сетевой доступ, так как проекты все чаще оказываются распределенными; – программный интерфейс для возможностей программной интеграции таких систем с другим ПО, поддерживающим разработку ПО (например, со средствами непрерывной интеграции – они могут автоматически вносить в базу данных найденные при автоматическом прогоне тестов ошибки). Очень важным при работе с ошибками оказываются различные отчеты, о чем будет подробно рассказано при обсуждении VSTS. |