From 6fe4fd0676d71d88f8a8c726f046b4aa5438de70 Mon Sep 17 00:00:00 2001 From: Mathieu Benoit Date: Sun, 8 Mar 2026 15:53:51 -0400 Subject: [PATCH] [IMP] script TODO support running test --- script/todo/todo.py | 119 ++++++++++++++++++++++++++++++++++++++- script/todo/todo_i18n.py | 69 +++++++++++++++++++++++ 2 files changed, 187 insertions(+), 1 deletion(-) diff --git a/script/todo/todo.py b/script/todo/todo.py index e04c86f..325171b 100755 --- a/script/todo/todo.py +++ b/script/todo/todo.py @@ -240,7 +240,8 @@ class TODO: [8] {t("menu_config")} [9] {t("menu_network")} [10] {t("menu_security")} -[11] {t("menu_lang")} +[11] {t("menu_test")} +[12] {t("menu_lang")} [0] {t("back")} """ while True: @@ -289,6 +290,10 @@ class TODO: if status is not False: return elif status == "11": + status = self.prompt_execute_test() + if status is not False: + return + elif status == "12": status = self._change_language() if status is not False: return @@ -859,6 +864,118 @@ class TODO: else: print(t("cmd_not_found")) + def prompt_execute_test(self): + print(f"🤖 {t('test_description')}") + lst_choice = [ + {"prompt_description": t("test_run_module")}, + {"prompt_description": t("test_run_module_coverage")}, + ] + help_info = self.fill_help_info(lst_choice) + + while True: + status = click.prompt(help_info) + print() + if status == "0": + return False + elif status == "1": + self.execute_test_module(coverage=False) + elif status == "2": + self.execute_test_module(coverage=True) + else: + print(t("cmd_not_found")) + + def execute_test_module(self, coverage=False): + # Module name + module_name = input(t("test_enter_module_name")).strip() + if not module_name: + print(t("test_module_required")) + return + + # Database name + db_name = input(t("test_db_name")).strip() + if not db_name: + db_name = "test_todo_tmp" + + # Extra modules + extra_modules = input( + t("test_install_extra_modules") + ).strip() + + # Log level + log_level = input(t("test_log_level")).strip() + if not log_level: + log_level = "test" + + # Build module list + modules_to_install = module_name + if extra_modules: + modules_to_install += f",{extra_modules}" + + # Step 1: Create temp DB + print(f"\n--- {t('test_creating_db')} '{db_name}' ---") + cmd_restore = ( + f"./script/database/db_restore.py --database {db_name}" + ) + self.execute.exec_command_live( + cmd_restore, + source_erplibre=False, + single_source_erplibre=True, + ) + + # Step 2: Install modules + print(f"\n--- {t('test_installing_modules')}: {modules_to_install} ---") + cmd_install = ( + f"./script/addons/install_addons.sh" + f" {db_name} {modules_to_install}" + ) + self.execute.exec_command_live( + cmd_install, + source_erplibre=False, + single_source_erplibre=True, + ) + + # Step 3: Run tests + print(f"\n--- {t('test_running')}: {module_name} ---") + cmd_test = ( + f"ODOO_MODE_TEST=true" + f" ./run.sh" + f" -d {db_name}" + f" -u {module_name}" + f" --log-level={log_level}" + ) + if coverage: + cmd_test = f"ODOO_MODE_COVERAGE=true {cmd_test}" + status_code, output = self.execute.exec_command_live( + cmd_test, + return_status_and_output=True, + source_erplibre=False, + single_source_erplibre=True, + ) + + if status_code == 0: + print(f"\n✅ {t('test_success')}") + else: + print(f"\n❌ {t('test_failed')} {status_code}") + + # Step 4: Cleanup + lang = get_lang() + keep_input = input(t("test_keep_db")).strip().lower() + keep = keep_input in ( + ("o", "oui") if lang == "fr" else ("y", "yes") + ) + if keep: + print(f"{t('test_db_kept')}: {db_name}") + else: + print(f"\n--- {t('test_cleaning_db')} '{db_name}' ---") + cmd_drop = ( + f"./odoo_bin.sh db --drop --database {db_name}" + ) + self.execute.exec_command_live( + cmd_drop, + source_erplibre=False, + single_source_erplibre=True, + ) + def execute_pip_audit(self): lst_version, lst_version_installed, odoo_installed_version = ( self.get_odoo_version() diff --git a/script/todo/todo_i18n.py b/script/todo/todo_i18n.py index 8a84067..476fa69 100644 --- a/script/todo/todo_i18n.py +++ b/script/todo/todo_i18n.py @@ -343,6 +343,75 @@ TRANSLATIONS = { "fr": "Débogage todo.py", "en": "Debug todo.py", }, + # Test section + "menu_test": { + "fr": "Test - Tester un module Odoo", + "en": "Test - Test an Odoo module", + }, + "test_description": { + "fr": "Tester un module Odoo sur une base de données temporaire!", + "en": "Test an Odoo module on a temporary database!", + }, + "test_run_module": { + "fr": "Tester un module", + "en": "Test a module", + }, + "test_run_module_coverage": { + "fr": "Tester un module avec couverture de code", + "en": "Test a module with code coverage", + }, + "test_enter_module_name": { + "fr": "Nom du module à tester : ", + "en": "Module name to test: ", + }, + "test_db_name": { + "fr": "Nom de la base de données temporaire (défaut: test_todo_tmp) : ", + "en": "Temporary database name (default: test_todo_tmp): ", + }, + "test_install_extra_modules": { + "fr": "Modules supplémentaires à installer (séparés par des virgules, vide pour aucun) : ", + "en": "Extra modules to install (comma-separated, empty for none): ", + }, + "test_log_level": { + "fr": "Niveau de log (défaut: test) : ", + "en": "Log level (default: test): ", + }, + "test_creating_db": { + "fr": "Création de la base de données temporaire", + "en": "Creating temporary database", + }, + "test_installing_modules": { + "fr": "Installation des modules", + "en": "Installing modules", + }, + "test_running": { + "fr": "Exécution des tests", + "en": "Running tests", + }, + "test_cleaning_db": { + "fr": "Suppression de la base de données temporaire", + "en": "Cleaning up temporary database", + }, + "test_keep_db": { + "fr": "Conserver la base de données temporaire? (o/N) : ", + "en": "Keep the temporary database? (y/N): ", + }, + "test_db_kept": { + "fr": "Base de données conservée", + "en": "Database kept", + }, + "test_success": { + "fr": "Tests terminés avec succès!", + "en": "Tests completed successfully!", + }, + "test_failed": { + "fr": "Les tests ont échoué avec le code de retour", + "en": "Tests failed with return code", + }, + "test_module_required": { + "fr": "Le nom du module est requis!", + "en": "Module name is required!", + }, # Language selection "lang_prompt": { "fr": "Choisir la langue / Choose language",