Поможем написать учебную работу
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.
Цель работы
Освоить приемы подготовки тестов и изучить программные средства тестирования модулей
Используемые средства
Microsoft Visual Studio 2005/2008 (MS VS), библиотека CppUnit.
Порядок выполнения работы
1. В соответствии с заданием разработать приложение. Приложение должно состоять из двух частей: головной программы и библиотеки, содержащей модули.
2. Выполнить планирование тестирования модуля из разработанной библиотеки: составить таблицы тестов.
3. Создать тестирующее приложение с применением библиотеки CppUnit. Реализовать в нем все запланированные тесты. Выполнить запуск тестов и анализ результатов. Если все тесты прошли успешно, то в исследовательских целях изменить условия проверок таким образом, чтобы вызвать реакцию библиотеки на ошибки.
4. Составить отчет о проделанной работе.
Содержание отчета
1. Цель работы.
2. Текст задания.
3. Планирование тестов.
4. Тексты исходного кода тестируемого модуля и тестирующего проекта.
5. Описание фактического процесса выполнения тестирования и отладки, с указанием, какие ошибки выявлялись и какие изменения вносились в процессе отладки.
6. Выводы.
Задание
8. Обмен местами двух заданных поддеревьев.
Пример выполнения работы
Задача. Разработать класс стека. Выполнить тестирование его методов занесения элемента в стек и извлечения из стека.
Создаем приложение и библиотеку с объявлением класса. MS VS по умолчанию при открытии создает пустое решение, где можно создавать свои проекты или добавлять существующие. Для того, чтобы создать проект заходим в меню Файл->Создать->Проект.
Выбираем проект типа "Проект Win32" и задаем имя StackApp.
Далее появится мастер создания нового проекта
Нажимаем далее, чтобы задать на следующем окне мастера тип приложения "Статическая библиотека" с поддержкой предварительно скомпилированных заголовков (галочка "Предварительно скомпилированный заголовок").
Наживаем готово. В результате в обозревателе решений MS VS можно увидеть только что созданный проект.
Далее либо в обозревателе решений либо в окне классов (вторая владка внизу окна обозревателя решений) добавляем новый класс Stack. Для этого на имени проекта необходимо нажать правой кнопкой мыши и выбрать меню "Добавить->Класс".
Появится окно, в котором можно выбрать элементы для вставки в проект. Выбираем "Класс C++".
Наживаем "Добавить" и в появившемся окне мастера пишем название добавляемого класса "Stack" нажимаем "Готово".
В Visual Studio 2010 имя Stack является зарезервированным, поэтому там необходимо написать отличное от Stack имя (поэтому на скриншотах встречается класс Stack1).
MS VS отобразит созданный класс в проекте и откроет для редактирования заголовочный файл и файл реализации добавленного класса Stack.
В заголовочный файл Stack.h добавляем определения методов (в коде исправлено Stack1 на Stack)
#pragma once #include <vector> // Для использования STL using namespace std; class Stack { private: vector<int> _body; public: Stack(int capacity); virtual ~Stack(); // Положить в стек void push(int value); // Взять из стека int pop(); // Получить значение на вершине стека int onTop(); // Размер стека int size(); }; |
В файл реализации добавляем определения методов класса
#include "StdAfx.h" #include "Stack.h" Stack::Stack(int capacity) : _body(capacity) { } Stack::~Stack() { } void Stack::push(int value) { if (_body.size() < _body.capacity()) { _body.push_back(value); } } int Stack::pop() { int result = 0; if (!_body.empty()) { result = _body.back(); _body.pop_back(); } return result; } int Stack::onTop() { int result = 0; if (!_body.empty()) { result = _body.back(); } return result; } int Stack::size() { return _body.size(); } |
Компилируем проект и убеждаемся в отсутствии ошибок. Для этого выбираем меню "Построение->Построить StackApp" (либо построить решение, так пока в решении только один проект, поэтому скомпилиреутся приложение StackApp. Так же можно воспользоваться контекстным меню проекта, щелкнув для этого правой кнопкой мыши по названию проекта. Далее выбрать пункт "Построение").
Информация о построении будет выведена в окне "Вывод", располагающемся в низу MS VS (если окно закрыто, его можно открыть через меню "Вид->Вывод").
Закрываем решение "Файл->Закрыть решение" или просто закрыть MS VS и создаем новое приложение, с помощью которого будем выполнять тестирование разработанной библиотеки. Для этого создадим новый проект. При создании проекта выберем тип создаваемого проекта "Консольное приложение Win32" и зададим имя StackTests.
В мастере создания нового проекта отмечаем создание проекта с готовым файлом для головной функции ("Предварительно скомпилированный заголовок").
MS VS отобразит созданный проект
В файл головной функции вставляем следующий текст, который выполняет запуск всех тестов, зарегистрированных в данной приложении (пока что ни одного теста нами не создано).
// StackTests.cpp: определяет точку входа для консольного приложения. // #include "stdafx.h" #include "cppunit/ui/text/TestRunner.h" #include "cppunit/extensions/TestFactoryRegistry.h" int main(int argc, char* argv[]) {
CppUnit::TextUi::TestRunner runner; CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); runner.addTest( registry.makeTest() ); bool wasSucessful = runner.run( "", false );
return wasSucessful; } |
Далее проект необходимо будет настроить так, чтобы указанные в директивах include пути указывали на каталог с заголовочными файлами библиотеки CppUnit.
Для этого прежде необходимо скомпилировать библиотеки пакета CppUnit. Последнюю версию пакета и документацию к нему можно скачать по адресу:
http://sourceforge.net/projects/cppunit/files/. Скачанный архив, в нашем случае cppunit-1.12.1, необходимо разархивировать в какую-либо папку, чтобы на нее в последствии можно было ссылаться. Внутри разархивированного архива можно найти инструкцию по работе с CppUnit для платформы win32 - INSTALL-WIN32.txt. Внутри этого документа стоит обратить внимание на разделы Building, в нем описывается как скомпилировать библиотеки CppUnit (они необходимы для работы), Libraries, описывает какие библиотеки должны быть скомпилированный, Project build Target, описывает предназначения библиотек.
При компиляции библиотек в Visual Studio 2008 Rus возникли ошибки компиляции. Для того чтобы их устранить нужно отредактировать файл MsDevCallerListCtrl.cpp, он находится по адресу " cppunit-1.12.1\src\msvc6\testrunner\", где "cppunit-1.12.1" - папка, куда был разархивирован CppUnit.
В файле необходимо найти
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("7.0") lcid("0") raw_interfaces_only named_guids |
и заменить на
#import "libid:80cc9f66-e7d8-4ddd-85b6-d9e6cd0e93e2" version("9.0") lcid("0") raw_interfaces_only named_guids |
где version означает номер версии MS VS (для 2005 - 8.0, для 2008 - 9.0).
Далее можно приступать к компиляции библиотек CppUnit. Для этого в MS VS откроем проект " CppUnitLibraries.dsw", находящийся по адресу " cppunit-1.12.1\src\". ("Файл->Открыть->Решение или проект")
На все предложения системы о преобразовании проекта отвечаем утвердительно
Открытое решение будет состоять из шести проектов
Согласно инструкциям из файла INSTALL-WIN32.txt выбирает меню "Построение->Пакетное построение"
В появившемся окне выбираем "Выделить все" и "Построить"
Начнется процесс компиляции библиотек CppUnit. Скомпилированный библиотеки можно найти по адресу: cppunit-1.12.1\lib\
После завершения компиляции решение можно закрыть и продолжить работу с проектом StackTests. Для этого откроем StackTests. Настроим свойства проекта. Для этого выберем меню "Проект->Свойства" (можно воспользоваться контекстным меню проекта, щелкнув для этого правой кнопкой мыши по названию проекта. Далее выбрать пункт "Свойства").
В появившемся окне Свойств проекта выбираем в "Свойствах конфигурации" пункт "C/C++"->"Общие". Здесь необходимо задать "Дополнительные каталоги включаемых файлов" (нажимаем на стрелочку и изменить).
В появившемся окне выбираем "Создать новую строку" (желтая папка). В добавленной новой строке прописываем путь к заголовочным файлам тестируемого приложения Stack и к папке include в CppUnit (путь можно не прописывать, а выбрать с помощью обозревателя папок, нажав на кнопку "..." в конце новой созданной строки).
В пункте "C/C++"->"Библиотека времени выполнения" убеждаемся, что установлено значение "Многопоточная отладка DLL (/MDd)".
Убедится, что все нужные значения прописаны можно в пункте "Командная строка" в "C/C++"
Далее прописываем название требуемой библиотеки CppUnit и путь к ней. Для этого нужно развернуть вкладку "Компоновщик" и выбрать меню "Ввод". К "Дополнительным зависимостям" добавляем библиотеку "cppunitd.lib".
Здесь же на вкладке "Компоновщик", нов пункте "Общие" задаем путь к этой библиотеке. Для этого необходимо изменить значение "Дополнительные каталоги библиотек". Там необходимо прописать путь к папке "cppunit-1.12.1\lib\".
Необходимые изменения в свойства проекта были внесены, поэтому окно свойств можно закрыть.
Добавляем в решение тестируемый проект. Для этого в обозревателе решений выбираем "Решение StackTests", в контекстном меню выбираем "Добавить->Существующий проект..." и находим файл тестируемого проекта StackApp.vcxproj.
MS VS отобразит оба проекта в решении StackTests. Далее надо установить тестирующий проект активным. Для этого в контекстном меню проекта StackTests выбираем "Назначить запускаемым проектом" (заголовок запускаемого проекта выделяется жирным шрифтом).
Через главное меню устанавливаем зависимость между проектами: "Проект->Зависимости проектов..." (можно воспользоваться контекстным меню проекта StackTests, щелкнув для этого правой кнопкой мыши по названию проекта. Далее выбрать пункт "Зависимости проектов...").
В появившемся окне указываем зависимость тестирующего проекта StackTests от тестируемого проекта Stack. Для этого отмечаем проект Stack галочкой.
Убеждаемся, что сборка проекта выполняется без ошибок. Можно запустить приложение ("Отладка->Начать отладку") и увидеть, что ни один тест не выполнен.
Добавим тестовый набор в виде класса StackTest в проект StackTests, аналогично тому, как делали ранее. В заголовочный файл тестового набора добавляем ссылки на библиотеку CppUnit:
#include "cppunit\extensions\HelperMacros.h" #include "cppunit\TestFixture.h" |
Добавляем ссылку на тестируемую библиотеку
#include "Stack.h" |
Наш класс тестового набора делаем потомком класса TestFixture из библиотеки CppUnit
class StackTest : public CppUnit::TestFixture |
На закладке "Окно классов" выбираем класс с тестовым набором StackTest и добавляем методы для тестирования.
Тестирующие методы должны иметь тип возвращаемого значения void и публичный уровень доступа.
Помимо указанного способа добавления методов, их можно добавить простым редактированием файла (в данном случаем StackTest.cpp).
После добавления тестирующих методов задаем их в тестовом наборе с помощью макросов из библиотеки CppUnit. В результате заголовочный файл класса тестового набора выглядит следующим образом:
#pragma once #include "cppunit\extensions\HelperMacros.h" #include "cppunit\TestFixture.h" #include "Stack.h" class StackTest : public CppUnit::TestFixture {
// Определение тестов тестового набора CPPUNIT_TEST_SUITE( StackTest ); // определение тестового набора, указывается имя класса
CPPUNIT_TEST( testPushWhenEmpty ); // определение тестового метода, указывается имя метода CPPUNIT_TEST( testPushWhenFull ); // -"- CPPUNIT_TEST( testPopWhenEmpty ); // -"- CPPUNIT_TEST( testPopWhenFull ); // -"-
CPPUNIT_TEST_SUITE_END(); // конец определения тестового набора
public: StackTest(void); ~StackTest(void); void testPopWhenFull(); void testPopWhenEmpty(); void testPushWhenFull(); void testPushWhenEmpty(); }; |
В файле реализации регистрируется класс тестового набора макросом CPPUNIT_TEST_SUITE_REGISTRATION из библиотеки CppUnit, чтобы исполняющая система библиотеки выполнила все заданные тестовые методы этого класса. В тестовые методы заносится тестирующий код.
#include "StdAfx.h" #include "StackTest.h" CPPUNIT_TEST_SUITE_REGISTRATION( StackTest ); StackTest::StackTest(void) { } StackTest::~StackTest(void) { } void StackTest::testPushWhenEmpty() { Stack c(10); c.push(12); CPPUNIT_ASSERT_EQUAL (12, c.onTop()); } void StackTest::testPushWhenFull() { Stack c(3); c.push(23); c.push(34); c.push(45); CPPUNIT_ASSERT_EQUAL(45, c.onTop()); // // Добавить элемент, когда стек заполнен // c.push(56); // Стек не должен измениться CPPUNIT_ASSERT_EQUAL(45, c.onTop()); } void StackTest::testPopWhenEmpty() { Stack c(10); CPPUNIT_ASSERT_EQUAL(0, c.size()); c.pop(); // Стек не должен измениться CPPUNIT_ASSERT_EQUAL(0, c.size()); } void StackTest::testPopWhenFull() { Stack c(3); c.push(23); c.push(34); c.push(45); CPPUNIT_ASSERT_EQUAL(45, c.onTop()); // // Удалить элемент, когда стек заполнен // c.pop(); // Стек не должен измениться CPPUNIT_ASSERT_EQUAL(34, c.onTop()); } |
Запускаем тестирующее приложение и получаем сообщения об ошибках, в которых указано имя файла с тестом, номер строки с проверкой правильности и нарушенное условие.
Далее выполняется отладка, для которой можно запустить приложение в отладочном режиме ("Отладка->Начать отладку") с использованием точек останова ("Отладка->Создать точку останова") и просмотром значений переменных, также можно использовать другие средства. В данном случае выясняется, что динамический размер массива данных стека всегда равен емкости массива. Поэтому изменяем код класса Stack следующим образом.
Заголовочный файл класса Stack (Stack.h)
#pragma once #include <vector> #include "Stack.h" using namespace std; class Stack { private: vector<int> _body; int _maxSize; public: Stack(int maxSize); virtual ~Stack(); // Положить в стек void push(int value); // Взяь из стека int pop(); // Получить значение на вершине стека int onTop(); // Размер стека int size(); }; |
Файл реализации класса Stack (Stack.cpp)
#include "StdAfx.h" #include "Stack.h" Stack::Stack(int maxSize) : _maxSize(maxSize) { } Stack::~Stack() { } void Stack::push(int value) { if (_body.size() < _maxSize) { _body.push_back(value); } } int Stack::pop() { int result = 0; if (!_body.empty()) { result = _body.back(); _body.pop_back(); } return result; } int Stack::onTop() { int result = 0; if (!_body.empty()) { result = _body.back(); } return result; } int Stack::size() { return _body.size(); } |
Теперь запуск тестов не вызывает сообщений об ошибках.
Тест может указать наличие ошибки в написанных тестах (. - тест успешно завершен, .F - тест обнаружил ошибку). Например, если внести изменения в размерность стека в методе testPushWhenFull, то тест покажет ошибку во втором тесте. Вместо ожидаемого значения "45" на вершине стека находится элемент со значением "34".
После выполнения тестирования, в исходное тестируемое приложение можно добавлять код, использующий класс стека.
Макросы анализа результатов тестирования
Ниже приведен перечень макросов из библиотеки CppUnit, используемых для автоматизированного анализа результатов тестирования
#define CPPUNIT_ASSERT(condition) Проверка того, что условие - истина
#define CPPUNIT_ASSERT_MESSAGE(message, condition) проверка со специальным сообщением
#define CPPUNIT_FAIL(message) возбуждение ошибки со специальным сообщением
#define CPPUNIT_ASSERT_EQUAL(expected, actual) проверка равенства двух чисел
#define CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expected, actual) проверка того, что два значения равны с дополнительным сообщением в случае ошибки
#define CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, actual, delta) проверка равенства двух вещественных чисел |