Лабораторні роботи ТПЗ 1-8

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
ІКТА
Факультет:
КН
Кафедра:
Електронні обчислювальні машини

Інформація про роботу

Рік:
2012
Тип роботи:
Лабораторна робота
Предмет:
Тестування програмних засобів

Частина тексту файла (без зображень, графіків і формул):

Міністерство освіти і науки України Національний університет „Львівська політехніка” Кафедра ЕОМ Звіт з лабораторної роботи №2 з дисципліни “ Тестування програмних засобів ” Львів 2012 Мета: розглянути фреймворки для автоматизованого тестування програмного забезпечення. Виконання роботи: Фреймворк SoapUI Soap UI - веб-сервіс з відкритим кодом, призначений для тестування додатків з сервіс-орієнтованою архітектурою (SOA). Його функціональність включає перевірку, розробку, симуляцію, виклик і фальшивий викли веб-сервісу, функціональні, завантажувальні і піддатливе тестування веб-сервісу. Комерційна версія soapUI Pro, взагальному фокусується на досягненні продуктивності і розроблена сторонніми компаніями.  Рис. 1 Головне вікно Soap UI Перший реліз Soap UI був завантажений на Sourceforge в листопаді 2005. Це ПЗ з відкритим кодом випущене з ліцензією GNU/GPL. Цей фреймворк було завантажено більш ніж 2000000 разів з часу першого релізу. Він побудований на платформі Java і використовує Swing для інтерфейсу користувача, тому він є кросплатформенним. Сьогодні він підтримує IDEA, Eclipse i NetBeans. Він підтримує такі можливості: Перевірка веб-сервісів Запуск веб-сервівсів Розробку веб-сервівсів Емуляцію роботи веб-сервівсів і Функціонал завантаження і тестування безпеки веб-сервісу Одна з основних проблем, які виникають під час інтеграції різних систем між собою це те, що на момент розробки ці сервіси або не існують, або не завжди доступні (або доступні з великими проблемами). Таке може статися, якщо, наприклад, компанія розробляє додаток на базі SOA, і кожен з сервісів створюється паралельно різними людьми. Чекати поки одна людина закінчить свій компонент, перш ніж приступати до своєї розробці - не найефективніший спосіб. Добре, якщо всі сервіси знаходяться в руках однієї компанії, тоді можна ще хоч якось домовитися, але в реальності все буває якраз навпаки - сервіси знаходяться під контролем сторонніх компаній і буває дуже складно вплинути на їх розробку. Щоб це було легше зрозуміти - уявімо гіпотетичну ситуацію. Існує якась компанія, яка займається виконання різного роду технічних робіт, наприклад ремонтує / контролює / встановлює охоронні системи. У компанії є регістр даних клієнтів, що зберігається в якійсь базі даних. Доступ до цієї бази даних можна отримати через спеціальний інтерфейс, через який дані про клієнтів заносяться в систему, проглядаються і оновлюються. Коли приходить новий замовлення, то він оформляється у ще одній спеціальній системі замовлень, після чого на об'єкт відправляється технік, який власне і займається обслуговуванням охоронних систем. У техніка є загальна інструкція, що описує, як він має діяти на об'єкт, але, в принципі, кожен з них діє за власним розсудом, виходячи з ситуації на місці. Після виконання роботи - технік створює звіт у вільній формі, який зберігається в певної третьої системі. Припустимо, що компанія хоче покращити якість звітів. Вона хоче бачити, які саме роботи були зроблені, скільки часу займала кожна з них, які проблеми найбільш часті і так далі. Всю цю інформацію планується використовувати для поліпшення продуктивності і, як результат, зниження витрат і збільшення обороту. Для цього планується впровадити нову інформаційну систему, яка дозволить стандартизувати робочий процес. Виглядає це як список завдань / checklist на PDA техніка, які він повинен виконати, відвідавши об'єкт. Ця ж система дозволить пакувати замовлення таким чином, щоб одному техніку діставалися замовлення в одній і тій же частині міста, тим самим збільшивши кількість об'єктів, які він може відвідати за день. Наймати працівника в штат компанія не бажає і тому наймається контрактор, який, власне, і інтегрує ці системи між собою. Ось тут починається саме інтересaное. Як правило, бази даних, що зберігають клієнтів, замовлення, звіти, доступні усередині корпоративної мережі, але не видно зовні з причин безпеки. У той же час, навіть перебуваючи всередині мережі, доступ можна отримати тільки прямо приєднати до бази даних. В принципі, контрактор може організувати доступ до цих баз через спеціальні з'єднання, але це в такому випадку, він буде дуже сильно залежати від доступності та працездатності цих систем. Друге особливо важливо, так як доступ, швидше за все можна отримати не до live системам, а до тестіровочним, які, як правило, мають звичай працювати нестабільно. До того ж, будь-яке нове ланка в доступі до даних збільшують вартість розробки, так як у випадку проблем доводиться переглядати всі ланки. Прямий доступ до бази даних не є найкращим рішенням. Звичайно, це можна зробити, але краще представити кілька бази даних як окремий сервіс. Це забезпечить меншу залежність від баз даних і дозволить в майбутньому без проблем замінити існуючі системи на одну загальну, тим самим, припустимо, скоротивши витрати на обслуговування і, можливо, ліцензії. На жаль, у компанії такого сервісу поки немає, але вона пообіцяла контрактору, що якщо він надасть їм інтерфейс, який повинен реалізовувати цей сервіс, то вони створять його. Але! У перебігу місяця. Ouch. Контрактор не може дозволити собі чекати місяць. Звичайне рішення цієї проблеми - створити симулятори сервісів, які будуть емулювати зовнішні системи згідно з контрактом. Ось про те, як зробити це найбільш ефективно і піде тут мова. Симулятор завжди можна написати вручну, будь то звичайний perl скрипт, який сканує на певний порт і посилає назад дані або це java web сервер, що емулює ту ж задачу. На жаль, всі ці рішення досить ресурсомісткі. Інший підхід - використання готових інструментів, для створення досить динамічних заглушок. Один з таких інструментів - soapUI. Фреймворк CUnit Загальний огляд CUnit – це фреймворк для написання, адміністрування та виконання модульних тестів на мові С. Він розроблений, як статична бібліотека, яка зв’язана з кодом користувача. Сunit включає великий набір перевірок для простих типів даних. Додаткова в ньому є ще кілька інших інтерфейсів для виконання тестів і перегляду результатів тестування. Вони включають автоматизовані інтерфейси для тестування коду і перегляду результатів, а також інтерактивні інтерфейси, які дозволяють користувачу запускати тести і переглядати результати динамічно. Типи даних і функції потрібні користувачу знаходяться в заголовочних файлах ( табл.1 ) Таблиця 1. Файли потрібні для роботи з CUnit. Заголовочний файл Опис  1 #include <CUnit/CUnit.h> Містить Assert-макроси для тест-кейсів, і включає інші заготовочні файли фреймворку  2 #include <CUnit/CUError.h> Функії перехоплення помилок. Включається в проект автоматично в CUnit.h.  3 #include <CUnit/TestDB.h> Типи даних і функції для роботи з регістром тестів, набором тестів і самими тестами. Включається в проект автоматично в CUnit.h.  4 #include <CUnit/TestRun.h> Оголошення типів даних і функцій для виконання тестів і отримання результатів. Включається в проект автоматично в CUnit.h.  5 #include <CUnit/Automated.h> Автоматичний інтерфейс виводу в xml.  6 #include <CUnit/Basic.h> Базовий інтерфейс з не інтерактивним виводом в stdout.  7 #include <CUnit/Console.h> Інтерактивний інтерфейс виводу на консоль.  8 #include <CUnit/CUCurses.h> Інтерактивний інтерфейс виводу на консоль. (*nix).  9 #include <CUnit/Win.h> Інтерфейс Windows. (ще не реалізований)  CUnit – це комбінація кросплатформенного фреймворку і різноманітних інтерфейсів користувача. Кросплатформенний фреймворк забезпечує базову підтримку керування тестовим регістром, наборами тестів і тестами. Інтерфейс користувача забезпечує взаємодію з фреймворком, запуск тестів і перегляд результатів.  Рис 1. Структура CUnit. Індивідуальні тести складають набори тестів, з яких в свою чергу складений активний регістр тестів. Набори тестів можуть мати опції, і викликати певні функції перед і після виконання наборів тестів. Всі набори тестів/тести можна запустити єдиним викликом функції, або можна вибирати певні набори тестів чи окремі тести для запуску. Послідовність дій для початку використання CUnit Написати функції для тестування (ініціалізації, завершення виконання набору тестів, якщо необхідно) Ініціалізувати реєстр тестів CU_initialize_registry() Додати набір тестів в регістр CU_add_suite() Додати тести в набір CU_add_test() Виконати тести використовуючи пропрієтарний інтерфейс CU_console_run_test() Очистити регістр тестів CU_cleanup_registry(). Всі публічні імена в CUnit починаються з префіксу CU_. Це допомагає зменшити появу помилки в коді користувача. Раніші версії CUnit використовували імена без цього префіксу і досі підтримуються в CUnit, але треба використовувати макрос USE_DEPRECATED_CUNIT_NAMES. Написання тестів CUnit тест – це С-функція з сигнатурою void test_func(void). Немає ніяких обмежень на вміст тестової функції окрім того, що вона не повиння модифікувати сам фреймворк (тобто додавати тести, набори тестів чи запускати тести на виконання). Вона може викликати іншу функцію яка також не повинна модифікувати фреймворк. Додавання тесту в тесті спричинить виконання його функції для тестування при виконанні самого тесту. Приклад тестування функції яка повертає максимальне з двох чисел: int maxi(int i1, int i2) { return (i1 > i2) ? i1 : i2; } void test_maxi(void) { CU_ASSERT(maxi(0,2) == 2); CU_ASSERT(maxi(0,-2) == 0); CU_ASSERT(maxi(2,2) == 2); } СUnit містить ряд перевірок для тестування логічних умов. Успішне чи неуспішне виконання перевірок відстежується фреймворком, і результати роботи можна побачити після виконання тесту. Кожна така перевірка тестує одну логічну умову і виконання її неуспішне, якщо умова рівна FALSE.У випадку не проходження перевірки функція продовжує виконання, хіба що користувач задав ’xxx_FATAL’ версію перевірки. В цьому випадку тест-функція завершує виконання. FATAL версія перевірки повинна використовуватися обачно, адже тест-функція не буде мати змоги завершитися коректно, наприклад не зможе закрити файл. Проте це не впливає на функцію завершення набору тестів. Також існують спеціальні функції які реєструють проходження чи не проходження тесту без будь-яких додаткових параметрів. Вони використовуються для тестування гілок виконання чи інших випадків, які не підходять для чітких логічних перевірок. void test_longjmp(void) { jmp_buf buf; int i; i = setjmp(buf); if (i == 0) { run_other_func(); CU_PASS("run_other_func() succeeded."); } else CU_FAIL("run_other_func() issued longjmp."); } Інші функції можуть вільно використовувати перевірки CUnit. Вони будуть прелічені для викликаючої функції. Також вони можуть використовувати FATAL версії перевірок. Непрохождження перевірки призведе до виходу з усіх функції по ланцюгу викликів і з базової функції. Таблиця 2. Список перевірок CUnit. Функція Опис  CU_ASSERT(int expression) CU_ASSERT_FATAL(int expression) CU_TEST(int expression) CU_TEST_FATAL(int expression) Перевіряє чи expression є TRUE (не нуль) Еxpression - вираз  CU_ASSERT_TRUE(value) CU_ASSERT_TRUE_FATAL(value) Перевіряє чи value є TRUE (не нуль) Value - значення  CU_ASSERT_FALSE(value) CU_ASSERT_FALSE_FATAL(value) Перевіряє чи value є FALSE (zero)  CU_ASSERT_EQUAL(actual, expected) CU_ASSERT_EQUAL_FATAL(actual, expected) Перевіряє чи actual = = expected actual – те що дане expected – те що очікуване  CU_ASSERT_NOT_EQUAL(actual, expected)) CU_ASSERT_NOT_EQUAL_FATAL(actual, expected) Перевіряє чи actual != expected  CU_ASSERT_PTR_EQUAL(actual, expected) CU_ASSERT_PTR_EQUAL_FATAL(actual, expected) Перевіряє чи вказівники actual = = expected  CU_ASSERT_PTR_NOT_EQUAL(actual, expected) CU_ASSERT_PTR_NOT_EQUAL_FATAL(actual, expected) Перевіряє чи вказівники  actual != expected  CU_ASSERT_PTR_NULL(value) CU_ASSERT_PTR_NULL_FATAL(value) Перевіряє чи вказівник value == NULL  CU_ASSERT_PTR_NOT_NULL(value) CU_ASSERT_PTR_NOT_NULL_FATAL(value) Перевіряє чи вказівник value != NULL  CU_ASSERT_STRING_EQUAL(actual, expected) CU_ASSERT_STRING_EQUAL_FATAL(actual, expected) Перевіояє чи стрічки actual і expected є еквівалентні  CU_ASSERT_STRING_NOT_EQUAL(actual, expected) CU_ASSERT_STRING_NOT_EQUAL_FATAL(actual, expected) Перевіояє чи стрічки actual і expected є різні  CU_ASSERT_NSTRING_EQUAL(actual, expected, count) CU_ASSERT_NSTRING_EQUAL_FATAL(actual, expected, count) Перевіояє чи перші count символів стрічки actual і expected є такі ж самі  CU_ASSERT_NSTRING_NOT_EQUAL(actual, expected, count) CU_ASSERT_NSTRING_NOT_EQUAL_FATAL(actual, expected, count) Перевіояє чи перші count символів стрічки actual і expected не є такі ж самі  CU_ASSERT_DOUBLE_EQUAL(actual, expected, granularity) CU_ASSERT_DOUBLE_EQUAL_FATAL(actual, expected, granularity) Перевіряє чи |actual - expected| <= |granularity| Треба підключити math.h  CU_ASSERT_DOUBLE_NOT_EQUAL(actual, expected, granularity) CU_ASSERT_DOUBLE_NOT_EQUAL_FATAL(actual, expected, granularity) Перевіряє чи |actual - expected| > |granularity| Треба підключити math.h  CU_PASS(message) Реєструє проходження перевірки. Message - повідомлення  CU_FAIL(message) CU_FAIL_FATAL(message) Реєструє непроходження перевірки.  Таблиця 3. Список старих версій функцій CUnit Старі імена Нові імена  ASSERT CU_ASSERT_FATAL  ASSERT_TRUE CU_ASSERT_TRUE_FATAL  ASSERT_FALSE CU_ASSERT_FALSE_FATAL  ASSERT_EQUAL CU_ASSERT_EQUAL_FATAL  ASSERT_NOT_EQUAL CU_ASSERT_NOT_EQUAL_FATAL  ASSERT_PTR_EQUAL CU_ASSERT_PTR_EQUAL_FATAL  ASSERT_PTR_NOT_EQUAL CU_ASSERT_PTR_NOT_EQUAL_FATAL  ASSERT_PTR_NULL CU_ASSERT_PTR_NULL_FATAL  ASSERT_PTR_NOT_NULL CU_ASSERT_PTR_NOT_NULL_FATAL  ASSERT_STRING_EQUAL CU_ASSERT_STRING_EQUAL_FATAL  ASSERT_STRING_NOT_EQUAL CU_ASSERT_STRING_NOT_EQUAL_FATAL  ASSERT_NSTRING_EQUAL CU_ASSERT_NSTRING_EQUAL_FATAL  ASSERT_NSTRING_NOT_EQUAL CU_ASSERT_NSTRING_NOT_EQUAL_FATAL  ASSERT_DOUBLE_EQUAL CU_ASSERT_DOUBLE_EQUAL_FATAL  ASSERT_DOUBLE_NOT_EQUAL CU_ASSERT_DOUBLE_NOT_EQUAL_FATAL   Реєстр тестів Реєстр тестів – це репозиторій наборів тестів і самих тестів. CUnit підтримує активний тестовий реєстр, який оновлюється коли користувач додає новий тест. Реєстр тестів CUnit в коді – це структура даних CU_TestRegistry. Вона включає поля для зберігання загальної кількості наборів тестів і окремих тестів в реєстрі, а також вказівник на початок зв’язного списку зареєстрованих наборів typedef struct CU_TestRegistry { unsigned int uiNumberOfSuites; unsigned int uiNumberOfTests; CU_pSuite pSuite; } CU_TestRegistry; typedef CU_TestRegistry* CU_pTestRegistry; Зазвичай користувачу необхідно лиш ініціалізувати реєстр тестів а потім завершити роботу реєстру. Проте є і інші функції для роботи з реєстром, якщо це необхідно. Основні функції та структури реєстру тестів: typedef struct CU_TestRegistry typedef CU_TestRegistry* CU_pTestRegistry CU_ErrorCode CU_initialize_registry(void) Void CU_cleanup_registry(void) CU_pTestRegistry CU_get_registry(void) CU_pTestRegistry CU_set_registry(CU_pTestRegistry pTestRegistry) CU_pTestRegistry CU_create_new_registry(void) Void CU_destroy_existing_registry(CU_pTestRegistry* ppRegistry) Коли тестування завершене необхідно викликати функцію для завершення роботи реєстру void CU_cleanup_registry(void). Вона звільняє п’янять, яку використовує фреймворк. Вона повинна бути останньою функцією, яка викликається при тестуванні.(крім функції установки тестового реєстру CU_initialize_registry() або CU_set_registry()). Невдале виконання цієї функції призведе до витоку пам’яті. Це функція знищує всі набори тестів і окремі тести в реєстрі, тому вказівники на ці дані не можна буде розіменувати після завершення роботи реєстру. Виклик CU_cleanup_registry(void) вплине тільки на внутрішній реєстр тестів CU_TestRegistry, який підтримується фреймворком. Знищення будь-якого іншого тестового реєстру користувачем є справою користувача. Це можна зробити явно викликом CU_destroy_existing_registry(), або неявно роблячи реєстр активним викликом CU_set_registry(), а потім знащити його викликом CU_cleanup_registry()  знову. Також в реєстрі є деякі інші функції для забезпечення потреб тестування і внутрішнього використання, проте користувачі мають про них знати для глибшого розуміння фреймворку і можливо практичного використання. CU_pTestRegistry CU_get_registry(void) Повертає вказівник на активний тестовий реєстр. Реєстр це змінна типу CU_TestRegistry. Пряма маніпуляція з тестовим реєстром не рекомендована для цього використовуються API. Так як фреймворк керує реєстром, то вказівник буде недісним при завершенні роботи реєстру. CU_pTestRegistry CU_set_registry(CU_pTestRegistry pTestRegistry) Замінює активний реєстр на вказаний. Повертається вказівник на попередній реєстр. Завершення роботи попереднього реєстру – справа користувача. Це можна зробити явно викликавши CU_destroy_existing_registry() для цього вказівника, або неявно викликавши CU_set_registry() а потім CU_cleanup_registry(). Слід проявляти обережність, щоб не знищити реєстру, який встановлюється в якості активного. Це може призвести до багаторазового звільнення тієї ж пам’яті і помилки програми. CU_pTestRegistry CU_create_new_registry(void) Створює новий реєстр і встановлює на нього вказівник. Новий реєстр не містить ніяких наборів тестів чи окремих тестів. Завершувати роботу реєстру є відповідальністю користувача. void CU_destroy_existing_registry(CU_pTestRegistry* ppRegistry) Знищує і звільняє всю пам'ять зайняту певним реєстром включаючи будь-які зареєстровані набори тестів чи тести. Цю функцію не слід викликати для активного реєстру. Це призведе до багаторазового звільнення тієї ж пам’яті і помилки програми. Виклик функції з параметром NULL нічого не виконує. Таблиця 4. Список старих версій функцій CUnit для роботи з реєстром Старі імена Нові імена  _TestRegistry CU_TestRegistry  _TestRegistry.uiNumberOfGroups PTestRegistry->uiNumberOfGroups CU_TestRegistry.uiNumberOfSuites CU_pTestRegistry->uiNumberOfSuites  _TestRegistry.pGroup PTestRegistry->pGroup CU_TestRegistry.pSuite CU_pTestRegistry->pSuite  PTestRegistry CU_pTestRegistry  initialize_registry() CU_initialize_registry()  cleanup_registry() CU_cleanup_registry()  get_registry() CU_get_registry()  set_registry() CU_set_registry()   Керування тестами і наборами тестів Для того, щоб запустити тести CUnit треба додати тести в спеціальну колекцію тестів(набір), який розміщений в реєстрі тестів. typedef struct CU_Suite typedef CU_Suite* CU_pSuite typedef struct CU_Test typedef CU_Test* CU_pTest typedef void (*CU_TestFunc)(void) typedef int (*CU_InitializeFunc)(void) typedef int (*CU_CleanupFunc)(void) CU_pSuite CU_add_suite(const char* strName, CU_InitializeFunc pInit, CU_CleanupFunc pClean); CU_pTest CU_add_test(CU_pSuite pSuite, const char* strName, CU_TestFunc pTestFunc); typedef struct CU_TestInfo typedef struct CU_SuiteInfo CU_ErrorCode CU_register_suites(CU_SuiteInfo suite_info[]); CU_ErrorCode CU_register_nsuites(int suite_count, ...); Щоб додати нібір тестів в реєстр необхідно використовувати функцію: CU_pSuite CU_add_suite(const char* strName, CU_InitializeFunc pInit, CU_CleanupFunc pClean) Вона створює нову колекцію(набір) тестів з певним ім’ям, функцією ініціалізації і функцією завершення. Новий набір тестів знаходиться в реєстрі тестів, тому він повинен бути ініціалізований перед додаванням тестів. Дана реалізація CUnit не підтримує створення наборів тестів без реєстру тестів. Ім’я набору повинно бути унікальне для всі наборів реєстру. Функції ініціалізації і завершення є необов’язковими і передаються у вигляді вказівників на функції, які будуть виконані до і після тестів в наборі тестів. Вони не приймають параметрів і не повертають значення 0 при успішному завершенні (при неуспішному завершенні – інше значення). Якщо цих функції не потрібно в наборі, то функції додавання набору CU_add_suite() треба передати аргументи NULL на їх місці. Функція повертає вказівник на новий набір тестів, який потрібен функції додавання тестів. При помилці повертається NULL і код помилки фреймворку приймає одне з наступних значень. Таблиця 5. Коди помилок встановлені функцією CU_add_suite() CUE_SUCCESS створення набору тестів успішне  CUE_NOREGISTRY реєстр не був ініціалізований  CUE_NO_SUITENAME немає імені набору  CUE_DUP_SUITE ім’я не унікальне  CUE_NOMEMORY помилка виділення пам’яті   Щоб додати тест в набір тестів існує функція CU_pTest CU_add_test(CU_pSuite pSuite, const char* strName, CU_TestFunc pTestFunc) Вона створює новий тест який має ім’я і тестову функцію, яку реєструє в певному наборі тестів. Набір тестів повинен бути створеним функцією CU_add_suite(). Ім’я тесту повинно бути унікальне в наборі тестів. Вказівник на тестову функцію повинен бути ненульовий і вказувати на функцію яка викличеться при виконанні тесту. Тестові функції не мають параметрів і не повертають значень. Функція повертає вказівник на новий тест.При помилці повертається NULL і код помилки фреймворку приймає одне з наступних значень. Таблиця 6. Коди помилок встановлені функцією CU_add_test() CUE_SUCCESS створення тесту успішне  CUE_NOSUITE Набір тестів не існує  CUE_NO_TESTNAME ім’я тесту не задано  CUE_NO_TEST Тестова функція не існує чи неправильна  CUE_DUP_TEST ім’я тесту не унікальне  CUE_NOMEMORY помилка виділення пам’яті   #define CU_ADD_TEST(suite, test) (CU_add_test(suite, #test, (CU_TestFunc)test)) Цей макрос автоматично створює унікальне імя, яке базується на імені тестової функції і додає її в певний набір тестів. Результат роботи повинен бути перевірений користувачем, щоб запобігти помилкам CU_ErrorCode CU_register_suites(CU_SuiteInfo suite_info[]) CU_ErrorCode CU_register_nsuites(int suite_count, ...) Для великих тестових структур з багатьма тестами і наборами тестів, управління тестами/наборами тестів і їх реєстрацією є стомлююче і в процесі можна допустити помилки. CUnit забезпечує спеціальну систему реєстрації для допомоги в управлінні тестами і наборами тестів. Вся суть цієї системи забезпечити централізацію реєстрації тестів і наборів тестів А також зменшити об’єм коду перевірки на помилки, який має писати користувач. Тести згруповані в масиви змінних структури CU_TestInfo  CU_TestInfo test_array1[] = { { "testname1", test_func1 }, { "testname2", test_func2 }, { "testname3", test_func3 }, CU_TEST_INFO_NULL, }; Кожен елемент масиву включає ім’я (унікальне) і тестову функцію для одного тесту. Масив має закінчуватись елементом з NULL значеннями, який оголошений макросом CU_TEST_INFO_NULL. Тести включені в єдиний масив CU_TestInfo формують єдину множину тестів, які будуть зареєстровані в одному наборів тестів. Інформація про набори тестів знаходиться в одному чи більше масивах елементів CU_SuiteInfo  CU_SuiteInfo suites[] = { { "suitename1", suite1_init-func, suite1_cleanup_func, test_array1 }, { "suitename2", suite2_init-func, suite2_cleanup_func, test_array2 }, CU_SUITE_INFO_NULL, }; Кожен з цих елементів масиву включає (унікальне) ім’я, функцію ініціалізаці набору тестів і функцію завершення набору тестів а також масив CU_TestInfo для кожного конкретного набору тестів. Якщо функцій ініціалізації чи завершення не потрібно, тоді вказується NULL. Масив повинен закінчуватися елементом з NULL значеннями, який оголошений макросом CU_SUITE_INFO_NULL. Всі набори тестів оголошені в CU_SuiteInfo масиві можна зареєструвати єдиним рядком. CU_ErrorCode error = CU_register_suites(suites); При виникненні помилки при реєстрації набору тестів чи тесту повертається код помилки. Код помилки такий самий, яки при виконання функцій CU_add_test() і CU_add_suit(). Функція CU_register_nsuites()  призначена для ситуацій коли користувач хоче зареєструвати багато CU_SuiteInfo масивів одним рядком коду CU_ErrorCode error = CU_register_nsuites(2, suites1, suites2); Функція приймає кількість масивів для реєстрації і самі масиви. Перший параметр – це кількість масивів. Таблиця 7. Старі версії функцій Старі імена Нові імена  TestFunc CU_TestFunc  InitializeFunc CU_InitializeFunc  CleanupFunc CU_CleanupFunc  _TestCase CU_Test  PTestCase CU_pTest  _TestGroup CU_Suite  PTestGroup CU_pSuite  add_test_group() CU_add_suite()  add_test_case() CU_add_test()  ADD_TEST_TO_GROUP() CU_ADD_TEST()  test_case_t CU_TestInfo  test_group_t CU_SuiteInfo  test_suite_t no equivalent - use CU_SuiteInfo  TEST_CASE_NULL CU_TEST_INFO_NULL  TEST_GROUP_NULL CU_SUITE_INFO_NULL  test_group_register CU_register_suites()  test_suite_register no equivalent - use CU_register_suites()   Виконання тестів Cunit забезпечує виконання всіх тестів в усіх зареєстрованих наборах тестів, але також можна виконувати і окремі тести. Протягом кожного запуску фреймворк зберігає стан кожного набору тестів, запущені тести, пройдені тести і не пройдені тести. Треба мати на увазі, що результати очищуються кожного разу, коли тести запускаються(навіть непройдені). Тоді як Cunit забезпечує виконання примітивних функцій для запуску тестів і наборів тестів, користувач хоче використовувати один з мпрощених інтерфейсів користувача. Вони скривають деталі взаємодії з фреймворком і забезпечують вивід деталей виконання тестів і результати для користувача. В CUnit є наступні інтерфейси Таблиця 8. Список інтерфейсів користувача Інтерфейс Платформа Опис  Automated all Не інтерактивний з виводом xml файлів  Basic all Не інтерактивний з виводом в stdout  Console all Інтерактивний консольний режим під контролем користувача  Curses Linux/Unix Інтерактивний режим з контролем користувача   Якщо цих інтерфейсів недостатньо, користувачі можуть також використовувати примітивні API фреймворку. Для взаємодії з фреймворком потрібно читати його документацію. Атоматичні інтерфейси не інтерактивні. Клієнт запускає тести і результати виводяться в xml файл. Лістин зареєстрованих тестів і наборів тестів також можна знайти в xml файлі. Наступна функція включає автоматичний інтерфейс АРІ: void CU_automated_run_tests(void) Виконує всі тести в усіх заєрестрованих наборах тестів. Результат тестів виводиться в файл ROOT-Results.xml. Ім’я ROOT може бути задано функцією CU_set_output_filename(). Якщо ім’я файлу не задано перед кожним запуском результат файлу буде перезаписано. CU_ErrorCode CU_list_tests_to_file(void) Записує список зареєстрованих наборів тестів і тестів в файл. Файл називається ROOT-Listing.xml. Файл з лістингом не генерується при виконання тестів. Клієнський код повинен явно вказати це функцією CU_automated_run_tests(). Ім’я ROOT може бути задано функцією CU_set_output_filename(). Якщо ім’я файлу не задано перед кожним запуском результат файлу буде перезаписано. void CU_set_output_filename(const char* szFilenameRoot) Встановлює імена файлів для виводу результатів тестування і лістингу. szFilenameRoot використовується для для побудови імен додаючи до них Results.xml і -Listing.xml, відповідно. Базовий інтерфейс також не інтерактивний. Результати зписуються в stdout. Інтерфейс забезпечує виконання окремих наборів тестів і тестів і дозволяє клієнтському коду контролювати тип виводу на кожному виконанні тесту. Він забезпечує значну гнучкість для клієнтів, які хочуть простий доступ до Cunit API. Він забезпечується наступними функціями: CU_ErrorCode CU_basic_run_tests(void) Виконує тести в усіх зареєстрованих наборах тестів. Повертає код першої помилки яка виникає при виконанні тесту. Тип виводу контролюється типом виконання, який встановлюється функцією CU_basic_set_mode(). CU_ErrorCode CU_basic_run_suite(CU_pSuite pSuite) Виконує всі тести з певного набору тестів. Повертає код першої помилки яка виникає при виконанні тесту. Тип виводу контролюється типом виконання, який встановлюється функцією CU_basic_set_mode(). CU_ErrorCode CU_basic_run_test(CU_pSuite pSuite, CU_pTest pTest) Виконує певний тест з певного набору тестів. Повертає код першої помилки яка виникає при виконанні тесту. Тип виводу контролюється типом виконання, який встановлюється функцією CU_basic_set_mode(). void CU_basic_set_mode(CU_BasicRunMode mode) Встановлює базовий режим виконання, який контролює вивід протягом виконання тестів CU_BRM_NORMAL Невдалі тести і результати  CU_BRM_SILENT Не виводиться нічог окрім помилок виконання  CU_BRM_VERBOSE Виводиться все  CU_BasicRunMode CU_basic_get_mode(void) Отримати поточний режим виводу. void CU_basic_show_failures(CU_pFailureRecord pFailure) Виводить результати провалених тестів в stdout. Не залежить від режиму виконання. Консольний режим є інтерактивний. Все що потрібно зробити користувачу – це ініціалізувати сесію консолі, і користувач може інтерактивно керувати виконанням тестів. А сасе він керує зареєстрованими наборами тестів і тестами і отримує результати тестів. Щоб запусти консольний режим треба виконати функцію void CU_console_run_tests(void) Інтерактивний режим для Linux. Користувачу слід запустити сесію і контролювати тестування інтерактивно. Можна вибирати і виконувати тести і набори тестів і переглядати їх результати тестів. Використання цього інтерфейсу потребує зв’язування бібліотеки з програмою. Щоб запустити сесію слід використати: void CU_curses_run_tests(void) Інтерфейси представляють результати виконання тестів, але клієнтський код має безпосередньо доступитися до результату. Він включає різні результати виконання включаючи провалені тести з результатами виконанн. Результати перезаписуються кожен раз при виконанні тестів чи при ініціалізації завершенні роботи реєстру. Функції доступу до результатів тестів: unsigned int CU_get_number_of_suites_run(void) unsigned int CU_get_number_of_suites_failed(void) unsigned int CU_get_number_of_tests_run(void) unsigned int CU_get_number_of_tests_failed(void) unsigned int CU_get_number_of_asserts(void) unsigned int CU_get_number_of_successes(void) unsigned int CU_get_
Антиботан аватар за замовчуванням

28.03.2013 20:03-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!