erplibre/test/test_plan.base.md
Mathieu Benoit 111583c77d [ADD] test: add bilingual test plan with mmg
Document all 13 test files, 262 tests, and coverage
matrix in EN/FR using multilingual markdown generator.

Generated by Claude Code 2.1.74 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
2026-03-11 23:07:01 -04:00

25 KiB

Test Plan — ERPLibre ./test/

Overview

Plan de test — ERPLibre ./test/

Vue d'ensemble

Metric / Métrique Value / Valeur
Test files / Fichiers de test 13
Test classes / Classes de test 56
Test methods / Méthodes de test 262
Framework unittest (Python stdlib)
Command / Commande python3 -m unittest discover -s test -v

1. test_config_file.py — Configuration and file merging

Type: Unit test (pure logic, no real I/O)

Class # Tests What is validated
TestDeepMergeWithLists 11 Recursive dict merging with list strategies (replace vs extend), source dict immutability
TestGetConfig 6 Loading and merging configs from base + override + private JSON, correct precedence
TestGetConfigValue 2 Navigating nested values by key path
TestGetLogoAsciiFilePath 1 Returns the logo file path

Mocks: @patch on CONFIG_FILE paths, temporary JSON files

1. test_config_file.py — Configuration et fusion de fichiers

Type : Test unitaire (pure logique, aucun I/O réel)

Classe # Tests Ce qui est validé
TestDeepMergeWithLists 11 Fusion récursive de dicts avec stratégies de listes (replace vs extend), immutabilité du dict source
TestGetConfig 6 Chargement et fusion de configs depuis base + override + private JSON, précédence correcte
TestGetConfigValue 2 Navigation dans les valeurs imbriquées par chemin de clés
TestGetLogoAsciiFilePath 1 Retourne le chemin du fichier logo

Mocks : @patch sur les chemins CONFIG_FILE, fichiers temporaires JSON


2. test_execute.py — Shell command execution

Type: Integration test (executes real bash processes)

Class # Tests What is validated
TestExecuteInit 3 Terminal detection (gnome-terminal, osascript), venv configuration
TestExecCommandLive 15 Command execution with various return modes (status, output, command), venv activation, custom environment variables

Mocks: @patch("shutil.which") for terminal. Bash commands are actually executed.

2. test_execute.py — Exécution de commandes shell

Type : Test d'intégration (exécute de vrais processus bash)

Classe # Tests Ce qui est validé
TestExecuteInit 3 Détection du terminal (gnome-terminal, osascript), configuration du venv
TestExecCommandLive 15 Exécution de commandes avec différents modes de retour (status, output, commande), activation de venv, variables d'environnement custom

Mocks : @patch("shutil.which") pour le terminal. Les commandes bash sont exécutées réellement.


3. test_git_tool.py — Git utilities and manifest parsing

Type: Unit test

Class # Tests What is validated
TestRepoAttrs 3 Repo attributes data structure
TestGetUrl 3 URL format conversion HTTPS ↔ SSH
TestGetTransformedRepoInfo 10 Org, repo name, path extraction from URL, org forcing, revision, clone_depth
TestDefaultProperties 5 Default constants, Odoo version reading
TestStrInsert 3 Substring insertion at position
TestGetProjectConfig 1 Reading EL_GITHUB_TOKEN from env_var.sh
TestGetRepoInfoSubmodule 2 Parsing .gitmodules
TestGetManifestXmlInfo 2 Parsing Google Repo manifest XML
TestConstants 3 Verifying defined constants

Mocks: @patch("builtins.open"), temporary files for .gitmodules and XML

3. test_git_tool.py — Utilitaires Git et parsing de manifests

Type : Test unitaire

Classe # Tests Ce qui est validé
TestRepoAttrs 3 Structure de données des attributs de repo
TestGetUrl 3 Conversion d'URL HTTPS ↔ SSH
TestGetTransformedRepoInfo 10 Extraction d'org, nom de repo, chemin depuis URL, forçage d'org, revision, clone_depth
TestDefaultProperties 5 Constantes par défaut, lecture de la version Odoo
TestStrInsert 3 Insertion de sous-chaîne à une position
TestGetProjectConfig 1 Lecture de EL_GITHUB_TOKEN depuis env_var.sh
TestGetRepoInfoSubmodule 2 Parsing de .gitmodules
TestGetManifestXmlInfo 2 Parsing de manifests XML Google Repo
TestConstants 3 Vérification des constantes définies

Mocks : @patch("builtins.open"), fichiers temporaires pour .gitmodules et XML


4. test_kill_process_by_port.py — Process management

Type: Unit test (mocked processes, no real kill)

