mai
2008
Mais les images parlent d’elles-mêmes :
Après cette accroche quelque peu racoleuse, je m’explique :
JsUnit est un outil permettant de tester ses fonctions écrit en JavaScript. C’est tout simplement l’équivalent Javascript de JUnit. J’ai programmé mes tests au fur et à mesure en utilisant Firefox, puis à la fin de la semaine, je me suis rappelé l’existence d’Internet Explorer. Au vu des résultats, je me suis dit que la compatibilité présumée de Prototype envers FF et IE allait prendre du plomb dans l’aile. Il m’a donc fallu chercher l’origine de ces bugs.
Première partie : des variations minimes mais suffisantes
Les lecteurs avisés me diront que je ne teste pas la même chose, puisque j’ai 56 tests sur FireFox et 59 sur IE. C’est parce que JUnit sous IE s’amuse à évaluer des fonctions telles que celle-ci :
function testControllers(){};
*/
Avec Prototype, j’ai étendu l’objet Element pour y mettre la fonction getParentElement() qui renvoit le paragraph le plus proche de l’élément.
J’utilise donc la ligne : parent=element.up(".paragraph");
IE me renvoit une erreur "Not Implemented". Je pensais qu’il y avait une erreur avec l’implémentation de up() par Prototype mais en fait mÔnsieur Internet Explorer n’accepte pas le nom de variable parent. Essayez parent="" ou parent="java" et vous aurez une erreur "Not Implemented".
En déclarant la variable var parent="", tout va mieux.
Il faut ensuite savoir que lorsque vous écriver du code HTML, les moteurs de Firefox et IE les réécrivent derrière vous. Cela se voit en utilisant alert(monElement.innerHTML). J’ai repéré deux problèmes notables :
Internet Explorer réécrit au lieu de . Les guillemets de l’attribut value disparait : ce qui fait que value n’est d’ailleurs plus un attribut au sens xml. Assez génant pour les tests unitaires tels que celui-ci :
assertTrue (divControllers.innerHTML.include(‘ value="I" ‘));
Internet Explorer réécrit ses balises en majuscules. InnerHTML renvoit H3 au lieu de h3. Il faut donc réécrire les tests :
assertTrue(divForm.innerHTML.toLowerCase().include(‘h3′));
au lieu de :
assertTrue(divForm.innerHTML.include(‘h3′));
Deuxième partie : Le XML avec Prototype
Dans mes tests unitaires, j’utilise une String :
"<lastname>Zozol</lastname>"+
"<firstname>Nicolas</firstname>"+
"<web-site>http://www.edupassion.com</web-site>"+
"<identifiant>1</identifiant>"+
"<role>professeur</role>"+
"<level>admin</level>"+
"</object>";
Et je teste ma fonction sensée recevoir transport.responseText.
transport.responseText=result;
assertTrue(maFonction(result)=="tout va bien");
Une fonction utilisant transport.responseText est à priori plus facile à tester qu’une autre utilisant transport.responseXML.
result.select("firstname")[0].innerHTML fonctionne très bien sous FireFox et me renvoit « Nicolas ». Mais sous IE, impossible de parser un élément non inscrit dans le document ! Prototype fonctionne bien, mais considère, sous IE, result comme une string, et pas comme un ensemble d’élément organisés en arbre. Il est donc nécessaire de passer par responseXML et d’ignorer ici les avantages de Prototype.
Le test unitaire de la fonction traitant le résultat devient plus compliqué : le Mock object n’est plus une String mais un document. Si vous avez une petite fonction fiable transformant mon String en document XML, je suis preneur.
J’ai du mal a comprendre ce que tu reproches à IE là honnêtement… Tout ce que tu décris fait partie du fonctionnement normal…
Tape dans ta console firebug « parent », tu vas voir que l’objet existe et qu’il correspond à un objet du navigateur. Ca me parait assez normal qu’il ne soit pas possible de réécrire par dessus… Bizarrement FF le fait mais doit utiliser un mécanisme pour l’identifier différemment que l’objet window.parent. Donc la je dirais que IE est plutot juste.
A mon avis, tu utilises mal le .innerHTML. C’est pas une propriété qui doit servir à
afficher la structure d’un element mais uniquement son contenu texte. Donc que IE te retourne une mauvaise valeur sur un code que toi même utilises mal, ca me parait pas super choquant. Pour voir la valeur de ton input, ya une propriété qui existe, .value ^^.
IE a toujours écrit ses attributs en majuscule ^^. Ceci étant, la encore tu utilises les mauvaises méthodes. C’est pour ce genre de choses que le DOM existe.
La encore, si responseText et responseXML existent, c’est bien pour quelque chose. Appliquer une fonction destinée à un objet de l’interface Node sur une String, forcément, ca ne marche pas…
Cadeau:
<br />
var parser = null; <br />
var xml = null; <br />
<br />
try{ <br />
parser = new ActiveXObject('Microsoft.XMLDOM'); <br />
parser.async = false; <br />
parser.loadXML(xmlTxt); <br />
xml = parser.documentElement; <br />
} <br />
catch(e){ <br />
parser = new DOMParser(); <br />
xml = parser.parseFromString(xmlTxt,"text/xml").documentElement; <br />
} <br />
<br />
return xml; <br />
<br />
}
Il faut être honnête : certaines erreurs sont dues au fait que Firefox est plus permissif que IE.
Ensuite j’avais des erreurs parce que le XML n’étant pas parsé par IE, mes tests attendaient un résultat précis, et du coup la suite du programme lance une erreur alors qu’un programme bien fait devrait plutôt levé une exception.
me voila, tu m’as racolé ! :>>
et avec les 4 corrections que tu fais, tu résous 14 erreurs d’IE. Édifiant !!!
en fait, ce jsunit, il devrait s’en servir chez microsoft pour tester IE !
le coup du je te vire les quotes, c’est un coup à déprimer ceux qui font de l’XML sous IE.