Главная страница
Навигация по странице:

  • 5.7. КЛАССИФИКАЦИЯ ТЕСТОВ

  • 5.8. ОТЛАДКА

  • 5.9. ОПТИМИЗАЦИЯ

  • 1) АЛГОРИТМЫ И ИХ РАЗРАБОТКА 6.1. ПОНЯТИЕ АЛГОРИТМА И ЕГО СВОЙСТВА

  • 6.2. ПРЕДСТАВЛЕНИЕ АЛГОРИТМА И ПСЕВДОКОД

  • Лекции по программированию. Основные понятия классификация программного обеспечения


    Скачать 1.57 Mb.
    НазваниеОсновные понятия классификация программного обеспечения
    АнкорЛекции по программированию.doc
    Дата15.01.2018
    Размер1.57 Mb.
    Формат файлаdoc
    Имя файлаЛекции по программированию.doc
    ТипДокументы
    #14117
    КатегорияИнформатика. Вычислительная техника
    страница5 из 6
    1   2   3   4   5   6

    5.6. АКСИОМЫ ТЕСТИРОВАНИЯ

    Тестирование программных систем в настоящее время остается в большей мере искусством, чем наукой. При проведении тестов рекомендуется придерживаться так называемых аксиом тес­тирования, представляющих собой эвристические приемы. Вот не­которые из них:

    1. хорошим считается тот тест, в котором высока вероятность обнаружения ошибок;

    2. тестирование собственной программы существенно ослож­няется психологическими причинами;

    3. необходимой частью тестов считается описание выходных результатов;

    4. нужно готовить тесты как для правильных, так, и для непра­вильных данных; ,

    1. нельзя тестировать «с лету», наскоком;

    2. необходимо тщательно изучать результаты каждого теста;

    1. по мере обнаружения все большего числа ошибок в про­грамме, возрастает вероятность обнаружения в ней еще большего числа ошибок;

    2. тестирование программ должны осуществлять самые лучшие и опытные программисты;

    3. одной из главных задач разработчиков программы является возможность осуществления ее тестирования;

    1. нельзя изменять программу только с целью облегчить про­цесс ее тестирования;

    2. чем раньше спроектирован тест, тем выше вероятность вы­явления ошибок. Лучше всего готовить тесты еще на этапе проек­тирования системы;

    3. процесс тестирования должен быть документирован и пол­ностью управляем, хаотичность недопустима;

    4. необходимы повторяемость и завершенность тестов;

    5. следует избегать добавления новых тестов уже в процессе тестирования.

    5.7. КЛАССИФИКАЦИЯ ТЕСТОВ

    По условиям их поведения тесты могут быть класси­фицированы следующим образом:

    Доказательство (proof) - попытки найти ошибки в программе путем доказательств на основе математических теорем о правиль­ности программы, безотносительно к внешней программной среде.

    Верификация программы (programverification) - попытка найти ошибки, выполняя программу в тестовой или моделируемой среде.

    Испытание (validation) - попытка найти ошибки, выполняя программу в заданной программной среде.

    Приемо-сдаточные испытания - проверка пригодности про­граммы для эксплуатации; такие испытания обычно проводят под контролем поставщика системы.

    По назначению тесты классифицируются:

    тестирование модуля (автономное тестирование) (moduletesting) — контроль, отдельного модуля в изолированной среде (например, с помощью ведущей программы), инспекция текста модуля на сес­сии программистов, которая иногда дополняется математическим доказательством правильности модуля;

    тестирование сопряжений (integrationtesting) - контроль со­пряжений между частями программной системы, как между ком­понентами в комплексе, так и между модулями отдельного компо­нента (например, у заглушки);

    комплексное тестирование (systemtesting) — контроль и испы­тание системы по отношению к исходным целям. Осуществляется с целью проверки правильной совместной работы составных час­тей программы. При комплексном тестировании особое внимание обычно уделяется взаимодействию компонентов. Комплексное тес­тирование является процессом контроля, если оно выполняется в условиях моделируемой среды, и процессом испытания при вы­полнении в реальной среде;

    системное тестирование - при системном тестировании вся система в целом обычно рассматривается как некоторый «черный ящик»; поведение этой системы исследуют, не вникая в подробно­сти отдельных ее компонентов и взаимодействий между ними;

    тестирование приемлемости (acceptancetesting) - проверка соответствия программы требованиям пользователя.

    5.8. ОТЛАДКА

    Процесс тестирования нельзя путать с процессом от­ладки (debugging). Первый служит лишь для обнаружения факта существования ошибок, а не для их локализации и устранения.

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

    Существуют несколько способов отладки программы.

    Распечатка текущего состоя н и я . Используется с це­лью фиксации фактических значений переменных для проверки хода вычислений. Для этого во время отладки программы в места, которые программист считает критическими, помещают процеду­ры распечатки текущего состояния переменных. После окончания теста вызовы этих процедур удаляются, и программа снова пере­компилируется.

    Точки останова. Используются в случае разного рода за­цикливаний, когда программа в какой-то момент «зависает». В текст программы включают процедуры останова программы. Например, можно поместить процедуру вывода обычного сообщения вроде «Достигнута точка #ппп» и инициировать паузу до нажатия на лю­бую клавишу. При таком подходе программист точно знает, до ка­кой точки дошла программа перед зацикливанием.

    Метод деления п о п о л а м . Этот метод используют свя­зисты, когда ищут обрыв в кабеле, закопанном в землю. Например, если приблизительно известно до какого момента программа ус­пешно выполняется, то в этом месте программы ставят точку ос­танова. Затем ставят точку в конце «подозреваемой» процедуры и посредине - между первой и последней точками. Снова компили­руют и выполняют программу. Если программа дошла до второй точки, то зацикливание произошло где-то между второй и третьей точками, если не дошла - между первой и второй. После этого вставляется новая точка останова в локализованный участок и про­грамма снова компилируется. Таким образом, постоянно сжимая район поисков, можно найти ошибочный участок.

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

    5.9. ОПТИМИЗАЦИЯ

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

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

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

    Разгрузка участков повторяемости. Является спо­собом оптимизации, который чаще всего подразумевает разгрузку циклов путем вынесения из них выражений, которые могут быть вычислены вне циклов.

    К этому виду преобразований относятся также «чистки» тел ре­курсивных процедур, когда выражения в соответствующем цикле (или теле многократно вызываемой процедуры) выносятся и раз­мещаются перед входом в участок повторяемости — это так назы­ваемая чистка вверх.

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

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

    Например, операция сложения выполняется быстрее операции умножения, а умножение быстрее операции деления. Поэтому один оператор умножения переменной на некоторое небольшое целое число (обычно не более трех) лучше заменить на эквивалентное количество сложений. Выражение:

    Total := Summa + Summa + Summa;

    эффективнее выражения: Total := 3 * Summa;

    а операцию деления Summa := Summa/2; лучше заменить на более быстрое умножение, которое приведет к тому же самому результату Summa := Summa * 0.5;

    Чистка программы. Данный способ повышает качество программы за счет удаления из нее ненужных объектов и конст­рукций. Набор преобразований этого типа включает в себя сле­дующие варианты оптимизации:

    удаление несущественных операторов, то есть операторов, не влияющих на результат программы;

    удаление бесполезных операторов, вычисляющих вспомога­тельные переменные, используемые только для подстановки в дру­гие выражения;

    удаление объявленных, но неиспользуемых переменных и типов;

    удаление идентичных операторов;

    удаление процедур, к которым нет обращений.

    Необходимость в такого рода чистках возникает потому, что очень часто программист «захлебывается» в общем количестве пе­ременных и процедур одного слишком большого модуля. Подчас он объявляет переменные, которые потом нигде в программе не использует.

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

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

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

    Это так называемая экономия на типе переменной. Существует и еще ряд способов более экономного расходования памяти:

    1. Глобальная экономия памяти подразумевает совмещение по памяти не существующих одновременно статических переменных. Модульное программирование также подразумевает разнесение объявлений несвязанных переменных в различные модули.

    2. Изменение области существования переменной.

    3. Перемещение оператора объявления переменной (резервиро­вания памяти) ближе к тому участку программы, в котором содер­жатся операторы, использующие эту переменную, то есть перемен­ную следует объявлять в границах того блока, где она используется.

    4. Экономия стека: при передаче массива в качестве параметра подпрограммы, следует использовать ссылку на массив. Помимо экономии памяти это приводит также и к экономии времени за счет того, что система не создает копии передаваемого массива в стеке.

    1) АЛГОРИТМЫ И ИХ РАЗРАБОТКА

    6.1. ПОНЯТИЕ АЛГОРИТМА И ЕГО СВОЙСТВА

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

    Алгоритм - это точное, сформулированное на определенном языке, конечное описание того или иного способа действия, осно­ванного на применении исполнимых элементарных однозначно трактуемых шагов.

    Любой алгоритм имеет пять особенностей.

    1) Конечность алгоритма (финитность). Означает, что алго­ритм всегда должен заканчиваться после конечного числа шагов.

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

    Однако существуют примеры, использующие бесконечные процессы, например контроль показателей жизнедеятельности па­циента в больнице или поддержание установленной высоты полета авиалайнера.

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

    2) Определенность алгоритма. Каждый шаг алгоритма должен быть точно определен, то есть действия, которые необходимо про­извести должны быть недвусмысленно определены в каждом воз­можном случае.

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

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

    3) Наличие входных данных. Алгоритм имеет некоторое число
    входных величин, заданных ему до начала работы.

    Иногда это число может равняться нулю, однако это означает, что входные величины должны быть описаны как часть алгоритма. Например, алгоритм сложения числа 777 с числом 333. В этом слу­чае шаги 1 и 2 должны быть записаны так:

    Шаг 1. Записать число 777.

    Шаг 2. Под ним записать число 333

    ………

    То есть, если даже входные величины отсутствуют, то какие-то величины будут описаны в самом алгоритме. В противном случае алгоритм не может быть выполнен.

    1. Наличие выходных данных. Результатом выполнения любого алгоритма всегда будет обработанная информация, выдаваемая в том или ином виде и, следовательно, алгоритм обязательно имеет одну или несколько выходных величин, являющихся результатом обработки входных данных.

    2. Эффективность алгоритма. Алгоритм, который выполняет действие за меньшее число шагов признается более эффективным.

    Это связано с тем. что любая программа, в основе которой ле­жит тот или иной алгоритм, должна выполняться на реальном вы­числительном устройстве. Поэтому большое значение имеет время выполнения программы, на которое влияет количество шагов алго­ритма. Кроме того, программа занимает определенный объем в па­мяти компьютера. Поэтому количество шагов косвенно влияет на еще один показатель эффективности - размер программы.
    6.2. ПРЕДСТАВЛЕНИЕ АЛГОРИТМА И ПСЕВДОКОД

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

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

    Каждый примитив состоит из двух частей: синтаксической и семантической. Синтаксис относится к символьному представле­нию примитива, а семантика - к смысловому значению примитива.

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

    Псевдокод - это система обозначений, предназначенная для не­формального представления идей в процессе разработки алгоритмов.

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

    Альтернатива выражается на псевдокоде следующей структурой: if (условие) then (действие) else (действие)

    Сокращенный синтаксис этого конструкта когда не предусмот­рено действие для варианта else выглядит так:

    if (условие) then (действие)

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

    Эта инструкция предписывает проверить условие и, если оно верно, выполнить действие, а затем вновь проверить условие. Если при очередной проверке условие оказывается неверным, следует перейти к инструкции, следующей за данной структурой.

    while (условие) do (действие)

    Цикл-doна псевдокоде имеет следующий вид: repeat (действие) until (условие)

    Оператор присваивания. Часто желательно ссылаться на неко­торые значения с помощью описательных имен. Для установки по­добных связей будет использоваться следующая конструкция при­сваивания:

    assign имя the value выражение

    здесь параметр имя - это описательное имя, а параметр выражение описывает значение, связываемое с этим именем. Например: assign Итог the value Цена + Налог

    При ее выполнении результат суммирования значений пере­менных Цена и Налог будет связан с именем Итог .

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

    В псевдокоде для обозначения заголовка, по которому можно рас­познать данный блок псевдокода используется термин procedure: procedure имя

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

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

    Такие обобщенные имена в псевдокоде выделяют угловыми скобками и указывают их в круглых скобках а той же строке, в которой определяется имя данной процедуры. В частности, процеду­ра Сортировка, предназначенная для сортировки произвольных списков имен, будет начинаться следующей инструкцией: procedure Сортировка(<список>)

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

    Поиск более удачных средств представления алгоритмов про­должается и поныне. Существующие тенденции заключаются в ис­пользовании графических методов, однако псевдокод остается дос­таточно эффективным при разработке процедурных компонентов небольшого размера, входящих в состав программных систем.
    1   2   3   4   5   6


    написать администратору сайта