Class # Tests What is validated
TestProcDesc 3 Process description formatting (pid, cmdline, username)
TestGetAncestry 3 Parent process chain walking (stops at pid 1, ppid 0)
TestChooseTarget 3 Target process selection (detection of ./run.sh, ./odoo_bin.sh)
TestKillProcess 2 Process termination (gentle terminate vs force kill)
TestKillTree 3 Recursive process tree killing (children first)
TestFindListeners 5 Network socket enumeration by port (filtering, deduplication)
TestProtectedNames 2 System process protection (systemd, gnome-shell, sshd)
TestStopParentKill 2 Wrapper script detection

Mocks: _make_proc() creates mocked psutil.Process objects, @patch on psutil functions

4. test_kill_process_by_port.py — Gestion de processus

Type : Test unitaire (processus mockés, aucun kill réel)

Classe # Tests Ce qui est validé
TestProcDesc 3 Formatage de description de processus (pid, cmdline, username)
TestGetAncestry 3 Remontée de la chaîne de processus parents (arrêt à pid 1, ppid 0)
TestChooseTarget 3 Sélection du processus cible (détection de ./run.sh, ./odoo_bin.sh)
TestKillProcess 2 Terminaison de processus (gentle terminate vs force kill)
TestKillTree 3 Kill récursif de l'arbre de processus (enfants d'abord)
TestFindListeners 5 Énumération des sockets réseau par port (filtrage, dédoublonnage)
TestProtectedNames 2 Protection des processus système (systemd, gnome-shell, sshd)
TestStopParentKill 2 Détection des scripts wrapper

Mocks : _make_proc() crée des objets psutil.Process mockés, @patch sur les fonctions psutil


5. test_todo.py — Interactive CLI TODO

Type: Unit test

Class # Tests What is validated
TestTODOInit 1 TODO class initialization
TestFillHelpInfo 3 Help text generation, i18n key resolution
TestGetOdooVersion 3 Parsing version.json, active version detection
TestOnDirSelected 1 Directory selection
TestExecuteFromConfiguration 5 Executing commands/makefiles/callbacks from config dict
TestConstants 7 Path constants verification
TestDeployGitServer 2 Git daemon deployment logic
TestProcessKillGitDaemon 1 Git daemon process killing
TestExecuteUnitTests 2 Unit test execution
TestKdbxGetExtraCommandUser 3 KeePass integration
TestSetupClaudeCommit 1 Claude commit template setup
TestSelectDatabase 2 Database selection
TestRestoreFromDatabase 2 Database restoration
TestCreateBackupFromDatabase 1 Backup creation

Mocks: MagicMock() for Execute and database manager, temporary files

5. test_todo.py — CLI interactif TODO

Type : Test unitaire

Classe # Tests Ce qui est validé
TestTODOInit 1 Initialisation de la classe TODO
TestFillHelpInfo 3 Génération de texte d'aide, résolution des clés i18n
TestGetOdooVersion 3 Parsing de version.json, détection de la version active
TestOnDirSelected 1 Sélection de répertoire
TestExecuteFromConfiguration 5 Exécution de commandes/makefiles/callbacks depuis config dict
TestConstants 7 Vérification des chemins constants
TestDeployGitServer 2 Logique de déploiement du git daemon
TestProcessKillGitDaemon 1 Kill du processus git daemon
TestExecuteUnitTests 2 Exécution des tests unitaires
TestKdbxGetExtraCommandUser 3 Intégration KeePass
TestSetupClaudeCommit 1 Setup du template de commit Claude
TestSelectDatabase 2 Sélection de base de données
TestRestoreFromDatabase 2 Restauration de base de données
TestCreateBackupFromDatabase 1 Création de backup

Mocks : MagicMock() pour Execute et database manager, fichiers temporaires


6. test_todo_i18n.py — Internationalization (FR/EN)

Type: Unit test

Class # Tests What is validated
TestTranslations 3 TRANSLATIONS dictionary completeness (all keys have fr and en, no empty values)
TestT 4 t() function: returns correct language, falls back to key if unknown
TestGetLang 7 Language detection: memory cache, env_var.sh reading, environment variable, fallback to "fr"
TestSetLang 4 Language persistence in env_var.sh, missing file handling
TestLangIsConfigured 3 Configuration state detection

Mocks: @patch.object on ENV_VAR_FILE, @patch.dict(os.environ), setUp/tearDown to reset _current_lang

6. test_todo_i18n.py — Internationalisation (FR/EN)

Type : Test unitaire

