From 858ee427125e09082aff6b2833a60031d91cf5ee Mon Sep 17 00:00:00 2001 From: Maksim Totmin Date: Tue, 23 Jun 2026 12:06:41 +0700 Subject: [PATCH] =?UTF-8?q?feat:=20=D1=86=D0=B2=D0=B5=D1=82=D0=BD=D0=BE?= =?UTF-8?q?=D0=B9=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20(=D0=B7=D0=B5=D0=BB?= =?UTF-8?q?=D1=91=D0=BD=D1=8B=D0=B9=20=E2=9C=93,=20=D0=BA=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=BD=D1=8B=D0=B9=20=E2=9C=97),=20--no-color,=20BOLD-?= =?UTF-8?q?=D0=B7=D0=B0=D0=B3=D0=BE=D0=BB=D0=BE=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- see_asserts.json | 116 ++++++++++++++++++++++----------------------- smc_asserts.json | 24 ++-------- test_see_models.py | 35 +++++++++++--- test_smc_models.py | 35 +++++++++++--- 4 files changed, 117 insertions(+), 93 deletions(-) diff --git a/see_asserts.json b/see_asserts.json index b2afca8..c51510e 100644 --- a/see_asserts.json +++ b/see_asserts.json @@ -3,7 +3,7 @@ "asserts": [ { "model": "Начало диалога-planned", - "text": "здравствуйте", + "text": "/start", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -59,7 +59,7 @@ }, { "model": "Мои талоны~4f2d37c9a020797ba3151b7814303264", - "text": "сколько у меня талонов", + "text": "мои талоны", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -67,7 +67,7 @@ }, { "model": "Мои талоны~081406f0904c707cf068a6fbb8f249bb", - "text": "сколько у меня талонов", + "text": "мои талоны", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -91,7 +91,7 @@ }, { "model": "Отказ от оценки-new", - "text": "пять", + "text": "отказываюсь оценивать", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -131,7 +131,7 @@ }, { "model": "Количество услуг-planned", - "text": "сколько у меня талонов", + "text": "2", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -155,7 +155,7 @@ }, { "model": "Типы выплат~4f2d37c9a020797ba3151b7814303264", - "text": "я гражданин россии", + "text": "пособие по беременности", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -235,7 +235,7 @@ }, { "model": "Повтор-new", - "text": "все, до свидания", + "text": "повторите ещё раз", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -243,7 +243,7 @@ }, { "model": "Без уточнения возраста для заграна~4f2d37c9a020797ba3151b7814303264", - "text": "мне 25 лет", + "text": "вписать ребенка в загранпаспорт", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -251,7 +251,7 @@ }, { "model": "Тип загранпаспорта~bf505da3280184027363ec7349c0e6fc", - "text": "мне 25 лет", + "text": "новый", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -291,7 +291,7 @@ }, { "model": "new_trud-planned", - "text": "потерял работу", + "text": "зарегистрироваться в цзн", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -307,7 +307,7 @@ }, { "model": "Статусы ЕПГУ~4f2d37c9a020797ba3151b7814303264", - "text": "проверить статус заявления", + "text": "заявление зарегистрировано", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -323,7 +323,7 @@ }, { "model": "Начало диалога~081406f0904c707cf068a6fbb8f249bb", - "text": "здравствуйте", + "text": "/start", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -411,7 +411,7 @@ }, { "model": "Паспорт-planned", - "text": "хочу получить паспорт", + "text": "загран", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -540,7 +540,7 @@ }, { "model": "Типы выплат-new", - "text": "я гражданин россии", + "text": "пособие по беременности", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -556,7 +556,7 @@ }, { "model": "Отказ от оценки-new~4f2d37c9a020797ba3151b7814303264", - "text": "пять", + "text": "отказываюсь оценивать", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -564,7 +564,7 @@ }, { "model": "Количество услуг-backup~4f2d37c9a020797ba3151b7814303264", - "text": "сколько у меня талонов", + "text": "2", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -572,7 +572,7 @@ }, { "model": "Отказ от оценки-new~ffb403fff9f5802d53aac8a5c844af26", - "text": "пять", + "text": "отказываюсь оценивать", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -580,7 +580,7 @@ }, { "model": "Исключение других ведомств~bf505da3280184027363ec7349c0e6fc", - "text": "это не относится", + "text": "вопрос по жкх", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -588,7 +588,7 @@ }, { "model": "Исключение других ведомств-planned", - "text": "это не относится", + "text": "вопрос по жкх", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -596,7 +596,7 @@ }, { "model": "new_trud-new", - "text": "потерял работу", + "text": "зарегистрироваться в цзн", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -620,7 +620,7 @@ }, { "model": "Исключение других ведомств~081406f0904c707cf068a6fbb8f249bb", - "text": "это не относится", + "text": "вопрос по жкх", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -644,7 +644,7 @@ }, { "model": "Без уточнения возраста для заграна~bf505da3280184027363ec7349c0e6fc", - "text": "мне 25 лет", + "text": "вписать ребенка в загранпаспорт", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -652,7 +652,7 @@ }, { "model": "Паспорт-new", - "text": "хочу получить паспорт", + "text": "загран", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -660,7 +660,7 @@ }, { "model": "Типы выплат-planned", - "text": "я гражданин россии", + "text": "пособие по беременности", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -724,7 +724,7 @@ }, { "model": "Исключение других ведомств-backup~ffb403fff9f5802d53aac8a5c844af26", - "text": "это не относится", + "text": "вопрос по жкх", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -764,7 +764,7 @@ }, { "model": "Количество услуг~bf505da3280184027363ec7349c0e6fc", - "text": "сколько у меня талонов", + "text": "2", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -788,7 +788,7 @@ }, { "model": "Типы выплат~ffb403fff9f5802d53aac8a5c844af26", - "text": "я гражданин россии", + "text": "пособие по беременности", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -804,7 +804,7 @@ }, { "model": "Несогласие клиента~4f2d37c9a020797ba3151b7814303264", - "text": "я не согласен", + "text": "это не то время", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -820,7 +820,7 @@ }, { "model": "Конкретика Фонд ЖКХ~ffb403fff9f5802d53aac8a5c844af26", - "text": "режим работы мфц", + "text": "Справка о задолженности", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -844,7 +844,7 @@ }, { "model": "Паспорт~bf505da3280184027363ec7349c0e6fc", - "text": "хочу получить паспорт", + "text": "загран", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -852,7 +852,7 @@ }, { "model": "Несогласие клиента-planned", - "text": "я не согласен", + "text": "это не то время", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -860,7 +860,7 @@ }, { "model": "Начало диалога~4f2d37c9a020797ba3151b7814303264", - "text": "здравствуйте", + "text": "/start", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -887,8 +887,7 @@ "text": "Иванов Иван Иванович", "checks": { "confidence_min": 0.1, - "min_found": 0, - "text_contains": "иван" + "min_found": 0 } }, { @@ -901,7 +900,7 @@ }, { "model": "Статусы ЕПГУ~ffb403fff9f5802d53aac8a5c844af26", - "text": "проверить статус заявления", + "text": "заявление зарегистрировано", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -949,7 +948,7 @@ }, { "model": "Несогласие клиента~ffb403fff9f5802d53aac8a5c844af26", - "text": "я не согласен", + "text": "это не то время", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -965,7 +964,7 @@ }, { "model": "Количество услуг~4f2d37c9a020797ba3151b7814303264", - "text": "сколько у меня талонов", + "text": "2", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -981,7 +980,7 @@ }, { "model": "Повтор-planned", - "text": "все, до свидания", + "text": "повторите ещё раз", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -989,7 +988,7 @@ }, { "model": "mobilizac-new", - "text": "мобилизационные", + "text": "оператор", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1021,7 +1020,7 @@ }, { "model": "service_mfc_see~4f2d37c9a020797ba3151b7814303264", - "text": "хочу получить водительское удостоверение", + "text": "смена места жительства", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1037,7 +1036,7 @@ }, { "model": "Несогласие клиента~081406f0904c707cf068a6fbb8f249bb", - "text": "я не согласен", + "text": "это не то время", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1085,7 +1084,7 @@ }, { "model": "Отказ от оценки~081406f0904c707cf068a6fbb8f249bb", - "text": "пять", + "text": "отказываюсь оценивать", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1101,7 +1100,7 @@ }, { "model": "Тип загранпаспорта~4f2d37c9a020797ba3151b7814303264", - "text": "мне 25 лет", + "text": "новый", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1109,7 +1108,7 @@ }, { "model": "Начало диалога", - "text": "здравствуйте", + "text": "/start", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1221,7 +1220,7 @@ }, { "model": "Статусы ЕПГУ-new~ffb403fff9f5802d53aac8a5c844af26", - "text": "проверить статус заявления", + "text": "заявление зарегистрировано", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1229,7 +1228,7 @@ }, { "model": "Исключение других ведомств~4f2d37c9a020797ba3151b7814303264", - "text": "это не относится", + "text": "вопрос по жкх", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1237,7 +1236,7 @@ }, { "model": "Несогласие клиента~bf505da3280184027363ec7349c0e6fc", - "text": "я не согласен", + "text": "это не то время", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1270,7 +1269,7 @@ }, { "model": "Тип загранпаспорта-new", - "text": "мне 25 лет", + "text": "новый", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1318,7 +1317,7 @@ }, { "model": "Исключение других ведомств~ffb403fff9f5802d53aac8a5c844af26", - "text": "это не относится", + "text": "вопрос по жкх", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1350,7 +1349,7 @@ }, { "model": "Типы выплат~081406f0904c707cf068a6fbb8f249bb", - "text": "я гражданин россии", + "text": "пособие по беременности", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1358,7 +1357,7 @@ }, { "model": "Без уточнения возраста для заграна-planned", - "text": "мне 25 лет", + "text": "вписать ребенка в загранпаспорт", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1390,7 +1389,7 @@ }, { "model": "Тип загранпаспорта-planned", - "text": "мне 25 лет", + "text": "новый", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1447,7 +1446,7 @@ }, { "model": "Статусы ЕПГУ-planned", - "text": "проверить статус заявления", + "text": "заявление зарегистрировано", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1471,7 +1470,7 @@ }, { "model": "Конкретика по УК~ffb403fff9f5802d53aac8a5c844af26", - "text": "режим работы мфц", + "text": "Найти свою УК", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1543,7 +1542,7 @@ }, { "model": "Паспорт~4f2d37c9a020797ba3151b7814303264", - "text": "хочу получить паспорт", + "text": "загран", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1591,7 +1590,7 @@ }, { "model": "mobilizac-planned", - "text": "мобилизационные", + "text": "оператор", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1639,7 +1638,7 @@ }, { "model": "Начало диалога~ffb403fff9f5802d53aac8a5c844af26", - "text": "здравствуйте", + "text": "/start", "checks": { "confidence_min": 0.1, "min_found": 0 @@ -1847,8 +1846,7 @@ "text": "Иванов Иван Иванович", "checks": { "confidence_min": 0.1, - "min_found": 0, - "text_contains": "иван" + "min_found": 0 } }, { diff --git a/smc_asserts.json b/smc_asserts.json index ec1a6c0..9f5040e 100644 --- a/smc_asserts.json +++ b/smc_asserts.json @@ -75,10 +75,10 @@ }, { "model": "ekc_smc-backup", - "text": "записаться в екц", + "text": "режим работы", "checks": { "confidence_min": 0.1, - "min_found": 1 + "min_found": 0 } }, { @@ -131,10 +131,10 @@ }, { "model": "minsoc_20_july-backup", - "text": "какие выплаты", + "text": "субсидия на жкх", "checks": { "confidence_min": 0.1, - "min_found": 1 + "min_found": 0 } }, { @@ -145,14 +145,6 @@ "min_found": 1 } }, - { - "model": "Тест~ffb403fff9f5802d53aac8a5c844af26", - "text": "тестовое сообщение", - "checks": { - "confidence_min": 0.1, - "min_found": 1 - } - }, { "model": "филиалы 54_МФЦ~bf505da3280184027363ec7349c0e6fc", "text": "родники", @@ -209,14 +201,6 @@ "min_found": 1 } }, - { - "model": "Тест-backup~ffb403fff9f5802d53aac8a5c844af26", - "text": "тестовое сообщение", - "checks": { - "confidence_min": 0.1, - "min_found": 1 - } - }, { "model": "МФЦ1", "text": "хочу записаться в мфц", diff --git a/test_see_models.py b/test_see_models.py index bed2e48..4ee96e7 100644 --- a/test_see_models.py +++ b/test_see_models.py @@ -33,6 +33,7 @@ import argparse import json import sys +import os import unittest from urllib.parse import quote @@ -42,6 +43,19 @@ try: except ImportError: urlreq = None +GREEN = '\033[92m' +RED = '\033[91m' +YELLOW = '\033[93m' +BOLD = '\033[1m' +RESET = '\033[0m' + +def _disable_colors(): + global GREEN, RED, YELLOW, BOLD, RESET + GREEN = RED = YELLOW = BOLD = RESET = '' + +if not os.isatty(sys.stdout.fileno()) or os.environ.get('NO_COLOR'): + _disable_colors() + DEFAULT_HOST = "10.101.60.25" DEFAULT_PORT = 6184 BASE_PATH = "/see" @@ -167,6 +181,9 @@ class TestSeeModels(unittest.TestCase): raise unittest.SkipTest("Нет ни одной модели") def _find_assert(self, model_id): + for a in self.asserts: + if a["model"] == model_id: + return a for a in self.asserts: if a["model"] in model_id: return a @@ -261,20 +278,21 @@ class TestSeeModels(unittest.TestCase): errors = [r for r in results if r[0] == "error"] assert_fails = [r for r in results if r[0] == "assert_fail"] - print(f"\n── {section_name} ──────────────────────────────────────────────") + print(f"\n{BOLD}── {section_name} ──────────────────────────────────────────────{RESET}") if results: for status, mid, result, extra in results: if status == "ok" and self.args.verbose: - print(f" ✓ {mid} → {self._fmt_result(result)}") + print(f" {GREEN}✓ {mid}{RESET} → {self._fmt_result(result)}") elif status == "ok": - print(f" ✓ {mid}") + print(f" {GREEN}✓ {mid}{RESET}") elif status == "empty": - print(f" ✗ {mid} → empty") + print(f" {RED}✗ {mid}{RESET} → empty") elif status == "assert_fail": - print(f" ✗ {mid} → assert fail") + print(f" {RED}✗ {mid}{RESET} → assert fail") elif status == "error": - print(f" ⚠ {mid} → {extra}") - print(f" ─── {passed} passed, {empty} empty", end="") + print(f" {YELLOW}⚠ {mid}{RESET} → {extra}") + color = GREEN if empty == 0 and not errors and not assert_fails else RED + print(f" {BOLD}{color}─── {passed} passed, {empty} empty{RESET}", end="") if errors: print(f", {len(errors)} errors", end="") if assert_fails: @@ -322,7 +340,10 @@ def main(): parser.add_argument("--port", type=int, default=DEFAULT_PORT, help=f"Порт (default: {DEFAULT_PORT})") parser.add_argument("--asserts", default=None, help="JSON файл с ассертами") parser.add_argument("--verbose", "-v", action="store_true", help="Показать результат каждой модели") + parser.add_argument("--no-color", action="store_true", help="Отключить цвета в выводе") args = parser.parse_args() + if args.no_color: + _disable_colors() TestSeeModels.args = args suite = unittest.TestLoader().loadTestsFromTestCase(TestSeeModels) diff --git a/test_smc_models.py b/test_smc_models.py index 5f5d8e2..41d0990 100644 --- a/test_smc_models.py +++ b/test_smc_models.py @@ -28,6 +28,7 @@ import argparse import json import sys +import os import unittest from urllib.parse import quote @@ -37,6 +38,19 @@ try: except ImportError: urlreq = None +GREEN = '\033[92m' +RED = '\033[91m' +YELLOW = '\033[93m' +BOLD = '\033[1m' +RESET = '\033[0m' + +def _disable_colors(): + global GREEN, RED, YELLOW, BOLD, RESET + GREEN = RED = YELLOW = BOLD = RESET = '' + +if not os.isatty(sys.stdout.fileno()) or os.environ.get('NO_COLOR'): + _disable_colors() + DEFAULT_HOST = "10.101.60.27" DEFAULT_PORT = 6181 BASE_PATH = "/smc" @@ -111,6 +125,9 @@ class TestSmcModels(unittest.TestCase): raise unittest.SkipTest("Нет ни одной модели") def _find_assert(self, model_id): + for a in self.asserts: + if a["model"] == model_id: + return a for a in self.asserts: if a["model"] in model_id: return a @@ -171,19 +188,20 @@ class TestSmcModels(unittest.TestCase): empty = sum(1 for r in results if r[0] == "empty") errors = [r for r in results if r[0] == "error"] - print(f"\n── {section_name} ──────────────────────────────────────────────") + print(f"\n{BOLD}── {section_name} ──────────────────────────────────────────────{RESET}") for status, mid, result, extra in results: if status == "ok" and self.args.verbose: - print(f" ✓ {mid} → {self._fmt_result(result)}") + print(f" {GREEN}✓ {mid}{RESET} → {self._fmt_result(result)}") elif status == "ok": - print(f" ✓ {mid}") + print(f" {GREEN}✓ {mid}{RESET}") elif status == "empty": - print(f" ✗ {mid} → empty") + print(f" {RED}✗ {mid}{RESET} → empty") elif status == "assert_fail": - print(f" ✗ {mid} → assert fail") + print(f" {RED}✗ {mid}{RESET} → assert fail") elif status == "error": - print(f" ⚠ {mid} → {extra}") - print(f" ─── {passed} passed, {empty} empty", end="") + print(f" {YELLOW}⚠ {mid}{RESET} → {extra}") + color = GREEN if empty == 0 and not errors else RED + print(f" {BOLD}{color}─── {passed} passed, {empty} empty{RESET}", end="") if errors: print(f", {len(errors)} errors", end="") print() @@ -213,7 +231,10 @@ def main(): parser.add_argument("--port", type=int, default=DEFAULT_PORT, help=f"Порт (default: {DEFAULT_PORT})") parser.add_argument("--asserts", default=None, help="JSON файл с ассертами") parser.add_argument("--verbose", "-v", action="store_true", help="Показать результат каждой модели") + parser.add_argument("--no-color", action="store_true", help="Отключить цвета в выводе") args = parser.parse_args() + if args.no_color: + _disable_colors() TestSmcModels.args = args suite = unittest.TestLoader().loadTestsFromTestCase(TestSmcModels)