Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПКС / ПКС. Лабораторная 5

.docx
Скачиваний:
3
Добавлен:
19.09.2023
Размер:
952.77 Кб
Скачать

МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ,

СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА» (СПбГУТ)

Кафедра информационных управляющих систем

Лабораторная работа № 05

по Б1.О.12 «ПРОГРАММИРОВАНИЕ КРИТИЧЕСКИХ СЕРВИСОВ»

Студент гр. ИСТ-111_____________________________ П.П. Иванов

(подпись)

Проверил ___________________________ А. В. Параничев

(оценка и подпись)

Санкт-Петербург

2023 год

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

[желтым - для подстановки своих значений; зеленым - прочитать комментарии и удалить перед отправкой; все выделение убрать перед отправкой; файл переименовать по шаблону]

[1. Зарегистрироваться на ресурсе "облачной" загрузки и управления БД MySQL (можно использовать другую реляционную СУБД в онлайн-режиме с бесплатным доступом): 1.1) нажать  https://www.freemysqlhosting.net/ , нажать "Start Free Account", введя свою почту; 1.2) нажать "MySQLHosting" и выбрать "Europe (MainLand)", нажать "SaveLocation"; 1.3) нажать CreateDatabase, получив имя сервера-логин-пароль: имя сервера вида: sql7.freemysqlhosting.net имя пользователя / имя базы данных вида: sql7609115 пароль: <отправляется на почту>. 1.4) нажать на ссылку "Follow this link for phpMyAdmin" (или https://www.phpmyadmin.co ) 1.5) перейти в раздел "SQL", скопировать в окно свой скрипт из 2й лабораторной работы, добавить в скрипт 1ю строку с именем базы данных вида: USE sql7609115 1.6) нажать "галочку" RetainQueryBox (сохранить окно запроса), отжать "галочку" EnableForeignKeyCheck (включить проверку внешних ключей); 1.7) нажать Go (вперед), убедиться, что скрипт выполнен (зеленые "галочки" на странице выполнения скрипта); 1.8) перейти Databases (Базы данных) -> выбрать свою базу данных вида sql7609115; -> перейти More -> Designer; получившуюся ER-диаграмму в нотации IDEF1X упорядочить, чтобы не было пересечений линий и добавить в отчет. 2. Зарегистрироваться на ресурсе "облачной" загрузки и управления БД MySQL (можно выбрать любой другой бесплатный ресурс; загрузка на 2й ресурс проводится на случай "падения" 1го ресурса): 2.1) нажать https://db4free.net/ , нажать Database -> Sign In: MySQL Database name: указать вида sql7609115 MySQL User name: указать вида sql7609115 Ввести свою почту 2.2) аналогично перейти к своей базе данных: по ссылке phpMyAdmin (или https://db4free.net/phpMyAdmin/ ) и заполнить ее. 2.3) также отобразить получившуюся ER-диаграмму в нотации IDEF1X упорядочить, чтобы не было пересечений линий и добавить в отчет. 3. Для проверки работы функций добавления строк составить 3 класса по 2 функции-теста в каждом (успешный и неуспешный); реализацию выполнить в виде файла testconsole _10.py (вместо 10 подставить название своего сервиса): также можно выполнить с другой СУБД и не обязательно на языке Python (в этом случае разбираемся самостоятельно с синтаксисом JavaScript, TypeScript и т.д.). 3.1) В таблицу подставить функции добавления строк в "свою" таблицу БД MySQL; составить функции чтения/добавления данных и дополнить эти функции значениями return. 3.2) Выполнить юнит-тестирование 6 функций чтения и добавления строк в удаленную базу данных.

Отчет оформить примерно как в шаблоне; можно по-своему, но не менее информативно

Файл отчета переименовать.]

Зарегистрирован аккаунт на сайте https://www.freemysqlhosting.net/ , создана на этому онлайн-ресурсе базу данных sql7609144 (рис. 1).

Рис. 1. Личный кабинет на сайте https://www.freemysqlhosting.net/

После регистрации аккаунта выполнено подключение к базе данных с помощью онлайн-ресурса https://www.phpmyadmin.co (рис. 2).

