Материал: Разработка и реализация программных средств для работы с веб-контентом в рамках проекта INTERIN PROMIS

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Цель тестирования: Подтвердить, что система реализована в соответствии с предъявленными к ней функциональными требованиями и полностью готова к работе, при этом система воспринимается как единый «чёрный ящик».

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

Исходные данные и результаты тестирования приведены в Таблице 4.1. Графа оценка определяет соответствие результатов ожидаемым («+» - соответствуют, «-» - нет).

Таблица 4.1 - Исходные данные и результаты тестирования программной системы

Исходные данные

Результат

Оценка

Запуск инсталлятора

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

+

Запук исполняемого файла клиента

Открывается приложения и начинается проверка обновлений, по ее завершению запускается главное окно

+

Нажатие на пунк меню

Открывается выбранное подменю

+

Изменение параметро системы

После сохранения именений результат успешно применяется

+

Запуск обновления

Запускается подсистема обновлений

+

Измнение размеров окна программы

Изменения применяются, пропорции отображаемого материала сохраняются

+

Нажатие на попункт меню "Печать в PDF"

Открывается диалоговое окно печати с возможностью выбора параметров

+

Нажатие на понкт меню "Помощ"

Открывается информационное окно "О программе"

+

Изменение адреса получения обновлений на локальный

Программа меняет протокол обмена данными и получает обновления из локальной папки

+

Переход по ссылке в МИС на открытие тектового файла

Идет загрузка фала, затем его открытие в выбранном тектовом редакторе.

+

Переход по ссылке в МИС на прямую печать тектового файла

Идет загрузка фала, затем его преобразование в pdf формат и отправка на принтер. От пользователя скрыт весь процесс.


Нажание на подпунк меню "Выход"

Программа закрывается

+

 

4.3 Тестирование модульной расширяемости

Для изменения логики работы всей системы достаточно в ее параметрах указать название другого модуля главного окна. На рисунке 4.2 представлен пример работы главного модуля, которы имеет название "InterinClntMainWnd_2.0.10.dll ".

Рисунок 4.2 - Пример работы модуля "InterinClntMainWnd_2.0.10.dll"

На рисунке 4.3 представлен процесс изменения главного исполнемого модуля на "InterinClntMainWnd_2.0.4.dll".

Рисунок 4.3 - Пример изменения главного исполняемого модуля

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

На рисунке 4.4 представлен пример работы главного модуля, которы имеет название "InterinClntMainWnd_2.0.4.dll ".

Рисунок 4.4 - Пример работы модуля "InterinClntMainWnd_2.0.4.dll"

Для расширения функиционала системы путем добавления бибилотек, а не их изменения потребуется в реестре операционной системы, в ветви "ModulesManeger" создать раздел. В нем разделе необхоимо создать такие параметры как module_path,module_name и version. В module_path необходимо указать полный путь до ибилотеки, а в module_name её полное наименование. После перезапуска программы, функционал реалиованный в данной бибилотеке будет доступен.

 

5. ВНЕДРЕНИЕ


Для внедрения клиента корпоративной информационной системы необходимо происталлировать програмный продукт на все необходимые рабочие места и насроить адрес домашней страницы. Далее, при необходимости, нужно установить программы для работы с тектовыми документами, а так же выбрать нужную в настройках. Для этого в настройках системы, в пункте "Редактор выходных форм" необходимо выбрать исполняемый файл тектового редактора. Данный процесс представлен на рисунке 5.1.

Рисунок 5.1 - Пример выбора редактора выходны фаорм

Вторым этапом внедрения является создание общего ресурса, на котором будет рассположены файлы обновления с их описанием. Разработанная подсистема обновлений позволяет без изменений использовать раличные протоколы обмена данными, такие как ftp,smb,file. Таким образом, необходимо только указать в настройках путь до папки с обновлениями.

На рисунке 5.2 представлен пример отображения медицинской информационной системы Interin PROMIS ALPHA на реализованном в данной работе клиенском приложениии.

Рисунок 5.2 - Вид типовой МИС

 

ЗАКЛЮЧЕНИЕ


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

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

Полученный программный продукт полностью удовлетворяет всем исходным требования и используется в качестве клиента медицинской информационной системы «Interin PROMIS ALPHA» в двух медицинских организацияхж

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

