Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2014 Лекції ТСПП (0-8).pdf
Скачиваний:
389
Добавлен:
12.02.2016
Размер:
1.74 Mб
Скачать

Лекція 8. Тестування і відлагодження програмного засобу

Суміжний контроль зверху - це контроль з боку розробників архітектури і зовнішнього опису ПЗ. Суміжний контроль знизу - це контроль специфікації модулів з боку розробників цих модулів.

Наскрізний контроль - це уявне прокручування (перевірка) структури програми при виконанні заздалегідь розроблених тестів. Є видом динамічного контролю так само, як і ручна імітація функціональної специфікації або архітектури ПЗ.

Слід відмітити, що характер здійснення цих методів контролю залежить від вибраного методу розробки структури програми: при класичному підході вони застосовуються до початку програмування модулів, а при конструктивному і архітектурному підходах - в процесі програмування модулів (у відповідні моменти часу).

2.Розроблення програмних модулів

2.1.Порядок розробки програмного модуля

При розробці програмного модуля доцільно дотримуватися наступного порядку [8.1]:

вивчення і перевірка специфікації модуля, вибір мови програмування;

вибір алгоритму і структури даних;

програмування модуля;

шліфовка тексту модуля;

перевірка модуля;

компіляція модуля.

Перший крок розробки програмного модуля в значній мірі є суміжним контролем структури програми знизу: вивчаючи специфікацію модуля, розробник повинен переконатися, що вона йому зрозуміла і достатня для розробки цього модуля. У завершенні цього кроку вибирається мова програмування: хоча мова програмування може бути вже зумовлений для всього ПЗ, все ж таки у ряді випадків (якщо система програмування це допускає) може бути вибраний інша мова, більш відповідна для реалізації даного модуля (наприклад, мова асемблера).

На другому кроці розробки програмного модуля необхідно з'ясувати, чи не відомі вже які-небудь алгоритми для вирішення поставленою і або близького до неї завдання. І якщо знайдеться відповідний алгоритм, то доцільно їм скористатися. Вибір відповідних структур даних, які використовуватимуться при виконанні модулем своїх функцій, в значній мірі зумовлює логіку і якісні показники модуля, що розробляється, тому його слід розглядати як вельми відповідальне рішення.

На третьому кроці здійснюється побудова тексту модуля на вибраній мові програмування. Велика кількість всіляких деталей, які повинні бути враховані при реалізації функцій, вказаних в специфікації модуля, легко можуть привести до створення вельми заплутаного тексту, що містить масу помилок і неточностей. Шукати помилки в такому модулі і вносити до нього необхідні зміни може виявитися вельми трудомістким завданням. Тому вельми важливо для побудови тексту модуля користуватися технологічно обгрунтованою і практично перевіреною дисципліною програмування. Вперше на це звернув увагу Дейкстра [8.2], сформулювавши і обгрунтувавши основні принципи структурного програмування. На цих принципах базуються багато дисциплін програмування, широко вживані на практиці [8.3-8.6]. Найбільш поширеною є дисципліна покрокової деталізації [8.3], яка детально обговорюється в розділах 8.2 і 8.3.

Наступний крок розробки модуля пов'язаний з приведенням тексту модуля до завершеного вигляду відповідно до специфікації якості ПЗ. При програмуванні модуля розробник основна увага приділяє правильності реалізації функцій модуля, залишаючи недопрацьованими коментарі і допускаючи деякі порушення вимог до стилю програми. При шліфовці тексту модуля він повинен відредагувати наявні в тексті коментарі і, можливо, включити в нього додаткові коментарі забезпечити необхідні примітиви якості [8.1]. З цією ж метою проводиться редагування тексту програми для виконання стилістичних вимог.

