Тестирование программы магистерской диссертации. Курсовая работа по дисциплине Тестирование программного обеспечения на тему Тестирование программы магистерской диссертации
Скачать 257.99 Kb.
|
МИНИСТЕРСТВО ТРАНСПОРТА РОССИЙСКОЙ ФЕДЕРАЦИИ ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «РОССИЙСКИЙ УНИВЕРСИТЕТ ТРАНСПОРТА (МИИТ)» РУТ (МИИТ) Кафедра «Вычислительные системы, сети и информационная безопасность» КУРСОВАЯ РАБОТА по дисциплине «Тестирование программного обеспечения» на тему «Тестирование программы магистерской диссертации» Выполнили: студенты группы УВВ-251 Захаров Ю.М. Преоверил: Давыдовский М.А. Москва 2022 СОДЕРЖАНИЕЗАДАНИЕ 2 КОД ПРОГРАММЫ НА ЯЗЫКЕ С++ 3 ПРИМЕР РАБОТЫ ПРОГРАММЫ 11 ВАРИАНТЫ ТЕСТОВ И ИХ КОД 13 ПРОВЕРКА РАБОТЫ ТЕСТОВ 16 ВЫВОД 18 ЗАДАНИЕРазработать тесты с использованием одной из систем модульного тестирования (JUnit, CUnit, NUnit, unittest и др). Провести тестирование всех модулей программы (порядка 10 модулей). Описание программы Разработка на c++ с использованием библиотек для модульного тестирования CPPUnit. Программа имитирует работу микроконтроллера Arduino с датчиками давления и температуры и передает сообщения на светодиодную матрицу (в данном случае в консоль) с указанными параметрами (например цвет, скорость отображения текста и т.д.). КОД ПРОГРАММЫ НА ЯЗЫКЕ С++#include #include #include #include #include #include #include #include #include #include #include using namespace std; HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); int gSpeed = 400; class Temperature { private: string degree; public: const int static maximum = 46; const int static minimum = -60; string getDegree() { // 7)получение температуры int cur = stoi(degree); if ((cur > maximum)||(cur < minimum)) return "[" + degree + "] Датчик температуры неисправен"; if (cur > 0) return "+" + degree + " C"; return degree + " C"; } // 1) установка температуры bool setDegree(const string& f) { if (f.length() < 1) { this->degree = "111"; return false; } if (f.length() > 3) { this->degree = "1000"; return false; } std::regex e("^-?\\d+"); if (std::regex_match(f, e)) { this->degree = f; return true; } else this->degree = "999"; return false; } }; class Pressure { private: string mmhg; public: const int static maximum = 800; const int static minimum = 600; string getPressure() { // 8) получение давления int cur = stoi(mmhg); if ((cur > maximum) || (cur < minimum)) return "[" + mmhg + "] Датчик давления неисправен"; return mmhg + " мм рт ст"; } //2) установка давления bool setPressure(const string& s) { if (s.length() < 1) { this->mmhg = "000"; return false; } if (s.length() > 3) { this->mmhg = "1000"; return false; } string::const_iterator it = s.begin(); while (it != s.end() && std::isdigit(*it)) ++it; if (!s.empty() && it == s.end()) { this->mmhg = s; return true; } else this->mmhg = "999"; return false; } }; class Matrix { private: vector unsigned int Intensity; unsigned int Rotation; public: Matrix() { tape.push_back("1"); Intensity = 0; Rotation = 0; } void setRotation(const unsigned int& rot) { // 3)установка ротации if (rot < 0 || rot > 15) this->Rotation = 0; else this->Rotation = rot; } void setIntensity(const unsigned int& ints) { //4)установка интенсивности if (ints < 1 || ints > 4) this->Intensity = 1; else this->Intensity = ints; } string setMessage(string tape) { // 5)Установка сообщения if (tape.length() < 2 && tape[0] != '0' && tape[0] != '1') tape = "Ошибка получения сообщения"; if (tape.length() > 250) { cout << "Ошибка сообщение слишком большое" << endl; tape = tape.substr(tape.length() - 250); tape.append("..."); } this->tape.push_back(tape); return tape; } int getRotation() { return this->Rotation; } int getIntensity() { return this->Intensity; } string getMessage(int i) { return this->tape[i]; } int getSize() { return this->tape.size(); } }; string utf8rus2(string source) { int i, k; string target; unsigned char n; char m[2] = { '0', '\0' }; k = source.length(); i = 0; while (i < k) { n = source[i]; i++; if (n >= 0xC0) { switch (n) { case 0xD0: { n = source[i]; i++; if (n == 0x81) { n = 0xA8; break; } if (n >= 0x90 && n <= 0xBF) n = n + 0x2F; break; } case 0xD1: { n = source[i]; i++; if (n == 0x91) { n = 0xB7; break; } if (n >= 0x80 && n <= 0x8F) n = n + 0x6F; break; } } } m[0] = n; target = target + string(m); } return target; } class Msg { public: Msg() { ; }; virtual void setMsg(string msg) { return; }; virtual string Serial_Read() { //6) ввод string message = ""; cout << "Reading from input channel..." << endl; while (!(cin >> message)) { cin.clear(); } cout << "Trying to set tape message as <<" << message << ">>" << endl; if (message == "") message = "No message"; return message; }; }; class mockMsg : public Msg { protected: string mess = ""; public: void setMsg(string msg) { this->mess = msg; }; string Serial_Read() override { cout << "Reading from input channel..." << endl; cout << "Trying to set tape message as <<" << mess << ">>" << endl; if (mess == "") mess = "No message"; return mess; }; }; void setup(Matrix& matrix) { matrix.setMessage("Приветствуем !"); matrix.setIntensity(5); // Задаем яркость от 0 до 15 matrix.setRotation(3); // Направление текста 1,2,3,4 SetConsoleTextAttribute(hConsole, 13); cout << "Trying to send tape message with Intesnsivity " << matrix.getIntensity() << " and Rotation " << matrix.getRotation() << endl; SetConsoleTextAttribute(hConsole, 7); }; void loop(Matrix& matrix) { // 10) проверка сообщений Msg run; while (matrix.getMessage(matrix.getSize()-1)[0] != '0') { matrix.setMessage(run.Serial_Read()); } cout << "Getting current temperature value..." << endl; Temperature temp; temp.setDegree(run.Serial_Read()); matrix.setMessage(temp.getDegree()); cout << "Getting current pressure value..." << endl; Pressure pres; pres.setPressure(run.Serial_Read()); matrix.setMessage(pres.getPressure()); }; bool trySkipMessage(string rus_message) { if ((rus_message == "Ошибка получения сообщения") || (rus_message[0] == '0' || rus_message[0] == '1')) { cout << "Skipping message <<" << rus_message << ">>" << endl; return true; } else { SetConsoleTextAttribute(hConsole, 13); for (int j = 0; j < rus_message.length(); j++) { cout << rus_message[j]; Sleep(gSpeed); } cout << endl; return false; } }; int send_messages(Matrix& matrix) { // 11) Отправка сообщения int sended = 0; for (int i = 0; i < matrix.getSize(); i++) { SetConsoleTextAttribute(hConsole, 7); string rus_message = matrix.getMessage(i); cout << "Sending message: " << rus_message << " -> "; rus_message = utf8rus2(rus_message); if(!trySkipMessage(rus_message)) sended++; } return sended; }; class TaskTest : public CppUnit::TestFixture { Matrix *matrix; Temperature* temp; Pressure* pres; Msg* run; public: void setUp() { matrix = new Matrix; temp = new Temperature; pres = new Pressure; run = new mockMsg(); } /* 1 модуль */ /* Проверка количества символов в сообщении (меньше) */ void testArgLess() { string m = matrix->setMessage("Test"); CPPUNIT_ASSERT(m.length() > 1); } /* Проверка количества символов в сообщении (больше) */ void testArgMore() { string m = matrix->setMessage("Test"); CPPUNIT_ASSERT(m.length() < 251); } /* 2 модуль */ /* Проверка "скипинга" */ void testSkip1() { bool res = trySkipMessage("Test-message333"); CPPUNIT_ASSERT(!res); } void testSkip2() { bool res = trySkipMessage("0"); CPPUNIT_ASSERT(res); } /* 3 модуль */ /* Проверка количества отправки */ void testSended() { matrix->setMessage("t"); matrix->setMessage("b"); matrix->setMessage("Test-1111111111"); matrix->setMessage("FFFFFF"); matrix->setMessage("Test-message333"); matrix->setMessage("0"); int sended = send_messages(*matrix); CPPUNIT_ASSERT(sended == 3); } /* 4 модуль */ /* Проверка Температуры (меньше) */ void testTempM() { temp->setDegree("-32"); matrix->setMessage(temp->getDegree()); int size = matrix->getSize(); string deg = matrix->getMessage(size - 1); CPPUNIT_ASSERT(stoi(deg) > temp->minimum); } /* Проверка Температуры (больше )*/ void testTempP() { temp->setDegree("32"); matrix->setMessage(temp->getDegree()); int size = matrix->getSize(); string deg = matrix->getMessage(size - 1); CPPUNIT_ASSERT(stoi(deg) < temp->maximum); } /* 5 модуль */ /* Проверка свойства Rotation (яркость от 0 до 15) */ void testRotation1() { matrix->setRotation(1); int rot = matrix->getRotation(); CPPUNIT_ASSERT(rot >= 0 && rot <= 15 ); } /* Проверка свойства Rotation > 15 */ void testRotation2() { matrix->setRotation(16); int rot = matrix->getRotation(); CPPUNIT_ASSERT(rot == 0); } /* 6 модуль */ /* Проверка свойства Intensity (Направление текста 1,2,3,4) */ void testIntensity1() { matrix->setIntensity(1); int ints = matrix->getIntensity(); CPPUNIT_ASSERT(ints >= 1 && ints <= 4); } /* Проверка свойства Intensity > 4 */ void testIntensity2() { matrix->setIntensity(5); int ints = matrix->getIntensity(); CPPUNIT_ASSERT(ints == 1); } /* 7 модуль */ /* Проверка того, что getPressure возвращает ошибку при нереальных значениях давления */ void testPressure() { pres->setPressure("999"); string err = pres->getPressure(); CPPUNIT_ASSERT(err == "[999] Датчик давления неисправен"); } /* 8 модуль */ /* Проверка того, что setDegree возвращает ошибку при нереальных значениях температуры */ void testDegree() { temp->setDegree("-99"); string err = temp->getDegree(); CPPUNIT_ASSERT(err == "[-99] Датчик температуры неисправен"); } /* 9 модуль */ /* Проверка давления за пределами разрешенных значений */ void testSetPressure1() { bool err = pres->setPressure("9999"); CPPUNIT_ASSERT(err == false); } void testSetPressure2() { bool err = pres->setPressure(""); CPPUNIT_ASSERT(err == false); } /* Проверка давления в пределах разрешенных значений */ void testSetPressure3() { bool err = pres->setPressure("788"); CPPUNIT_ASSERT(err == true); } /* 10 модуль */ /* Проверка отсутствия сообщений на ленте Используется заглушка (для имитации ввода пользователя)*/ void testSerial1() { string nom = run->Serial_Read(); CPPUNIT_ASSERT(nom == "No message"); } void testSerial2() { run->setMsg("try"); string nom = run->Serial_Read(); CPPUNIT_ASSERT(nom == "try"); } static CppUnit::Test* suite() { CppUnit::TestSuite* suite = new CppUnit::TestSuite; suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller suite->addTest(new CppUnit::TestCaller return suite; } }; int main(int argc, char* argv[]) { setlocale(LC_ALL, "rus"); int color = 13; //33 start: int a = 0; cin >> a; if (a == 0){ gSpeed = 10; CppUnit::TextUi::TestRunner run; run.addTest(TaskTest::suite()); run.run(); } else { Matrix matrix; setup(matrix); loop(matrix); int sending = 1; while (sending > 0) sending = send_messages(matrix); } goto start; system("pause"); } ПРИМЕР РАБОТЫ ПРОГРАММЫРисунок 1 – Ввод исходных данных Рисунок 2 – Цикл вывода сообщений на матрицу Рисунок 3 – Пример некорректных данных на входе ВАРИАНТЫ ТЕСТОВ И ИХ КОД1 модуль. Изначально в качестве ограничения размера буфера сообщения взято 250 символов. Первые два теста проверяют, что сообщения попадают в эти промежутки. /* 1 модуль */ /* Проверка количества символов в сообщении (меньше) */ void testArgLess() { string m = matrix->setMessage("Test"); CPPUNIT_ASSERT(m.length() > 1); } /* Проверка количества символов в сообщении (больше) */ void testArgMore() { string m = matrix->setMessage("Test"); CPPUNIT_ASSERT(m.length() < 251); } 2 модуль. Сообщения размером меньше 3 символов или содержащие сообщение об ошибке не должны выводиться на матрицу. Следующие два теста проверяют будут ли выводиться корректные сообщения и заведомо «ошибочные». /* 2 модуль */ /* Проверка "скипинга" */ void testSkip1() { bool res = trySkipMessage("Test-message333"); CPPUNIT_ASSERT(!res); } void testSkip2() { bool res = trySkipMessage("0"); CPPUNIT_ASSERT(res); } 3 модуль. В функции отправки сообщений ведется подсчет корректных сообщений. Следующий тест проверяет совпадает ли счетчик функции с ожидаемым результатом при отправке 6 различных сообщений. /* 3 модуль */ /* Проверка количества отправки */ void testSended() { matrix->setMessage("t"); matrix->setMessage("b"); matrix->setMessage("Test-1111111111"); matrix->setMessage("FFFFFF"); matrix->setMessage("Test-message333"); matrix->setMessage("0"); int sended = send_messages(*matrix); CPPUNIT_ASSERT(sended == 3); } 4 модуль. В программе заданы граничные значения температур (макс и мин). Если значения сильно уходят за предел рационального, то получаем сообщения о неисправности датчика. Ниже представлены тесты, которые проверяют входят ли значения 32/-32 в промежуток «адекватных» значений температуры. /* 4 модуль */ /* Проверка Температуры (меньше) */ void testTempM() { temp->setDegree("-32"); matrix->setMessage(temp->getDegree()); int size = matrix->getSize(); string deg = matrix->getMessage(size - 1); CPPUNIT_ASSERT(stoi(deg) > temp->minimum); } /* Проверка Температуры (больше )*/ void testTempP() { temp->setDegree("32"); matrix->setMessage(temp->getDegree()); int size = matrix->getSize(); string deg = matrix->getMessage(size - 1); CPPUNIT_ASSERT(stoi(deg) < temp->maximum); } 5 модуль. Яркость отображения настраивается в скетче Arduino. В представленной программе эти значения не несут какого то значения. Но при использовании в Arduino у них есть четкие ограничения от 0 до 15. В случае если установлено значение за этими пределами, значение яркости устанавливается равным 0. Приведенные тесты проверяют передачу корректных и некорректных значений. /* 5 модуль */ /* Проверка свойства Rotation (яркость от 0 до 15) */ void testRotation1() { matrix->setRotation(1); int rot = matrix->getRotation(); CPPUNIT_ASSERT(rot >= 0 && rot <= 15 ); } /* Проверка свойства Rotation > 15 */ void testRotation2() { matrix->setRotation(16); int rot = matrix->getRotation(); CPPUNIT_ASSERT(rot == 0); } 6 модуль. Направление текста – еще одно свойство, которое настраивается в скетче Arduino. При использовании в Arduino значения могут быть 1,2,3 и 4. В случае если установлено значение за этими пределами, значение направления устанавливается равным 1. Приведенные тесты проверяют передачу корректных и некорректных значений. /* 6 модуль */ /* Проверка свойства Intensity (Направление текста 1,2,3,4) */ void testIntensity1() { matrix->setIntensity(1); int ints = matrix->getIntensity(); CPPUNIT_ASSERT(ints >= 1 && ints <= 4); } /* Проверка свойства Intensity > 4 */ void testIntensity2() { matrix->setIntensity(5); int ints = matrix->getIntensity(); CPPUNIT_ASSERT(ints == 1); } 7 модуль. В программе заданы граничные значения давления (макс и мин). Если значения сильно уходят за предел рационального, то получаем сообщения о неисправности датчика. Ниже представлены тесты, которые проверяют значения, вызывающие сомнения в корректности. /* 7 модуль */ /* Проверка того, что getPressure возвращает ошибку при нереальных значениях давления */ void testPressure() { pres->setPressure("999"); string err = pres->getPressure(); CPPUNIT_ASSERT(err == "[999] Датчик давления неисправен"); } 8 модуль. Ниже представлены тесты, которые проверяют значения, вызывающие сомнения в корректности для температурного датчика. /* 8 модуль */ /* Проверка того, что setDegree возвращает ошибку при нереальных значениях температуры */ void testDegree() { temp->setDegree("-99"); string err = temp->getDegree(); CPPUNIT_ASSERT(err == "[-99] Датчик температуры неисправен"); } 9 модуль. Так же при установке значения температуры/давления проверяется длина полученного сообщения. Если она выходит за пределы норм, то метод возвращает false, если все корректно, то true. Далее проверяются несколько некорректных и одно корректное значения. /* 9 модуль */ /* Проверка давления за пределами разрешенных значений */ void testSetPressure1() { bool err = pres->setPressure("9999"); CPPUNIT_ASSERT(err == false); } void testSetPressure2() { bool err = pres->setPressure(""); CPPUNIT_ASSERT(err == false); } /* Проверка давления в пределах разрешенных значений */ void testSetPressure3() { bool err = pres->setPressure("788"); CPPUNIT_ASSERT(err == true); } 10 модуль. Данный тест проверяет ситуацию, когда с входным буфер произошла проблема и сообщение не поступило. В данном тесте также используется заглушка для имитации ввода пользователя. На самом деле значения в объект передаются методом setMsg(). Далее фактический результат сверяется с ожидаемым. При получении пустого сообщения на «ленту» оно заменяется текстом «No message». /* 10 модуль */ /* Проверка отсутствия сообщений на ленте Используется заглушка (для имитации ввода пользователя)*/ void testSerial1() { string nom = run->Serial_Read(); CPPUNIT_ASSERT(nom == "No message"); } void testSerial2() { run->setMsg("try"); string nom = run->Serial_Read(); CPPUNIT_ASSERT(nom == "try"); } ПРОВЕРКА РАБОТЫ ТЕСТОВРабота тестов без внесения ошибок: Рисунок 4 – Тесты – корректное завершение Добавим в код программы ошибку, например сделаем минимальные и максимальные значения температуры равными 0 (были -46 и +60). Измененный код: class Temperature { private: string degree; public: const int static maximum = 0; // 60 const int static minimum = 0; // -46 … } Работа автоматического теста с ошибкой: Рисунок 5 – Тесты – ошибки с исключениями в 2 тестах из 18 ВЫВОДВ данной курсовой работе была разработана программа, имитирующая разрабатываемую по теме диссертационной работы сборку. Были разработаны модульные тесты с использованием системы модульного тестирования CPPUnit, проверена работа подставного объекта. |