Classe # Tests Ce qui est validé
TestTranslations 3 Complétude du dictionnaire TRANSLATIONS (toutes les clés ont fr et en, aucune valeur vide)
TestT 4 Fonction t() : retourne la bonne langue, fallback sur la clé si inconnue
TestGetLang 7 Détection de langue : cache mémoire, lecture de env_var.sh, variable d'environnement, fallback à "fr"
TestSetLang 4 Persistance de la langue dans env_var.sh, gestion de fichier manquant
TestLangIsConfigured 3 Détection de l'état de configuration

Mocks : @patch.object sur ENV_VAR_FILE, @patch.dict(os.environ), setUp/tearDown pour réinitialiser _current_lang


7. test_check_addons_exist.py — Odoo addon validation

Type: Unit test (temporary files, no Odoo required)

Class # Tests What is validated
TestMainModuleFound 3 Module found with valid __manifest__.py, JSON and formatted JSON output
TestMainModuleMissing 2 Missing module returns code 1, JSON output for missing module
TestMainDuplicateModule 1 Duplicate module in multiple paths returns code 2
TestMainMissingManifest 1 Directory without __manifest__.py returns code 1
TestMainBadConfig 2 INI config without [options] section or without addons_path key returns -1

Mocks: @patch("sys.argv"), temporary files for addons and INI config

7. test_check_addons_exist.py — Validation des addons Odoo

Type : Test unitaire (fichiers temporaires, aucun Odoo requis)

Classe # Tests Ce qui est validé
TestMainModuleFound 3 Module trouvé avec __manifest__.py valide, sortie JSON et JSON formaté
TestMainModuleMissing 2 Module absent retourne code 1, sortie JSON pour module manquant
TestMainDuplicateModule 1 Module en double dans plusieurs chemins retourne code 2
TestMainMissingManifest 1 Répertoire sans __manifest__.py retourne code 1
TestMainBadConfig 2 Config INI sans section [options] ou sans clé addons_path retourne -1

Mocks : @patch("sys.argv"), fichiers temporaires pour addons et config INI


8. test_iscompatible.py — Pip version compatibility

Type: Unit test (pure logic, no I/O)

Class # Tests What is validated
TestStringToTuple 4 Version string to integer tuple conversion
TestParseRequirements 7 Parsing requirements.txt syntax (operators, multiple constraints, comments)
TestIsCompatible 11 Version compatibility checking with operators ==, >=, >, <, <=, != and ranges

Mocks: None — pure functions

8. test_iscompatible.py — Compatibilité de versions pip

Type : Test unitaire (pure logique, aucun I/O)

Classe # Tests Ce qui est validé
TestStringToTuple 4 Conversion de chaîne de version en tuple d'entiers
TestParseRequirements 7 Parsing de la syntaxe requirements.txt (opérateurs, contraintes multiples, commentaires)
TestIsCompatible 11 Vérification de compatibilité de version avec opérateurs ==, >=, >, <, <=, != et plages

Mocks : Aucun — fonctions pures


9. test_format_file_to_commit.py — Modified file detection for formatting

Type: Unit test (mocked git) + Integration test (execute_shell runs real processes)

Class # Tests What is validated
TestExecuteShell 5 Shell command execution: success, failure (return code), stderr capture, empty output, multiline output
TestGetModifiedFiles 9 Parsing git status --porcelain: modified, added, deleted (ignored), ZIP/tar.gz (ignored), untracked, empty status, multiple statuses, git error

Mocks: @patch on subprocess.run, os.path.exists, os.path.isfile

9. test_format_file_to_commit.py — Détection de fichiers modifiés pour formatage

Type : Test unitaire (git mocké) + Test d'intégration (execute_shell exécute de vrais processus)

Classe # Tests Ce qui est validé
TestExecuteShell 5 Exécution de commandes shell : succès, échec (code retour), capture stderr, sortie vide, sortie multiligne
TestGetModifiedFiles 9 Parsing du git status --porcelain : fichier modifié, ajouté, supprimé (ignoré), ZIP/tar.gz (ignorés), non suivi, statut vide, statuts multiples, erreur git

Mocks : @patch sur subprocess.run, os.path.exists, os.path.isfile


10. test_version.py — ERPLibre version management

Type: Unit test

Class # Tests What is validated
TestRemoveDotPath 6 Removing ./ prefix from paths
TestDie 3 Conditional exit with configurable error code
TestConstants 7 Versioned file name templates (venv, manifest, pyproject, poetry lock, addons, odoo)
TestUpdateValidateVersion 5 Version resolution: explicit, by odoo_version, default fallback, detected version, expected paths
TestUpdateDetectVersion 2 Version detection: missing files, matching with data_version
TestUpdatePrintLog 2 Execution log display (empty and populated)

