mercredi 28 août 2013

Play Framework et les Tests Unitaires



Depuis quelques jours, je joue avec Play!, un framework web Java.
Il possède plusieurs avantages forts sympathiques je trouve:

  • Stateless
  • REST
  • Asynchrone
  • Intgérant nativement Junit
Et c'est de ce dernier point en particulier que je vais parler aujourd'hui car l'intégration n'est pas si native que cela et je suis tombé sur plusieurs bugs gênants.

play test ne fait rien


La méthode conseillée pour lancer les tests est la commande "play test" mais malheureusement avec la version 2.1.3, cette commande ne teste absolument rien. Gênant ce bug...
Pour contourner cela il est nécessaire d'ajouter dans le fichier project/Build.scala les lignes suivantes:


val appDependencies = Seq(
    // Add your project dependencies here,
    javaCore,
    javaJdbc,
    javaEbean,
    "play" %% "play-test" % play.core.PlayVersion.current % "test" exclude("com.novocode", "junit-interface"),
    "com.novocode" % "junit-interface" % "0.9" % "test"
)


Ce problème devrait être corrigée dans la 2.1.4 qui ne devrait pas tarder à sortir.

play test se bloque lors des tests IHM


Il est possible avec Play! Framework de réaliser des tests fonctionnels en testant directement une page de notre application. Pour cela on utilise un testbrowser (cf la documentation sur le sujet).

Malheureusement si l'on fait cela avec la version actuelle de Play! Framework cela va bloquer entièrement la commande "play test" qui ne sera donc plus très utile.

Cela est dû à une incompatibilité avec la version de JQuery livré avec Play! Framework d'après ce bug.
La seule façon de débloquer cela est de télécharger la version 1.8.3 de jquery et de l'ajouter dans le dossier public/javascript en remplacement de la version 1.9.0 (ne pas oublier de mettre à jour vos pages aussi).

Lancer les tests unitaires depuis Eclipse


La commande "play test" est sympathique mais il arrive très régulièrement que l'on souhaite lancer uniquement un test ou une classe de tests depuis notre Eclipse et là malheureusement cela ne marche pas comme attendu à cause de l'erreur suivante:


java.lang.IllegalStateException: Class [class play.db.ebean.Model] is enhanced and [class models.Company] is not - (you can not mix!!)



Pour corriger cela il est nécessaire de télécharger le jar d'ebean et de l'ajouter en tant que paramètre par défaut dans Eclipse. Pour cela il est nécessaire d'aller dans Preferences > Java > Installed JRE > Edit et d'ajouter la ligne suivante:


-javaagent:/path/to/ebean/ebean-2.7.3-agent.jar



Et voilà ça devrait mieux aller !


Vraiment ? Pas dans tous les cas en fait. Il peut arriver que suite à cela un test soit cassé car lors d'un select en base via Ebean qui renvoie un objet avec un champ null.
Dans mon cas il s'agissait d'un champ Text (ou @Lob pour Ebean) qui était systématiquement vide alors que l'objet inséré le contenait bien.

Pour corriger cela il faut passer le champ concerné en private et générer soit même les getter/setter au lieu de laisser Play! le faire tout seul.
Et c'est tant mieux, je n'aime pas le fait d'avoir l'ensemble de mes champs public ça casse un peu le principe de l'encapsulation.

Fichier "init-data.conf" non trouvé


Si vous avez suivi les tutoriels du site Play! Framework vous avez vu que l'on peux ajouter facilement des données aux tests ou à l'application en cours de développement en créant un fichier Yaml dans le dossier conf/ et contenant l'ensemble des éléments à créer en base.

Le problème étant que si l'on fait les tests ensuite via Junit dans Eclipse il ne va jamais trouver ce fichier et donc ne va pas précharger votre base de données...

Pour corriger cela il faut ajouter le dossier conf au classpath d'Eclipse car celui-ci n'est pas ajouté lors de la commande "play eclipse".

Pour l'ajouter il suffit de faire un click droit sur le dossier conf/ dans le projet et choisir "Build Path" > "Use as Source Folder".

Je veux le coverage de mon code !


Maintenant que l'on a des tests qui fonctionnent que ça soit via la commande play test ou dans Eclipse on aimerait bien avoir également la couverture de code que l'on teste. Nous allons utiliser jacoco pour générer notre coverage.

Pour cela il faut ajouter plusieurs éléments à notre configuration:

  • Dans le fichier project/plugins.sbt ajouter les lignes suivantes:
libraryDependencies ++= Seq(
  "org.jacoco" % "org.jacoco.core" % "0.5.9.201207300726" artifacts(Artifact("org.jacoco.core", "jar", "jar")),
  "org.jacoco" % "org.jacoco.report" % "0.5.9.201207300726" artifacts(Artifact("org.jacoco.report", "jar", "jar")))

addSbtPlugin("de.johoop" % "jacoco4sbt" % "1.2.4")
  • Dans le fichier project/Build.scala:
  • Ajouter sous les import déjà existant les lignes suivantes:
import de.johoop.jacoco4sbt._
import JacocoPlugin._
  • Ajouter sous le bloc "val appDependencies = Seq(...)" une ligne:
lazy val s = Defaults.defaultSettings ++ Seq(jacoco.settings:_*)


  • Puis modifier le dernier bloc pour qu'il ressemble à cela (attention à bien ajouter le paramètre settings = s):
