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>
264 lines
No EOL
13 KiB
Markdown
264 lines
No EOL
13 KiB
Markdown
|
|
# 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 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` — 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` — 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` — 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` — 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` — 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` — 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` — 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` — 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` — 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` — 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` — 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` — 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
|
|
|
|
---
|
|
|
|
## 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)
|
|
|
|
---
|
|
|
|
## 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 | |