Mocks: @patch("sys.argv"), temporary files for version files, @patch on path constants

10. test_version.py — Gestion des versions ERPLibre

Type : Test unitaire

Classe # Tests Ce qui est validé
TestRemoveDotPath 6 Suppression du préfixe ./ des chemins
TestDie 3 Sortie conditionnelle avec code d'erreur configurable
TestConstants 7 Templates de noms de fichiers versionnés (venv, manifest, pyproject, poetry lock, addons, odoo)
TestUpdateValidateVersion 5 Résolution de version : explicite, par odoo_version, fallback par défaut, version détectée, chemins attendus
TestUpdateDetectVersion 2 Détection de version : fichiers absents, correspondance avec data_version
TestUpdatePrintLog 2 Affichage du log d'exécution vide et peuplé

Mocks : @patch("sys.argv"), fichiers temporaires pour les fichiers de version, @patch sur les constantes de chemin


11. test_docker_update_version.py — Docker version update

Type: Unit test (temporary files)

Class # Tests What is validated
TestEditText 2 Image update in docker-compose.yml after ERPLibre service, other lines preserved
TestEditDockerProd 3 FROM line replacement in Dockerfile, RUN/COPY lines preserved, multi-FROM handling

Mocks: None — uses tempfile.NamedTemporaryFile for Docker files

11. test_docker_update_version.py — Mise à jour de version Docker

Type : Test unitaire (fichiers temporaires)

Classe # Tests Ce qui est validé
TestEditText 2 Mise à jour de l'image dans docker-compose.yml après le service ERPLibre, préservation des autres lignes
TestEditDockerProd 3 Remplacement de la ligne FROM dans Dockerfile, préservation des lignes RUN/COPY, gestion multi-FROM

Mocks : Aucun — utilise tempfile.NamedTemporaryFile pour les fichiers Docker


12. test_code_generator_tools.py — Code generator tools

Type: Unit test (pure AST and string logic)

Class # Tests What is validated
TestCountSpaceTab 9 Indentation counting: spaces, tabs, mixed, \n/\r, custom group_space
TestExtractLambda 2 Lambda expression extraction from AST node, outer parentheses removal
TestFillSearchField 11 Recursive AST value extraction: Constant (str, int, bool), UnaryOp (negative), Name, Attribute, List, Dict, Tuple, Lambda, unsupported type
TestSearchAndReplace 4 Value replacement in Python code: quoted value, empty model, missing keyword, custom keyword
TestArgsTypeParam 6 ARGS_TYPE_PARAM dictionary validation for Odoo field types

Mocks: None — pure functions on AST and strings

12. test_code_generator_tools.py — Outils du générateur de code

Type : Test unitaire (pure logique AST et string)

Classe # Tests Ce qui est validé
TestCountSpaceTab 9 Comptage d'indentation : espaces, tabulations, mixte, \n/\r, group_space personnalisé
TestExtractLambda 2 Extraction d'expression lambda depuis un nœud AST, suppression des parenthèses externes
TestFillSearchField 11 Extraction récursive de valeurs AST : Constant (str, int, bool), UnaryOp (négatif), Name, Attribute, List, Dict, Tuple, Lambda, type non supporté
TestSearchAndReplace 4 Remplacement de valeurs dans du code Python : valeur entre guillemets, modèle vide, mot-clé absent, mot-clé personnalisé
TestArgsTypeParam 6 Validation du dictionnaire ARGS_TYPE_PARAM pour les types de champs Odoo

Mocks : Aucun — fonctions pures sur AST et chaînes de caractères


13. test_database_tools.py — Database tools

Type: Unit test (temporary files)

Class # Tests What is validated
TestProcessZip 4 ZIP file processing: line removal by keyword, preservation when no match, total removal, non-targeted files intact
TestCompareDatabaseApplicationLogic 4 CSV set comparison: identical CSVs, different, empty, one empty

Mocks: None — uses tempfile and zipfile for temporary files

13. test_database_tools.py — Outils de base de données

Type : Test unitaire (fichiers temporaires)

Classe # Tests Ce qui est validé
TestProcessZip 4 Traitement de fichiers ZIP : suppression de lignes par mot-clé, préservation quand pas de correspondance, suppression totale, fichiers non ciblés intacts
TestCompareDatabaseApplicationLogic 4 Comparaison de CSV par ensembles : CSVs identiques, différents, vides, un seul vide

Mocks : Aucun — utilise tempfile et zipfile pour les fichiers temporaires


Coverage matrix by component