val main = play.Project(appName, appVersion, appDependencies, settings = s).settings(
    
    parallelExecution     in jacoco.Config := false,    
    jacoco.reportFormats  in jacoco.Config := Seq(XMLReport("utf-8"), HTMLReport("utf-8")),    
    jacoco.excludes       in jacoco.Config := Seq("views.*", "controllers.Reverse*", "controllers.javascript.*", "controllers.ref.*", "Routes*")
  )



Et voilà la couverture peut maintenant être générée via la commande:

play jacoco:cover



L'ensemble des fichiers seront placés dans le dossier /target/scala-2.9.1/jacoco/html.


Petit exemple du look:





Post 11/52

lundi 26 août 2013

QTodoTxt: une application pour todo.txt simple, rapide et multiplateforme




Aujourd'hui j'aimerai vous parler d'un sujet qui me tient particulièrement à coeur à savoir l'organisation personnelle et en particulier "Getting things done" (GTD).


J'ai découvert ce système et lu le livre allant avec il y a 3 ans alors que je cherchais une méthode un peu plus évoluée afin de gérer mes actions et projets au mieux. Cela m'aide beaucoup afin de ne pas tout reporter au lendemain ni de conserver en tête toute la liste de choses que j'ai à faire.
Du coup cela me libère l'esprit et me permet de me concentrer sur ce que je fais à l'heure actuelle. En plus de ne rien oublier, je suis plus efficace dans ce que je fais, que du bénef !


Par contre il me manquait un outil me permettant d'appliquer cette méthode au quotidien. Mon cahier des charges était assez simple (enfin je pensais):

  • Libre
  • Fonctionnant sur Android, Linux et Windows
  • Permettant de synchroniser mes tâches entre mes différents appareils
  • Avec une interface utilisateur simple
En ce qui concerne la partie mobile et la synchro (via Dropbox) j'ai trouvé assez rapidement avec l'outil Todo.txt Touch de Gina Trapani qui est la partie mobile de todo.txt. Payant mais open-source, il fonctionne bien et est maintenu par une communauté active.
De plus l'application n'a pas une structure très complexe, uniquement 2 fichiers texte dont un optionnel:

  • todo.txt: contenant l'ensemble des tâches
  • done.txt: contenant l'ensemble des tâches terminées (optionnel)
Je me retrouvais donc avec 2 fichiers synchronisés sur mes ordinateurs mais rien pour les lire de manière un peu sympa...

Après moultes recherches où j'ai trouvé des interfaces web (un peu chiant de devoir installer un apache absolument partout), des outils pour Windows uniquement ou seulement pour Linux je suis tombé sur la perle rare: QTodoTxt.

Un outil simple, multi-plateforme codé en python + Qt, open-source et rapide. Bref il semblait idéal sauf qu'il:

  • n'était plus maintenu depuis 2011
  • avait quelques bugs gênants (pas de support de l'utf8,...)
  • manquait de quelques fonctionnalités (date de création, sauvegarde automatique, auto-archivage,...)
Heureusement le code étant opensource et ayant toujours voulu jouer un peu avec du python, je me suis dis pourquoi pas, adoptons une application !

Première fois et tout se passe bien , j'ajoute des fonctionnalités, des paquets binaires, je corrige quelques bugs et j'ai même reçu mes premiers rapports de bug d'utilisateurs externes.

C'est sympa de se dire que mon application est utile à d'autres.

Du coup après 2 versions l'application permet maintenant de gérer les URLs dans les tâches, les dates de fin, la sauvegarde automatique, l'archivage automatique et la correction des quelques bugs gênants.


Même si je ne suis pas dessus en permanence je m'en sers tous les jours et elle remplie bien son but, simple,rapide et efficace!


N'hésitez pas à la tester vous aussi !

Post: 10/52

samedi 17 août 2013

Compilation de lien n°3



Ca fait longtemps que je n'ai rien publié, mille excuses !

On est reparti pour un tour avec plein de nouvelles idées et de truc sympas à découvrir. Pour le moment on va commencer doucement avec une petite collection de liens intéressants.

  • http://colorschemedesigner.com/ : Si comme moi vous galérez toujours pour trouver des couleurs qui s'accordent bien ensemble ce site est fait pour vous. À partir d’une couleur donnée et du schéma choisi (monochrome, complémentaire, triade,...), l’application déduit les différentes teintes pouvant s’accorder entre elles. Toujours pratique !
  • Nginx vient de devenir le nouveau serveur web le plus utilisé parmi les sites du Top 1000 d'après cet article de w3techs.com. Va vraiment falloir que je teste ça !
  • Twitter: un article passionnant sur l'architecture utilisée par Twitter pour gérer 150 millions d'utilisateurs.
  • Un article donnant quelques conseils pour bien réussir un entretien (on y reviendra sur ce sujet :) et pas mal de liens utiles.
  • Dernier lien mais pas des moindres, il s'agit de RunDeck, un outil permettant d'automatiser des workflows à travers une ferme de serveurs. Puppet est super sympa mais malheureusement il n'est pas possible de demander à déployer d'abord le serveur A puis le B. RunDeck permet de faire ça et bien plus encore !
Et voilà c'est tout pour le moment !

Post: 9/52