Крок перевірки модуля є ручною перевіркою внутрішньої логіки модуля до початку його відладки (що використовує виконання його на комп'ютері), реалізує загальний принцип, сформульований для обговорюваної технології програмування, про необхідність контролю ухвалюваних рішень на кожному етапі розробки ПЗ (див. лекцію 3). Методи перевірки модуля обговорюються розділі 8.4.

77

Лекція 8. Тестування і відлагодження програмного засобу

І, нарешті, останній крок розробки модуля означає завершення перевірки модуля (за допомогою компілятора) і перехід до процесу відладки модуля.

2.2.Структурне програмування модуля

При програмуванні модуля слід мати зважаючи на, що програма повинна бути зрозумілою не тільки комп'ютеру, але і людині: і розробник модуля, і особи, перевіряючі модуль, і тестовики, що готують тести для відладки модуля, і супровідники ПЗ, що здійснюють необхідні зміни модуля, вимушені будуть багато разів розбирати логіку роботи модуля. У сучасних мовах програмування достатньо засобів, щоб заплутати цю логіку скільки завгодно сильно, тим самим, зробити модуль важко таким, що розуміється для людини і, як наслідок цього, зробити його ненадійним або важко супроводжуваним. Тому необхідно приймати заходи для вибирання відповідних мовних засобів і слідувати певній дисципліні програмування. Вперше на це звернув увагу Дейкстра [8.2] і запропонував будувати програму як композицію з декількох типів конструкцій (структур), що управляють, які дозволяють сильно підвищити понимаемость логіків роботи програми. Програмування з використанням тільки таких конструкцій назвали структурним.

Рис. 8.1. Основные управляющие конструкции структурного программирования.

Основними конструкціями структурного програмування є: проходження, розгалуження і повторення (див. Мал. 8.1). Компонентами цих конструкцій є узагальнені оператори (вузли обробки [8.5]) S, S1, S2 і умова (предикат) P. У якості узагальненого оператора може бути або простій оператор використовуваної мови програмування (оператори привласнення, введення, виводу, звернення до процедури), або фрагмент програми, що є композицією основних конструкцій структурного програмування, що управляють. Істотно, що кожна з цих конструкцій має по управлінню тільки один вхід і один вихід. Тим самим, і узагальненого оператора має тільки один вхід і один вихід.

Важливо також, що ці конструкції є вже математичними об'єктами (що, по-существу, і пояснює причину успіху структурного програмування). Доведено, що для кожної неструктурованої програми можна побудувати функціонально еквівалентну (тобто вирішальну те ж завдання) структуровану програму. Для структурованих програм можна математично доводити деякі властивості, що дозволяє виявляти в програмі деякі помилки. Цьому питанню буде присвячена окрема лекція.

Структурне програмування іноді називають ще "програмуванням без GO TO". Проте справа тут не в операторові GO TO, а в його безладному використанні. Дуже часто при втіленні структурного програмування на деяких мовах програмування (наприклад, на Фортрані) оператор переходу (GO TO) використовується для реалізації структурних конструкцій, не знижуючи основних достоїнств структурного програмування. Заплутують програму якраз "неструктурні" оператори переходу, особливо перехід на оператора, розташованого в тексті модуля вище (раніше) виконуваного оператора переходу. Проте, спроба уникнути оператора переходу в деяких простих випадках може привести до дуже громіздких структурованих програм, що не покращує їх ясність і містить небезпеку

78

Лекція 8. Тестування і відлагодження програмного засобу

появи в тексті модуля додаткових помилок. Тому можна рекомендувати уникати вживання оператора переходу усюди, де це можливо, але не ціною ясності програми [8.1].

До корисних випадків використання оператора переходу можна віднести вихід з циклу або процедури по особливій умові, даного циклу, що "достроково" припиняє роботу, або даної процедури, тобто що завершує роботу деякої структурної одиниці (узагальненого оператора) і що тим самим лише локально порушує структурованість програми. Великі труднощі (і ускладнення структури) викликає структурна реалізація реакції на виникаючі виняткові (часто помилкові) ситуації, оскільки при цьому потрібно не тільки здійснити достроковий вихід із структурної одиниці, але і провести необхідну обробку (виключення) цієї ситуації (наприклад, видачу відповідній діагностичній інформації). Обробник виняткової ситуації може знаходитися на будь-якому рівні структури програми, а звернення до нього може проводитися з різних нижніх рівнів. Цілком прийнятною з технологічної точки зору є наступна "неструктурна" реалізація реакції на виняткові ситуації [8.7]. Обробники виняткових ситуацій поміщаються в кінці тієї або іншої структурної одиниці і кожен такий обробник програмується таким чином, що після закінчення своєї роботи проводить вихід з тієї структурної одиниці, в кінці якої він поміщений. Звернення до такого обробника проводиться оператором переходу з даної структурної одиниці (включаючи будь-яку вкладену в неї структурну одиницю).

2.3.Покрокова деталізація і поняття про псевдокод.

Структурне програмування дає рекомендації про те, яким повинен бути текст модуля. Виникає питання, як повинен діяти програміст, щоб побудувати такий текст. Іноді програмування модуля починають з побудови його блок-схеми, що описує у загальних рисах логіку його роботи. Проте сучасна технологія програмування не рекомендує цього робити. Хоча блок-схеми дозволяють вельми наочно представити логіку роботи модуля, при їх кодуванні на мові програмування виникає вельми специфічне джерело помилок: відображення істотне двовимірних структур, якими є блок-схеми, на лінійний текст, що представляє модуль, містить небезпеку спотворення логіки роботи модуля, тим паче, що ПЗихологічно досить важко зберегти високий рівень уваги при повторному її розгляді. Виключенням може бути випадок, коли для побудови блок-схем використовується графічний редактор і вони формалізовані настільки, що по ним автоматично генерується текст на мові програмування (як наприклад, це може робитися в Р-технологии [8.6]).

Як основний метод побудови тексту модуля сучасна технологія програмування рекомендує покрокову деталізацію [8.1, 8.3, 8.5]. Суть цього методу полягає в розбитті процесу розробки тексту модуля на ряд кроків.

На першому кроці описується загальна схема роботи модуля в осяжній лінійній текстовій формі (тобто з використанням дуже крупних понять), причому цей опис не є повністю формалізованим і орієнтовано на сприйняття його людиною.

На кожному наступному кроці проводиться уточнення і деталізація одного з понять (називатимемо його уточнюваним), використаного (як правило, не формалізований) в якому або описі, розробленому на одному з попередніх кроків. В результаті такого кроку створюється опис вибраного уточнюваного поняття або в термінах базової мови програмування (тобто вибраного для уявлення модуля), або в такій же формі, що і на першому кроці з використанням нових уточнюваних понять. Цей процес завершується, коли всі уточнювані поняття будуть виражені кінець кінцем на базовій мові програмування.

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

Покрокова деталізація зв'язана з використанням часткової формалізованої мови для представлення вказаних описів, який отримав назву ПЗевдокоду [8.5, 8.8]. Ця мова дозволяє використовувати всі конструкції структурного програмування, які оформляються формалізований, разом з неформальними фрагментами на природній мові для представлення узагальнених операторів і умов. Як узагальнені оператори і умови можуть задаватися і відповідні фрагменти на базовій мові програмування.

79

Лекція 8. Тестування і відлагодження програмного засобу

Головним описом на ПЗевдокоді можна рахувати зовнішнє оформлення модуля на базовій мові програмування, яке повинно містити:

початок модуля на базовій мові, тобто перша пропозиція або заголовок (специфікацію) цього модуля [8.1];

розділ (сукупність) описів на базовій мові, причому замість описів процедур і функцій - тільки їх зовнішнє оформлення;

неформальне позначення послідовності операторів тіла модуля як одного узагальненого оператора (див. нижчий), а також неформальне позначення послідовності операторів тіла кожного опису процедури або функції як одного узагальненого оператора;

остання пропозиція (кінець) модуля на базовій мові [8.1].

Зовнішнє оформлення опису процедури або функції представляється аналогічно. Втім, якщо слідувати Дейкстре [8.2], розділ описів краще також представити тут неформальним позначенням, провівши його деталізацію у вигляді окремого опису.

Неформальне позначення узагальненого оператора на ПЗевдокоді проводиться на природній мові довільною пропозицією, що розкриває у загальних рисах його зміст. Єдиною формальною вимогою до оформлення такого позначення є наступне: ця пропозиція повинна займати цілком одне або декілька графічних (друкарських) рядків і завершуватися крапкою.

Для кожного неформального узагальненого оператора повинен бути створений окремий опис, що виражає логіку його роботи (зміст, що деталізує його) за допомогою композиції основних конструкцій структурного програмування та інших узагальнених операторів. Як заголовок такого опису повинно бути неформальне позначення узагальненого оператора, що деталізується. Основні конструкції структурного програмування можуть бути представлені в наступному вигляді (див. мал. 8.2). Тут умова може бути або явно заданою на базовій мові програмування як булевий вираз, або неформально представленою на природній мові деяким фрагментом, що розкриває у загальних рисах сенс цієї умови. У останньому випадку повинен бути створене окремий опис, що деталізує цю умову, з вказівкою як заголовок позначення цієї умови (фрагмента на природній мові).

Проходження:

обобщенный_оператор обобщенный_оператор

Розгалуження:

ЯКЩО умова ТЕ обобщенный_оператор

ІНАКШЕ обобщенный_оператор

ВСЕ ЯКЩО

Повторення:

ПОКИ умову РОБИТИ обобщенный_оператор

ВСЕ ПОКИ

Мал. 7.2. Основні конструкції структурного програмування на ПЗевдокоді.

Вихід з повторення (циклу):

ВИЙТИ

Вихід з процедури (функції): ПОВЕРНУТИСЯ

Перехід на обробку виняткової ситуації: ПОРУШИТИ имя_исключения

Мал. 7.3. Окремі випадки оператора переходу як узагальнений оператор.

80

Лекція 8. Тестування і відлагодження програмного засобу

Як узагальнений оператор на ПЗевдокоді можна використовувати вказані вище окремі випадки оператора переходу (див. мал. 8.3). Послідовність обробників виняткових ситуацій (виключень)

задається в кінці модуля або опису процедури(функції). Кожен такий обробник має вигляд:

ВИКЛЮЧЕННЯ імя_виключення

обобщенный_оператор ВСЕ ВИКЛЮЧЕННЯ

Відмінність обробника виняткової ситуації від процедури без параметрів полягає в наступній: після виконання процедури управління повертається до оператора, наступного за зверненням до неї, а після виконання виключення управління повертається до оператора, наступного за зверненням до модуля або процедури (функції), в кінці якого (якій) поміщено дане виключення.

Рекомендується на кожному кроці деталізації створювати достатньо змістовний опис, але легко осяжне (наочне), так щоб воно розміщувалося на одній сторінці тексту. Як правило, це означає, що таке опис повинен бути композицією п'яти-шести конструкцій структурного програмування. Рекомендується також вкладені конструкції розташовувати із зсувом управо на декілька позицій (див. мал. 8.4). В результаті можна отримати опис логіки роботи по наочності цілком конкурентне з блоксхемами, але що володіє істотною перевагою - зберігається лінійність опису.

ВИДАЛЕННЯ У ФАЙЛІ ЗАПИСІВ ДО ПЕРШОЇ

ЩО ЗАДОВОЛЬНЯЄ ЗАДАНОМУ ФІЛЬТРУ: ВСТАНОВИТИ ПОЧАТОК ФАЙЛУ. ПОКИ НЕ КІНЕЦЬ ФАЙЛУ РОБИТИ

ПРОЧИТАТИ ЧЕРГОВИЙ ЗАПИС.

ЯКЩО ЧЕРГОВИЙ ЗАПИС ЗАДОВОЛЬНЯЄ ФІЛЬТРУ ТЕ

ВИЙТИ

ІНАКШЕ ВИДАЛИТИ ЧЕРГОВИЙ ЗАПИС З ФАЙЛУ.

ВСЕ ЯКЩО ВСЕ ПОКИ

ЯКЩО ЗАПИСИ НЕ ВИДАЛЕНІ ТЕ НАДРУКУВАТИ "ЗАПИСИ НЕ ВИДАЛЕНІ".

ІНАКШЕ НАДРУКУВАТИ "ВИДАЛЕНО н ЗАПИСІВ".

ВСЕ ЯКЩО

Мал. 8.4. Приклад одного кроку деталізації на псевдокоді.

Ідею покрокової деталізації приписують Дейкстрі [8.1]. Проте він запропонував метод побудови тексту модуля, який є глибшим і перспективнішим, що принципово відрізняється.

По-перше, разом з уточненням операторів він пропонував поступово (по кроках) уточнювати (деталізувати) і використовувані структури даних.

По-друге, на кожному кроці він пропонував створювати деяку віртуальну машину для деталізації і в її термінах проводити деталізацію всіх уточнюваних понять, для яких ця машина дозволяє це зробити.

Таким чином, Дейкстра запропонував, по-суті, деталізувати по горизонтальних шарах, що є перенесенням його ідеї про шаруваті системи (див. лекцію 6) на рівень розробки модуля. Такий метод розробки модуля підтримується в даний час пакетами мови ПЕКЛА і засобами об'єктного - орієнтованого програмування.

81

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]