Tested component Source file Test file Type
ConfigFile script/config/config_file.py test_config_file.py Unit
Execute script/execute/execute.py test_execute.py Integration
GitTool script/git/git_tool.py test_git_tool.py Unit
kill_process_by_port script/process/kill_process_by_port.py test_kill_process_by_port.py Unit
TODO script/todo/todo.py test_todo.py Unit
todo_i18n script/todo/todo_i18n.py test_todo_i18n.py Unit
check_addons_exist script/addons/check_addons_exist.py test_check_addons_exist.py Unit
iscompatible script/poetry/iscompatible.py test_iscompatible.py Unit
format_file_to_commit script/maintenance/format_file_to_commit.py test_format_file_to_commit.py Unit + Integration
update_env_version script/version/update_env_version.py test_version.py Unit
docker_update_version script/docker/docker_update_version.py test_docker_update_version.py Unit
Code Generator (tools) script/code_generator/search_class_model.py test_code_generator_tools.py Unit
Database (tools) script/database/migrate/process_backup_file.py test_database_tools.py Unit

Partially covered components

The following components have tests for their pure functions, but functions requiring infrastructure (Odoo, PostgreSQL, network) are not unit tested:

  • script/database/process_zip and CSV logic tested; db_restore, image_db, list_remote not tested (require Odoo/PostgreSQL)
  • script/code_generator/extract_lambda, fill_search_field, search_and_replace, count_space_tab tested; generate_module, main not tested (require Odoo)
  • script/poetry/iscompatible, parse_requirements, string_to_tuple tested; combine_requirements, poetry_update.main not tested (require full filesystem)

Matrice de couverture par composant

Composant testé Fichier source Fichier test Type
ConfigFile script/config/config_file.py test_config_file.py Unitaire
Execute script/execute/execute.py test_execute.py Intégration
GitTool script/git/git_tool.py test_git_tool.py Unitaire
kill_process_by_port script/process/kill_process_by_port.py test_kill_process_by_port.py Unitaire
TODO script/todo/todo.py test_todo.py Unitaire
todo_i18n script/todo/todo_i18n.py test_todo_i18n.py Unitaire
check_addons_exist script/addons/check_addons_exist.py test_check_addons_exist.py Unitaire
iscompatible script/poetry/iscompatible.py test_iscompatible.py Unitaire
format_file_to_commit script/maintenance/format_file_to_commit.py test_format_file_to_commit.py Unitaire + Intégration
update_env_version script/version/update_env_version.py test_version.py Unitaire
docker_update_version script/docker/docker_update_version.py test_docker_update_version.py Unitaire
Code Generator (tools) script/code_generator/search_class_model.py test_code_generator_tools.py Unitaire
Database (tools) script/database/migrate/process_backup_file.py test_database_tools.py Unitaire

Composants partiellement couverts

Les composants suivants ont des tests pour leurs fonctions pures, mais les fonctions nécessitant une infrastructure (Odoo, PostgreSQL, réseau) ne sont pas testées unitairement :

  • script/database/process_zip et logique CSV testés ; db_restore, image_db, list_remote non testés (requièrent Odoo/PostgreSQL)
  • script/code_generator/extract_lambda, fill_search_field, search_and_replace, count_space_tab testés ; generate_module, main non testés (requièrent Odoo)
  • script/poetry/iscompatible, parse_requirements, string_to_tuple testés ; combine_requirements, poetry_update.main non testés (requièrent le filesystem complet)

Test patterns used

Pattern Usage
Mocking (@patch) System dependency isolation (psutil, shutil, subprocess, os.path, files)
Temporary files tempfile.mkdtemp() and tempfile.NamedTemporaryFile() for side-effect-free I/O testing
Helper factory _make_proc() in test_kill_process, _mock_git() in test_format, _write_csv() in test_database
Isolated state setUp/tearDown to reset globals between tests
Real execution test_execute.py and TestExecuteShell launch real bash processes
SimpleNamespace Lightweight config creation without argparse in test_docker
AST inline ast.parse(code, mode="eval").body to create test AST nodes

Patterns de test utilisés

Pattern Usage
Mocking (@patch) Isolation des dépendances système (psutil, shutil, subprocess, os.path, fichiers)
Fichiers temporaires tempfile.mkdtemp() et tempfile.NamedTemporaryFile() pour tester l'I/O sans effets de bord
Helper factory _make_proc() dans test_kill_process, _mock_git() dans test_format, _write_csv() dans test_database
État isolé setUp/tearDown pour réinitialiser les globals entre tests
Exécution réelle test_execute.py et TestExecuteShell lancent de vrais processus bash
SimpleNamespace Création de configs légères sans argparse dans test_docker
AST inline ast.parse(code, mode="eval").body pour créer des nœuds AST de test