fixed all the last big bugs before going to PWA
This commit is contained in:
+103
-1
@@ -338,6 +338,10 @@ J'ai mis une durée arbitraire de deux jours, mais je ne sais pas vraiment combi
|
||||
|
||||
----
|
||||
|
||||
### Outils utilisés
|
||||
|
||||
[A Remplir]
|
||||
|
||||
### Technologies utilisées
|
||||
|
||||
Dans ce projet différents choix ont été faits pour ce qui est des technologies.
|
||||
@@ -1939,7 +1943,105 @@ Les possibilitées sont infinies !
|
||||
|
||||
----
|
||||
|
||||
[A remplir au fur et à mesure de la création des tests]
|
||||
Alors la on arrive à la GROSSE erreur de ce projet...
|
||||
|
||||
Si je ne pouvais changer qu'une seule chose à ma facon de faire le projet après coup c'est ici que je ferai le changement.
|
||||
|
||||
Les tests sont d'une importance absolument capitale mais si ils sont bien faits, c'est surtout un moyen ultra efficace de vérifier que du nouveau code est performant et est beaucoup plus pratique à utiliser.
|
||||
|
||||
Je pense sans rire que j'aurais pu gagner plusieurs jours de travail si j'avais travaillé différemment vis-a-vis des tests.
|
||||
|
||||
### Comment ca c'est passé
|
||||
|
||||
Dès la création du planning prévisionnel j'ai fait une erreur capitale. J'ai mis les tests en fin de developpement des features... Et je ne leur ai laissé que très peu de temps tout en les mettant au milieu du chemin critique ce qui les rends particulièrement vulnérables si une tâche du chemin critique est retardée.
|
||||
|
||||
En fait dans ce projet je voulais surtout éviter de faire comme certains projets que l'on a pu avoir pendant notre formation. C'est à dire que je ne voulais surtout pas oublier la doc. Alors j'ai agencé le projet pour commencer par les fondations de la doc, puis en incluant les périodes de programmation et entre ces dernière ajouter des Tests dans les trous. Le soucis c'est que du coup les projets étaient un peu le dernier truc dont je devais me soucier ce qui a été une très mauvaise idée.
|
||||
|
||||
Je me suis retrouvé à devoir mordre sur les jours de tests car les tâches de programmation mettaient plus de temps que prévu (qui elles-même auraient pû être plus courte avec une bonne utilisation des tests) et je mme suis retrouvé à passer outre les tests pour avancer sur le reste du projet.
|
||||
|
||||
J'ai donc du en panique à la toute fin du projet construire quelques tests "unitaires" dont l'utilité est très limitée car tout le travail a déja été fait et que vu la complexité qu'a pris le projet, faire de vrais tests unitaires est devenu un peu trop compliqué pour valoir le coup.
|
||||
|
||||
Les seuls tests "unitaires" (Je l'écris entre quotes car ce ne sont pas vraiment des tests unitaires mais plutôt des tests tout courts car ils ne sont pas spécifiques) qu'il y a dans le projet final sont des tests exclusivement tournés sur l'OCR. Ils sont déja vraiment pratiques car cela me permet de tester d'autres algorythmes d'OCR et voir si les résultats sont meilleurs ou non mais c'est juste un peu trop tard quoi...
|
||||
|
||||
Les tests unitaires que j'ai implémentés sont un peu tous pareils au niveau du fonctionnement :
|
||||
|
||||
1. On choisit une image dans une liste d'images préparées qui sont scensée représenter le type de données rencontrées par l'application en temps normal
|
||||
2. On lis le nom de l'image que j'ai mis manuellement en indiquant ce qui était marqué sur l'image
|
||||
3. On fait un coup d'OCR sur l'image et on compare ce résultat avec la valeur que l'on est scensé retrouver
|
||||
|
||||
En pratique on est sur un code de ce style :
|
||||
|
||||
```Csharp
|
||||
[TestMethod()]
|
||||
public void SectorOCR_Test()
|
||||
{
|
||||
string directory = @"./../../TestImages/Sectors/";
|
||||
foreach (string file in Directory.GetFiles(directory))
|
||||
{
|
||||
Bitmap image = (Bitmap)Image.FromFile(file);
|
||||
DriverSectorWindow sectorsWindow = new DriverSectorWindow(image, new Rectangle(0, 0, image.Width, image.Height), 1, true);
|
||||
string[] paths = file.Split('/');
|
||||
string fileName = paths[paths.Length - 1];
|
||||
fileName = fileName.Replace(".png", "");
|
||||
|
||||
int timeMS = (int)sectorsWindow.DecodePng();
|
||||
string time = Reader.ConvertMsToTime(timeMS);
|
||||
|
||||
string[] checkDigits = fileName.Split('_');
|
||||
string[] digitsToCheck = time.Split(':');
|
||||
|
||||
if (time == "0:00:000")
|
||||
{
|
||||
Assert.AreEqual(0, Convert.ToInt32(checkDigits[0]));
|
||||
}
|
||||
else
|
||||
{
|
||||
//The ConvertMSToTime will always return three chars so we need to make the checkDigits be also three chars
|
||||
while (checkDigits.Length != 3)
|
||||
checkDigits = new[] { "0" }.Concat(checkDigits).ToArray();
|
||||
|
||||
for (int i = 0; i < checkDigits.Length; i++)
|
||||
{
|
||||
//We need to convert to int first because sometimes we have "08" and "8" and in string its not the same but in int it is
|
||||
Assert.AreEqual(Convert.ToInt32(checkDigits[i]), Convert.ToInt32(digitsToCheck[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Tout le code supplémentaire qui ne fait pas partie des étapes citées est juste la pour manipuler le format des résultats pour qu'il soit comparable.
|
||||
|
||||

|
||||
|
||||
Ce qui est pratique avec cette approche c'est qu'il est très facile de rajouter des cas spécifiques et voir comment le programme les gère.
|
||||
Si je vois que un certain nombre est souvent mal reconnu je peux faire exprès de le mettre dans le dossier et modifier mon code d'OCR jusqu'à ce que le test passe.
|
||||
|
||||
Si j'avais eu plus de temps j'aurais sûrement pu ajouter de vrais tests unitaires qui testent des fonctions très précises. Par exemple verifier que les différentes Windows sont bien appelées et que les zones se créent correctement ou même plus simplement que la lecture du JSON au démarrage marche bien.
|
||||
|
||||
Il faut savoir que même si je n'ai pas eu l'occasion d'écrire beaucoup de tests sous forme de code. Toute la phase de développement de l'OCR j'ai passé plus d'une heure par jour à analyser les résultats. Je gardais toutes les images des WINDOWS et je notais dans le nom du fichier ce que l'algorythme trouvais et je passais en revue manuellement les centaines de résultats pour isoler ceux qui posaient problème.
|
||||
|
||||
C'est comme ca que je me suis rendu compte par exemple que, avec cette police, les 4 et les 1 étaient souvent confondus. Donc même si les tests automatisés sont clairement insuffisant par rapport à ce que j'aurais peut-être du faire, j'ai passé énormément de temps à tester mon application.
|
||||
|
||||
### Comment ca aurait du se passer
|
||||
|
||||
Si je devais refaire ce projet aujourd'hui je pense que j'utiliserais un peu la même technique que pour la doc. J'aurais mis les tâches de Tests directement au début du projet et j'aurais determiné le squelette de l'application par la même occasion.
|
||||
|
||||
Je pense que j'aurais mis trois jours pour écrire tous les tests dont j'aurais besoin et j'aurais fait une stratégie de TDD (Test Driven Developpement) par ce que je pense que ca marcherait vraiment super bien sur ce type de projet.
|
||||
|
||||
J'aurais pris je pense 5 une dixaine d'images complêtes de la F1TV de plusieurs GP différents et j'aurais mis toutes les fenêtres découpées dans des fichiers avec des tests comme ceux que j'ai fait pour ce projet. Et comme ca je saurai que mon algo est bon uniquement quand il aura réussi à passer tous les tests.
|
||||
|
||||
Cela règlerait le soucis que j'ai eu le plus : Me retrouver à devoir changer l'OCR 5 fois par ce que à chaque fois que je développe une nouvelle feature je me rends compte d'une faiblesse mon algorythme...
|
||||
|
||||
Non seulement j'aurai eu beaucoup plus de facilité à avancer sur le projet, mais en plus je pense que cela m'aurait fait gagner énormément de temps non seulement car je n'ai plus à tester tout à la main mais en plus par ce que ca veut dire que quand l'OCR passe les tests je n'ai plus jamais à m'en soucier.
|
||||
|
||||
### Lecons
|
||||
|
||||
Je pense que dans mes futurs projets je mettrai les tests en début de projet plutôt que à la fin et je ferai en sorte qu'ils fassent partie du chemin critique et que je ne puisse pas passer à côté sous pretexte que "Je n'ai pas le temps".
|
||||
|
||||
Ecrire des tests c'est jamais marrant et c'est encore moins marrant quand ils nous empêchent d'avancer. Mais je suis convaincu que au final c'est un gain de temps et de sérénité incontournable.
|
||||
|
||||
[INSERER MEME SUR LES TESTS UNITAIRES]
|
||||
|
||||
## Résumé des difficultés techniques
|
||||
|
||||
|
||||
Reference in New Issue
Block a user