ПРИЛОЖЕНИЕ


(Обязательное)

Исходный код функции main ядра системы

#include "../src/InterinClntApp/interinclntapp.h"main(int argc, char **argv)

{InterinClntApp *app=Q_NULLPTR;

QString execAfterExit="";

char initRez;

bool done=false;

app=new InterinClntApp(argc, argv);

while(!done){

initRez=app->init();

if(!initRez){

execAfterExit=" Не удалось выполнить инициализацию параметров приложения.\n"

" Работа будет завершена. Обратитесь в техподдержку!";

if(app->getAppLog())

app->getAppLog()->toLog(0)<<execAfterExit<<endl;

QMessageBox::critical(0, QString(" Клиент МИС \"Интерин\" версия ")+

app->applicationVersion(), execAfterExit,

QMessageBox::Ok);

delete app;

return 1;

}

if(initRez==0x01){

if(app->loadMainModule()){

app->exec();

execAfterExit=app->getUpdateCommand();

if(!execAfterExit.isEmpty()){

app->getAppLog()->toLog(9)<<" Перезапускаемся для проверки обновлений.\n "<<execAfterExit<<endl;

initRez=0x02;

}

done=true;

}

else{

execAfterExit=" Не удалось загрузить основной модуль программы.\n"

" Нажмите Ок для загрузки основного модуля с сервера обновлений.\n"

" Нажмите Cancel для завершения работы и обратитесь в техподдержку!.";

if(app->getAppLog())

app->getAppLog()->toLog(0)<<execAfterExit<<endl;

if(QMessageBox::critical(0, QString(" Клиент МИС \"Интерин\" версия ")+

app->applicationVersion(), execAfterExit,

QMessageBox::Ok|QMessageBox::Cancel)!=QMessageBox::Ok)

done=true;

}

}

else{ execAfterExit=app->getUpdateCommand();

app->getAppLog()->toLog(9)<<" Обновились. После завершения выполняем команду\n "<<execAfterExit<<endl;

done=true;

}

}app->saveParams();

delete app;

if(!execAfterExit.isEmpty() && initRez==0x02)

QProcess(0).startDetached(execAfterExit);

return 0;

}

Исходный код менеджера модулей

#include "gsmodule.h"

GSModule::GSModule(const QString &moduleName, const QString &modulesSection,

QObject *parent):

QObject(parent)

{

setObjectName(moduleName);

m_DllInit=Q_NULLPTR;

m_DllStart=Q_NULLPTR;

m_DllStop=Q_NULLPTR;

m_DllAbout=Q_NULLPTR;

m_HandlersArray=Q_NULLPTR;

m_WidgetsArray=Q_NULLPTR;

m_Log=Q_NULLPTR;

m_ModuleParamsSection=modulesSection+"/"+objectName()+"/";

// load();

}::~GSModule()

{

unload();

m_Log=Q_NULLPTR;

}GSModule::init(void *abstractInterface)

{TGetEventsHandlers getHandlers=Q_NULLPTR;

TGetWidgetsList getWidgets=Q_NULLPTR;

QSettings objectParams;

objectParams.setValue(m_ModuleParamsSection+"version", about(ABOUT_VER));

if(!m_DllInit)

return 0x00;

if(!m_DllInit(abstractInterface, &m_ModuleParamsSection))

return 0x00;

getHandlers=(TGetEventsHandlers) m_Library.resolve("getEventsHandlers");

if(getHandlers)

m_HandlersArray=(THandlersArray *)getHandlers();

getWidgets=(TGetWidgetsList) m_Library.resolve("getWidgetsList");

if(getWidgets)

m_WidgetsArray=(TWidgetsArray *)getWidgets();

return 0x01;

}GSModule::start()

{QSettings objectParams;

if(!m_DllStart)

return 0x00;

// objectParams.setValue(m_ModuleParamsSection+"version", about(ABOUT_VER));

return m_DllStart();

}GSModule::stop()

{

m_HandlersArray=Q_NULLPTR;

m_WidgetsArray=Q_NULLPTR;

if(!m_DllStop)

return 0x00;

return m_DllStop();

}GSModule::about(char content)

{QString mess;

if(!m_DllAbout)

return "";

m_DllAbout(content, &mess);

return mess;

}GSModule::isLoaded()

{

return m_Library.isLoaded();

}GSModule::load()