Рис. 2. Личный кабинет phpMyAdmin в онлайн-ресурсе онлайн-ресурса https://www.phpmyadmin.co

После регистрации на сайте https://www.freemysqlhosting.net/ произведена загрузка скрипта для создания и заполнения таблиц базы данных sql7609144 с помощью онлайн-ресурса https://www.phpmyadmin.co (рис. 3).

Рис. 3. Результат выполнения скрипта по индивидуальному заданию

После выполнения скрипта по индивидуальному заданию в базе данных созданы и заполнены данными таблицы: ER-диаграмма в нотации IDEF1X представлена на рис. 4.

Рис. 4. Представление базы данных sql7609144 в виде ER-диаграммы с помощью онлайн-ресурса https://www.phpmyadmin.co

Перечень таблиц базы данных представлена на рис. 5.

Рис. 5. Перечень таблиц базы данных sql7609144

После выполнения аналогичных действий на сайте https://db4free.net/ и выполнения скрипта MySQL в СУБД phpMyAdmin в онлайн-ресурсе https://db4free.net/phpMyAdmin/, также получена IDEF1X-диаграмма (рис. 6).

Рис. 6. Представление базы данных sql7609144 в виде ER-диаграммы в онлайн-ресурсе

Далее в среде PyCharm создан прототип функций по чтению/добавлению записей в таблицу … базы данных создаваемого сервиса с помощью консольного приложения в файле main.py; для функций чтения и добавления записей указаны коды возврата для их последующего тестирования:

import time

import json

import pymysql

from decimal import *

# для распознавания типа Decimal из формата JSON

def decimal_default(obj):

 if isinstance(obj, Decimal):

     return float(obj)

 raise TypeError("Ошибка сериализации JSON: '%s'" % type(obj).__name__)

class dbase_mysql:

 def __init__(self):

     db = self.mysql_connect('sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144')

     if db is not None:

         print("Проверка чтения")

         self.select_data("1002")

 def mysql_connect(self, Host, User, Password, Database):

     db = None

     try:

         db = pymysql.connect(

                 host=Host,

                 user=User,

                 password=Password,

                 database=Database)

         print("Подключение к БД успешно установлено!) (время: {})".format(time.localtime()))

     except Exception as e:

         print("Подключение к БД не установлено!( \n{}\n{}\n(время: {})".

               e.__repr__(), e.args, format(time.localtime()))

         return 1

     return db

 def insert_data(self, values, db):

     try:

         if db is not None:

             cur = db.cursor()

             sql = "INSERT INTO CPU(CPU_id, CPU_coreCount, CPU_rate, CPU_brand, CPU_name) VALUES(%s, %s, %s, %s, %s)".format(values)

             print("Запрос {} успешно подготовлен!)".format(sql))

         else:

             print("Не удалось подключиться к БД!(")

             return 1

     except:

         print("Запрос {} не удалось подготовить!(".format(sql))

         return 2

     try:

         # inserting the values into the table

         cur.execute(sql, values)

         # commit the transaction

         db.commit()

     except:

         db.rollback()

         return 3

     print(cur.rowcount, "record inserted!")

     db.close()

     return 0

 def select_data(self, index):

     db = self.mysql_connect()

     ret = None

     try:

         if db is not None:

             cur = db.cursor()

             sql = "SELECT * FROM SU_list WHERE SystemUnit_RAM = {}".format(index)

             print("Запрос {} успешно подготовлен!)".format(sql))

         else:

             print("Не удалось подключиться к БД!(")

             return ret

     except:

         print("Запрос {} не удалось подготовить!(".format(sql))

         return ret

     try:

         cur.execute(sql)

         print("Выполнено: cur.execute(sql)")

         rows = cur.fetchall()

         print("Выполнено: rows = cur.fetchall()")

         row_headers = [x[0] for x in cur.description]

         print("Выполнено: row_headers = [x[0] for x in cur.description]")

         json_data = []

         for row in rows:

             json_data.append(dict(zip(row_headers, row)))

             print("Выполнено: json_data.append(dict(zip(row_headers, row)))")

         print("json_data = \n{}".format(json_data))

         ret = json.dumps(json_data, skipkeys=False, ensure_ascii=False, check_circular=True,

                          allow_nan=True, cls=None, indent=None, separators=None,

                          default=decimal_default, sort_keys=False)

         print("Успешно получен результат на запрос:\n{}".format(ret))

     except Exception as e:

         print("Запрос {} не удалось выполнить на сервере!( Ошибка:\n{}\n{}".

               format(sql), e.__repr__(), e.args)

     finally:

         db.close()

     return ret