{QSettings objectParams;

if(m_Library.isLoaded())

unload();_Library.setFileName(objectParams.value(m_ModuleParamsSection+"module_path","").toString()+.value(m_ModuleParamsSection+"module_file","").toString());

gsInfo(m_Log,9)<<" Загружаем файл\n "<<m_Library.fileName()<<"\n из секции\n "<<m_ModuleParamsSection<<endl;

if(!m_Library.load()){

objectParams.setValue(m_ModuleParamsSection+"version","");

return false;

}

m_DllInit= (TModuleInit) m_Library.resolve("init");

m_DllStart= (TModuleStart) m_Library.resolve("start");

m_DllStop= (TModuleStop) m_Library.resolve("stop");

m_DllAbout= (TModuleAbout) m_Library.resolve("about");

return true;

}GSModule::unload()

{

if(!m_Library.isLoaded()){

stop();

m_DllInit=Q_NULLPTR;

m_DllStart=Q_NULLPTR;

m_DllStop=Q_NULLPTR;

m_DllAbout=Q_NULLPTR;

return m_Library.unload();

}

return true;

}GSModule::onEvent(const QString &event, char param)

{TEventHandler eventHandler;

if(m_HandlersArray){

eventHandler=m_HandlersArray->value(event,Q_NULLPTR);

if(eventHandler){

eventHandler(param);

return 0x01;

}

}

return 0x00;

}*GSModule::getWidget(const QString &widgetId)

{

if(m_WidgetsArray)

return m_WidgetsArray->value(widgetId,Q_NULLPTR);

return Q_NULLPTR;

}GSModule::setLog(GSLog *log)

{

m_Log=log;

}::GSModulesManager(const QString &objectName, QObject *parent)

: QObject(parent)

{

m_ModulesSection=objectName;

setObjectName(objectName);

m_Log=Q_NULLPTR;

m_newExeName="";

m_instReceivedName="";

}::~GSModulesManager()

{

unloadAllModules();

m_Log=Q_NULLPTR;

}* GSModulesManager::loadModule(const QString &moduleName)

{GSModule* module=Q_NULLPTR;

if(moduleName.isEmpty())

return loadModule(m_MainModuleName);

gsInfo(m_Log,9)<<" Загружаем модуль "<<moduleName<<endl;

for(int i=0; i<m_lModules.size(); i++){

module=m_lModules.at(i);

if(module->objectName() == moduleName){

if(module->isLoaded())

return module;

else{

module->load();

break;

}

}

module=Q_NULLPTR;

}

if(!module){

module=new GSModule(moduleName, m_ModulesSection, this);

module->setLog(m_Log);

module->load();

m_lModules.append(module);

}

return module;

}GSModulesManager::loadAllModules(void *abstractInterface, bool doInit)

{QSettings params;

GSModule* module=Q_NULLPTR;

QStringList modules;

params.beginGroup(m_ModulesSection);

modules=params.childGroups();

int index=modules.indexOf(m_MainModuleName);

if(index>0){

modules[index]=modules[0];

modules[0]=m_MainModuleName;

}

gsInfo(m_Log, 9)<<" Загружаем все модули."<<endl;

for(int i=0; i<modules.size(); ++i){

module=loadModule(modules.at(i));

if(!module->isLoaded()){

gsInfo(m_Log, 9)<<" Модуль "<<modules.at(i)<<" не загружен. Необходимо получить обновление."<<endl;

continue;

}

if(doInit)

if(!module->init((void *)this))

gsInfo(m_Log,0)<<" Не удалось проинициализировать модуль: "<<module->objectName()<<endl;

}

}GSModulesManager::unloadModule(GSModule *module)

{

for(int i = 0; i<m_lModules.size(); ++i){

if(module == m_lModules.at(i)){

module=m_lModules.takeAt(i);

delete module;

return;

}

}

}GSModulesManager::unloadAllModules()

{GSModule *module;

bool ok=false;

gsInfo(m_Log, 9)<<" Выгружаем все модули. Общее число загруженных модулей "<<m_lModules.size()<<"."<<endl;

while(!m_lModules.isEmpty())

delete m_lModules.takeFirst();

}GSModulesManager::setLog(GSLog *log)

Источник: https://www.bibliofond.ru/view.aspx?id=897371