if __name__ == '__main__':

  activate = dbase_mysql()

  val = (10, 4, 2.9, 'AMD', 'Ryzen 5')

  db = activate.mysql_connect()

  count_request = activate.insert_data(val, db)

Для проверки работы прототипа функции по чтению и добавлению строк составлены 3 тестовых класса по 2 тестовых метода в каждом (успешный и неуспешный); реализация выполнена в виде файла testconsole_10.py: [составить 3 тестовых класса по 2 тестовых метода в каждом, дополнив вариант, представленный в примере]

import unittest

import main

class SuccesfullyTestCreate(unittest.TestCase):

  def test_create(self):

      test_create = main.dbase_mysql

      val = (12, 6, 2.9, 'AMD', 'Ryzen 5600')

      db = test_create.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144')

      self.assertEqual(0, test_create.insert_data(self, val, db))# add assertion here

  def test_connect(self):

      test_connect = main.dbase_mysql

      db = test_connect.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144')

      val = (13, 8, 3.3, 'AMD', 'Ryzen 7600')

      self.assertEqual(0, test_connect.insert_data(self, val, db))

class UnsuccesfullyTestCreate(unittest.TestCase):

  def test_create(self):

      test_create = main.dbase_mysql

      db = test_create.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144')

      val = (11, 8, 3.9, 'Intel', 'core I7')

      self.assertEqual(0, test_create.insert_data(self, val, db))

  def test_connect(self):

      test_connect = main.dbase_mysql

      db = test_connect.mysql_connect(self, 'sql7.freemysqlhosting.net', 'sql7609144','…', 'sql7609144')

      val = (13, 8, 3.1, 'AMD', 'Ryzen 7700')

      self.assertEqual(0, test_connect.insert_data(self, val, db))

if __name__ == '__main__':

  unittest.main()

Таблица 1

Результаты юнит-тестирования функций по добавлению записей в базу данных сервиса

Номер теста п/п

Тестовая функция и значения параметров

Ожидаемый результат

Фактический результат

Результат теста

1

val = (11, 8, 3.9, 'Intel', 'core I7')

assertEqual(0, test_create.insert_data(self, val, db))

0

0

OK

2

val = (11, 8, 3.9, 'Intel', 'core I7')

assertEqual(0, test_create.insert_data(self, val, db))

0

3

Failed

3

val = (12, 8, 3.3, 'AMD', 'Ryzen 7600')

self.assertEqual(0, test_connect.insert_data(self, val, db))

0

0

OK

4

val = (13, 8, 3.1, 'AMD', 'Ryzen 7700')

self.assertEqual(0, test_connect.insert_data(self, val, db))

0

1

Failed

5

6

В табл. 1 показаны следующие тесты:

  • № 1 и 3 выполнен успешно (ОК), т.к. ожидаемое значение и фактическое совпали. 

  • № 2 и 4 выполнен неуспешно (Failed), т.к. данный тесты не проходят проверку на правильность и в случае если бы здесь тесты выполнялись успешно, то при работе с реальной программе пользователь бы смог сломать базу данных указывая некорректные данные. Во 2ом тесте мы пытаемся добавить строчку с уже занятым первичным ключом, так как первичный ключ должен быть уникальным SQL выдаёт ошибку и передаёт в функцию, которая в свою очередь оповещает об этом. В 4ом мы пытаемся добавить строчку с неправильным паролем в базе данных, соответственно мы получаем ошибку и возвращается значение 1, 1 не равен 0 поэтому тест не выполнен.

Выводы: [5-7 строк]

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