Un Electron Libre...

Aller au contenu | Aller au menu | Aller à la recherche

Développement Web

Projets personnels et développements web en général, à l'exception de tout ce qui touche à Python/Django

Fil des billets - Fil des commentaires

Conventions de codage (si tant est que j'en ai...)

Quand j'ai vu cette chaine sur les conventions de codage se diffuser sur le web avant l'été (ici ou encore ), je me disais "enfin une qui va me passer à coté, je peux dormir tranquille", ne me considérant pas comme un développeur (ou alors un du dimanche ;-) ) et n'étant pas non plus développeur de formation... Et bien non, Nicolas Hoizey a décidé de me refiler cette chaine.

Pour les projets réalisés dans un cadre professionnel, pour tout ce qui a été en html/css/php et autres boucles SPIP, j'ai par le passé tenté de bêtement copier ce que faisaient mes petits camarades. Cela se justifiait principalement par le fait que j'intervenais ponctuellement sur le code et ne souhaitait pas les perturber plus que nécessaire.

Pour les projets réalisés dans un cadre professionnel et dont je suis à l'origine ou pour mes projets perso, je n'ai pas de règle précise, je vise surtout une logique de lisibilté.

Cela donnera par ex pour un script bash dont l'objectif est de packager des fichiers par ex :

#
## Get relevant information for the packaging
#
 
# Do we need to send file on the front server ?
... some code ...
 
# Do we need to send file on the database server ?
... some code ...
 
#
## Let's build the package
#
 
# Package files for front server
... some code ...
 
# Package files for database server
... some code ...

Je prends souvent ce schéma pour tout ce qui a trait à l'administration système et pour les CSS (en adaptant les caractères de commentaires bien sur...).

Pour continuer sur les CSS, mon ordre de fabrication de mon fichier va être le suivant :

  • Eléments globaux / génériques
  • Section des plus "grandes" vers les plus "petites" (body > left > sidebar)
  • Au sein de chaque section, en premier lieux les éléments de positionnement puis ceux de mise en forme (pour reprendre une logique du plus grand au plus petit)

L'idée étant de regrouper le code en des sous-ensemble logiques.

Cela pourrait donner qqc comme :

/********************************
*  Elements généraux/generiques
********************************/
 
body {
}
 
h1 {
}
 
a {
}
 
/********************************
* Zone gauche
********************************/
 
#left {
}
 
/* Menu gauche */
 
#left #menu {
}
 
#left #menu a{
}

Par contre, là où j'ai toujours eu un souci avec PHP par ex, c'est sur la convention à suivre sur la gestion des accolades (qui en plus suivant l'IDE, l'interpréation peut changer) :

Ex :

if ($toto == "toto")
    {
    ... some code ...
    }

ou

if ($toto == "toto")
{
    ... some code ...
}

ou :

if ($toto == "toto") {
    ... some code ...
    }

ou :

if ($toto == "toto") {
    ... some code ...
}

Ou surement encore plein d'autres choses faisant que mon code au final se trouvait mal indenté (ou pas toujours de la même façon, ne parvenant pas à décider de ce qui était le plus lisible), surtout si les choses avaient tendance à s'imbriquer.

Je pense d'ailleurs que c'est une des raisons pour lesquelles j'aime python. L'indentation que l'on doit respecter permet de donner une bonne lisibilité du code. En plus, la charte de bonne conduite est clairement définie, même si je ne la suis pas encore dans son intégralité...

"""
Profile
 
This object is used to provide some common information regarding the profile of a user.
"""
 
class Profile(models.Model):
    CIVILITY_CHOICES = (
         ('single', _('Single')),
         ('taken', _('Taken')),
    )
    who = models.ForeignKey(User, unique=True, verbose_name=_('Person'),)
    photo = models.ImageField(height_field="80", width_field="80", upload_to="photos", blank=True)
    street = models.CharField(_('Address 1'), max_length=100)
    street_bis = models.CharField(_('Address 2'), max_length=100, blank=True)
    zipcode = models.IntegerField(_('Zip code'), max_length=5)
    city = models.CharField(_('City'), max_length=100)
    country = models.CharField(_('Country'), max_length=100)
    phone = models.CharField(_('Phone'), max_length=20)
    mobile = models.CharField(_('Mobile'), max_length=20, blank=True)
    civility = models.CharField(_('Status'), max_length=20, choices=CIVILITY_CHOICES)
    birthdate = models.DateField(_('Birth date'))
    children = models.IntegerField(_('Children'), blank=True, null=True)
 
    def __unicode__(self):
        return self.who.get_full_name()
 
    class Admin:
        list_display = ('who',)
        list_filter = ['who',]
        search_fields = ['who',]
 
    class Meta:
        verbose_name = _('Civil state')
        verbose_name_plural = _('Civil states')

Pour le débat indentation vs espace, j'avoue avoir préféré les espaces. Etant feinéant, je profitais aussi de la fonction de nombreux IDE qui transforment la tabulation en 4 espaces (ce qui permettait de continuer à utiliser la touche tab pour indenter son code...)

En tous cas, si je devais donner une conclusion à cet essai, que pour adopter une convention de codage, il faut :

  • Regarder si une convention n'est pas définie au niveau du language, si oui, alors l'adopter.
  • Regarder si une convention n'est pas définie au niveau du programme que vous utilisez, si oui, alors l'adopter (et si elle entre en conflit avec celle du langue, tant pis pour le langage, il est plus logique d'avoir un code cohérent)
  • Si aucune des deux n'est définie, voir pour trouver une convention qui vous va bien à vous et le cas échéant à vos coéquipiers (à ce titre, mieux vaut en discuter avant le début du code qu'après, ça évitera de vous marcher dessus ensuite...)
  • Adopter une terminologie anglaise (penser que votre code et commentaires peuvent être lus/utilisés par un prestataire indien - que feriez vous si vous deviez reprendre un code dont les commentaires sont en chinois par ex ?)

MvMo 0.4 "Job wanted"

Ma recherche d'emploi aura au moins eu le mérite de faire avancer MvMo un peu plus vite que prévu ;-)

Au programme de la 0.4 :

  • Support du microformat hresume,
  • Ajout d'un champ "rôle" dans le modèle "Association"
  • Remaniement des modèles "Userskill", "Skill" et "Domainskill" pour que le domaine soit géré au niveau de "Skill" et non plus au niveau de "Userskill".
  • Les templates propres à MvMo sont dans mvmo/templates
  • Plein de petites corrections & améliorations
  • Sans oublier l'instance de démo MvMo

Le CHANGELOG complet est disponible.

Pour les utilisateurs (j'en connais au moins un), attention à bien lire le contenu de MIGRATIONS.txt et README.txt.

MvMo - Instance de démo en attendant la 0.4

La version 0.4, qui apporte son lot de nouveautés dont les microformats (hresume), ne devrait pas tarder à pointer le bout de son nez si j'arrive à tordre le nez à une petite jointure qui fait de la résistance...

Bref, en attendant cet événement, une instance de démo demandée depuis la sortie de la 0.1 a été mis en place (enfin !) :

Je n'ai pas encore mis en place la tâche cron qui réinitialise les contenus mais cela devrait être fait bientôt...

Au passage, il m'a fallu passer le serveur d'une version 0.96 à une version svn. Cela s'est fait sans trop de soucis, par contre, il me faudra faire quelques modifis pour Steinmetz.fr, il y a quelques warnings lié à la dépréciation de certaines syntaxes.

Bien entendu, je suis ouvert à toutes vos remarques / suggestions !

Edit du 13/02 : La jointure a été vaincue - l'instance de démo a été mis à jour, cela devrait être la 0.4 à quelques nettoyages près...

Selenium, testez fonctionnellement vos applications web (partie 2/2)

Billet publié initialement sur le blog de Clever Age

Suite de notre épopée sur Selenium, l’outil de test fonctionnel pour des applications web. Pour ceux qui auraient raté l’épisode 1 : Selenium, testez fonctionnellement vos applications web (partie 1/2)

Ce second volet suppose que vous avez lu l’épisode 1 et sera davantage axé sur l’implémentation de Selenium et Selenium RC.

Pré-requis

Pour Selenium IDE :

Pour Selenium RC :

  • Java Runtime Environment (JRE) >= 1.5.0 – Téléchargement
  • Selenium RC >= 0.9.2 - Téléchargement
  • Si vous comptez utiliser des scripts en Python, Ruby, Java, PHP, .Net ou Perl, il faut que le langage désiré soit installé sur votre ordinateur afin que les tests puissent être exécutés.

Enregistrer un test

Il suffit de procéder de la façon suivante :

  • Lancer Firefox
  • Menu Outils > Selenium IDE
  • Vérifier que le bouton d’enregistrement (bouton rond rouge) est bien pressé
  • Dans votre fenêtre Firefox, rendez-vous sur la page à tester
  • Exécuter les différentes étapes de votre scénario
  • Une fois votre scénario fini, stopper l’enregistrement en cliquant sur le bouton rond rouge)
  • Sauvegarder votre test (au format HTML)
  • Lancer le pour valider son bon fonctionnement (en cliquant sur la flêche verte)

Si besoin, fignoler votre test :

  • Ajouter des commandes "pause” si Selenium va plus vite que votre application ou détecte mal la fin de chargement de la page
  • Ajouter les commandes Selenium nécessaires si certaines parties de votre test n’ont pas pu être enregistrées par Selenium IDE (cas de certains menus/formulaire avec du javascript)
  • ...

Utiliser des valeurs dynamiques

Le besoin d’avoir des valeurs dynamiques se fait rapidement sentir dès lors que :

  • l’unicité d’une information est mise en place : une fois le test joué, on ne peut plus le rejouer sous peine de lever une erreur. Dans ce cas, le besoin peut être par exemple de pouvoir générer des listes de noms, prénoms et adresses email.
  • des mécanismes de cache sont en place : une fois le test joué, l’application a stocké les données demandées dans son cache. Rejouer le test est possible mais ce mécanisme de cache peut influer sur les résultats. Dans ce cas, le besoin peut être par exemple de pouvoir générer des dates aléatoires
  • des mécanismes temporels sont en place : si je teste une application de réservation de place de concerts avec pour date le 13 juin 2007, alors le test ne sera plus valide dès le 14 juin, puisque la date de l’événement sera passée.
  • ...

Selenium nous permet de définir des valeurs dynamiques, utilisables dans nos cas de test en créant des fonctions JavaScript.

Pour ce faire, il faut créer un fichier ’user-extensions.js’ qui contiendra par exemple pour la définition d’un jour et d’un mois compris entre aujourd’hui et la fin de l’année (les fonctions peuvent être améliorées, nous ne sommes pas à l’abri d’un 31 novembre par ex) :

function RandomNumber(value)
        {
        return Math.floor(Math.random()*value);  
        }
 
function RandomDay()
        {
        date = new Date();
        day = date.getDate();      
        return RandomNumber(31-day)+day;
        }
 
function RandomMonth()
        {
        date = new Date();
        month = date.getMonth(); //janvier = 0 -> décembre = 11
        return RandomNumber(11-month)+month;
        }

Il faut ensuite déclarer ce fichier dans Selenium IDE : Menu Option > Options... > Extensions de Selenium Core (user-extensions.js). Une fois votre fichier sélectionné, il vous faudra relancer votre instance de Selenium IDE pour qu’il soit pris en compte. Si votre fichier contient une erreur de syntaxe, Selenium IDE vous le dira.

Dans votre test Selenium, remplacez alors la valeur fixe par l’appel à la fonction javascript :

Ce que vous aviez initialement :

Commande Cible Valeur
type jour_arrivee 22
type mois_arrivee 12

Ce que vous obtenez au final :

Commande Cible Valeur
type jour_arrivee javascript{RandomDay()}
type mois_arrivee javascript{RandomMonth()}

Dans le cas d’une liste déroulante, il faudra procéder en deux étapes :

  • Génération de la valeur,
  • Selection de la valeur obtenue dans la liste.
Commande Cible Valeur
store mon_jour_arrivee javascript{RandomDay()}
select jour_arrivee label=${mon_jour_arrivee}

Conseils :

  • Créer une bibliothèque commune de fonctions JavaScript que chaque testeur/développeur viendra enrichir
  • Décomposer au maximum vos fonctions afin de pouvoir réutiliser rapidement certains morceaux pour construire d’autres fonctions.

Construire une Test Suite

Une Test Suite est un fichier HTML dans lequel chaque test est référencé dans une ligne du tableau, comme vous pouvez le constater dans l’exemple suivant :

<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>Selenium : CA Technical Meeting</title>
<script language="JavaScript" type="text/javascript">
   var DISABLED = true; // used to flag failing tests
   function filterTestsForBrowser() {
       var suiteTable = document.getElementById("suiteTable");
       var skippedTests = document.getElementById("skippedTests");
       for(rowNum = suiteTable.rows.length - 1; rowNum >= 0; rowNum--)
       {
           var row = suiteTable.rows[rowNum];
           var filterString = row.getAttribute("unless");
           if (filterString && eval(filterString))
           {
             var cellHTML = row.cells[0].innerHTML;
             suiteTable.deleteRow(rowNum);
             var newRow = skippedTests.insertRow(1);
             var newCell = newRow.insertCell(0)
             newCell.innerHTML = cellHTML;
           }
       }
   }
   function isFileURL() {
       var p = window.location.protocol;
       var result = ("file:" == p);
       return result;
   }
</script>
</head>
<body onload="filterTestsForBrowser()">
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium">
        <tbody>
                <tr>
                        <td><b>Selenium : Test Suite</b></td>
                </tr>
                <tr>
                        <td><a target="testFrame" href="file:///chemin/des/tests/test1.html">Test 1</a></td>
                </tr>
                <tr>
                        <td><a target="testFrame" href="file:///chemin/des/tests/test2.html">Test 2</a></td>
                </tr>
        </tbody>
</table>
<br />
<em>Not supported in this suite</em>
<table id="skippedTests" cellpadding="1" cellspacing="1" border="1" class="selenium">
        <tbody>
                <tr>
                        <td><b>Skipped Tests</b></td>
                </tr>
        </tbody>
</table>
</body>
</html>

Le bloc qui nous intéresse particulièrement est :

                <tr>
                        <td><a target="testFrame" href="file:///chemin/des/tests/test1.html">Test 1</a></td>
                </tr>

A noter :

  • La référence au test se fait sous la forme d’un lien.
  • Le test doit avoir la référence target="TestFrame" pour qu’il puisse être lancé.
  • Il vous suffit d’ajouter autant de ligne dans votre tableau que vous avez de tests à intégrer dans votre Test Suite.

Executer une Test Suite depuis Selenium IDE

Vous pouvez lancer une Test Suite depuis Selenium IDE en utilisant Test Runner. Pour cela il vous suffit de cliquer sur l’icône suivante :

Selenium - TestRunner

Dans votre navigateur, une fenêtre s’est alors ouverte et elle est composée de 4 parties :

  • En haut à gauche, la zone contenant le détail de votre Test Suite
  • En haut au milieu : le contenu de votre cas de test
  • En haut à droite : le panneau de contrôle de Test Runner
  • En bas : un aperçu du site dans lequel est exécuté votre test.

Selenium - TestRunner 2

Pour que TestRunner prenne votre Test Suite en considération, il vous suffit de changer le contenu de la variable "test" dans l’url appelée. Une fois votre Test Suite chargée, il vous suffit de l’exécuter.

Exporter un test vers Selenium RC

Comme dit dans le précédent billet, un des intérêts de Selenium RC est de pouvoir exécuter des tests dans un langage de script. Ce langage permettant de réaliser des actions supplémentaires, impossibles à réaliser depuis Selenium IDE.

L’export se fait très simplement :

  • Fichier > Exporter le Test sous > Choisissez le format qui vous intéresse.
  • Sauver le fichier avec l’extension appropriée.

Optionel : vous aurez peut être besoin de modifier la valeur de la "base url" dans votre test. Par défaut, Selenium IDE considère que cela est "localhost", ce qui peut ne pas correspondre à votre environnement.

Ex pour un test exporté en python :

Avant :

self.selenium = selenium("localhost", 4444, "*iexplore", "http://localhost:4444")

Après :

self.selenium = selenium("localhost", 4444, "*iexplore", "http://test.server.tld")

Exécuter un test avec Selenium RC

Il vous faut d’un côté lancer le serveur Selenium RC :

java –jar c:\path\to\selenium-rc\selenium-server.jar

et de l’autre lancer votre fichier de test dans votre langage de script (ou de double-cliquer sur le fichier si votre système d’exploitation vous le permet) :

C:\path\to\your\language\language.exe c:\path\to\test\test_case.ext

Note : si votre test utilise les fonctions javascript définies dans user-extensions.js, il vous suffit d’ajouter le paramètre "–userExtensions c :\path\to\user-extensions.js" lors du lancement du serveur :

java –jar c:\path\to\selenium-rc\selenium-server.jar -userExtensions c:\path\to\user-extensions.js

Exécuter une Test Suite avec Selenium RC

Pour se faire, il vous suffit le serveur en utilisant le paramètre htmlSuite et de préciser :

  • le navigateur à utiliser parmi *chrome (firefox) et *iehta (Internet Explorer)
  • l’url à tester,
  • le chemin de votre Test Suite
  • le chemin où stocker les résultats de la Test Suite :
java –jar c:\path\to\selenium-rc\selenium-server.jar –htmlSuite *iehta http://your.server.tld c:\path\to\test\suite\YourTestSuite.html c:\path\to
esults.html

De la même façon que précédemment, si vous devez utilser vos fonctions javascript, il faut ajouter le paramètre userExtensions :

java –jar c:\path\to\selenium-rc\selenium-server.jar –htmlSuite *iehta http://your.server.tld c:\path\to\test\suite\YourTestSuite.html c:\path\to
esults.html -userExtensions c:\path\to\user-extensions.js

Exécuter des tests en parallèle avec Selenium RC

Il suffit de :

  • lancer autant d’instances de Selenium RC que nécessaire sur différents ports (en utilisant le paramètre "–port"
  • Adapter vos scripts pour qu’ils utilisent le port en question au lieu du port par défaut (4444)‏
  • Exécuter les scripts.

selectAndWait vs select

Dans le cas de formulaire avec des listes déroulantes conditionnelles, il se peut que votre test échoue si vous cherchez à selectionner la valeur par défaut d’une liste rafraichie par la liste précédente.

Cela s’explique par le fait que Selenium enregistre votre selection via la commande "SelectAndWait". Comme vous sélectionnez la valeur par défaut d’une liste, Selenium ne voit pas cet événement et attend en vain.

L’astuce consiste alors à remplacer "selectAndWait" par "select".

Ressources

Selenium IDE

Selenium RC

Nous arrivons au terme de ce second épisode sur Selenium. Le but était d’illustrer son fonctionnement au travers de différents exemples. Toutes les fonctionnalités de l’outil n’ont pas été présentées ici (exécution d’un test pas à pas, définition de nouveaux point de démarrage d’un test, etc), l’idée étant de faire avant tout une présentation rapide de l’outil. Il ne vous reste plus qu’à jouer avec pour mieux l’appréhender.

ul, li et les listes imbriquées

Dans la série, "Même pas honte" et "Je me coucherais moins bête ce soir", je vous présente Nicolas et les listes imbriquées...

Jusqu'à présent, pouvoir avoir une liste du type :

  • Liste Niveau 1
    • Liste Niveau 2
  • Liste Niveau 1

J'écrivais en HTML depuis de nombreuses années :

<ul>
    <li>Liste Niveau 1</li>
    <ul>
        <li>Liste Niveau 2</li>
    </ul>
    <li>Liste Niveau 1</li>
</ul>

Cela avait le mérite de marcher mais le validateur n'aimait pas.

Et là, ce soir, paf la révélation grâce à l'extension HTML Validator.

<ul>
    <li>Liste Niveau 1</li>
    <li>
        <ul>
            <li>Liste Niveau 2</li>
        </ul>
    </li>
    <li>Liste Niveau 1</li>
</ul>

Quand on y pense, c'est évident (et encore plus quand on imagine un arbre / des noeuds XML) mais jusque là, cela n'avait pas fait tilt...

Je vais me coucher moins bête ce soir et mon squelette valide au regard de XHTML 1.0 Strict... ;-)

MvMo 0.3 - "I hate microbs"

Nouvelle version de MvMo, mon application de gestion de cv multi-utilisateurs basée sur Django.

Au programme des réjouissances :

  • Le projet est hébergé dans mon chaudron et non plus sur Google Code (trop lent, ergonomie à discuter, je préfère mercurial à subversion, etc).
  • Internationalisation de l'application (en/fr pour le moment)
  • Passage en unicode (requiert de passer sur la version de développement de Django)
  • Correction des bugs connus en 0.2

Pour ceux qui ne veulent pas sortir d'une version stable, dans models.py, il suffit de remplacer tous les :

__unicode__(self)

par :

__str__(self)

Au programme de la 0.4 :

  • Ajout des microformats hCard et hResume
  • Réorganisation des répertoires pour simplifier l'installation de l'application (en se basant sur tous les bons conseils de James Bennett et Malcolm Tredinnick pendant le mois de novembre...)

Selenium : testez fonctionnellement vos applications web (partie 1/2)

Billet publié originellement sur le blog de Clever Age : selenium, testez fonctionnellement vos applications web (partie 1/2)

Ce premier billet a pour objectif de présenter Selenium et ses fonctionnalités. Le second sera d’avantage axé sur son implémentation et utilisation.

Vous avez dit Selenium ?

Selenium est une suite d’outils permettant de faire des tests fonctionnels d’une application web (et uniquement web). Ces outils sont distribués par OpenQA, sous la licence libre Apache 2.0.

Par outil de test fonctionnel d’une application web, j’entends :

  • La capacité à simuler l’action d’un internaute avec prise en charge des actions réalisées avec le clavier et la souris (click, saisie d’un champ, sélection dans une liste déroulante, etc),
  • Les simulations sont bien sûr basées sur des cas de tests, basés eux-mêmes sur des cas d’utilisation,
  • La capacité à enregistrer ces simulations,
  • La capacité à exécuter ces simulations de façon automatisée de manière individuelle ou collective (on parlera alors de Test Suite).

Selenium est composé de 3 éléments :

  • Selenium Core : coeur de Selenium. Le core doit être installé sur le serveur sur lequel tourne votre application pour pouvoir les tester,
  • Selenium IDE : extension Firefox capable d’enregistrer et d’exécuter des tests et des Test Suites (via TestRunner, composant de l’IDE capable de jouer des Test Suite),
  • Selenium Remote Control :
    • Serveur qui permet d’exécuter des tests sur différents navigateurs (firefox, internet explorer, opera, etc) et différents systèmes d’exploitation (MS Windows, GNU/Linux, Mac OS)
    • Serveur qui permet d’exécuter des Test Suites sur ces différents navigateurs,
    • Serveur qui permet d’exécuter des tests écrit dans des languages de script comme Ruby, Python, Java, .Net et Perl.

Contrairement à Selenium Core, Selenium RC et Selenium IDE s’installent sur le poste du développeur. Selenium RC peut aussi s’installer sur un serveur dédié à l’exécution des tests si l’on souhaite les exécuter de façon automatisée.

Petit aperçu d’un test enregistré dans Selenium IDE :

selenium.png

Le test consiste à :

  • Ouvrir la page Google.fr,
  • Taper le mot clé "clever age"
  • Cliquer sur "Rechercher’
  • Cliquer sur le lien "Clever Age, conseil en architecture technique"
  • Sur le site de Clever Age, vérifier la présence du texte "systèmes informatiques flexibles").

Avant d’aller plus loin, Selenium n’est pas fait pour :

  • Tester des applications non-web : client lourd, service web, etc.
  • Faire des tests de performance.

Et pour être totalement honnête, Selenium :

  • A quelques soucis avec les sites en Ajax ou avec beaucoup de JavaScript.
    • Il convient alors de vérifier la qualité du code javascript développé.
    • et si cela ne suffit pas et pour que le test se déroule correctement, il arrive de devoir entrer des commandes équivalentes à ce qui aurait du être fait en javascript (ouverture d’une page, saisie d’une valeur, etc)
  • Ne sait pas gérer plusieurs fenêtres d’un navigateur :
    • Selenium sait ouvrir une pop-up,
    • Selenium ne peut piloter deux fenêtres lancées indépendemment l’une de l’autre,
    • En travaillant un peu le contenu du test enregistré et si la seconde fenêtre est ouverte depuis la première (cas d’une pop-up par exemple), alors il est possible de les contrôler simultanément.

Dois-je utiliser Selenium ?

Les utilisateurs de Selenium ont le profil suivant (liste non exhaustive) :

  • Analyste programmeur : pour vérifier que les développements sont conformes aux besoins exprimés
  • Développeur et équipe d’assurance qualité : pour valider le bon fonctionnement de l’application (non-regression, etc) et le passage en production.

Comment intégrer Selenium dans votre campagne de test ?

Sauf à vouloir perdre du temps, il convient de procéder de la façon suivante :

  1. Lecture des besoins & spécifications,
  2. Définition du périmètre de test,
  3. Rédaction des cas de tests,
  4. Enregistrement des tests dans Selenium,
  5. Exécution des tests.

Ce test doit-il être un test Selenium ?

La réponse est oui, si :

  • le test doit être joué plus d’une fois,
  • le test peut être automatisé de bout en bout.

A quoi sert une Test Suite ?

Nous pouvons voir les Test Suites de deux façons :

  • Un ensemble de tests individuels que nous voulons jouer à chaque nouvelle version d’un projet. Chaque test correspond à un cas d’utilisation et permet de valider le bon fonctionnement de l’application dans son ensemble.
  • Un ensemble de composants qui seront utilisés pour construire un test.. Ces composants pourront être mutualisés entre les différents tests. Prenons un exemple : le test d’une application est souvent composé de trois étapes : connection à l’application, action à mener puis déconnexion de l’application. Je vais donc créer trois tests :
    • Un test "connexion" : sa portée se limite à aller sur l’écran d’authentification de l’application, saisir les identifiants et se connecter.
    • Un test "action" : le coeur du test, il contient la fonctionnalité à tester dans notre scénario
    • Un test "déconnexion", consiste à cliquer sur le lien "Déconnexion" et vérifier que cela est bien le cas.

Petite illustration : imaginons que notre application porte sur la gestion des congés.

selenium2.png

Dans le premier cas, ma Test Suite est composée de trois cas de test. Chaque test couvre l’ensemble du processus à tester.

Dans le second cas, chaque composant est une portion du process complet. Le "Test 1" pourrait tout à fait être représenté par ce second cas.

Comment s’intègre Selenium dans un processus d’intégration continue ?

Il "suffit" de s’appuyer sur la capacité de Selenium à exporter les tests enregistrés dans Selenium IDE dans un des formats supportés par Selenium RC et adapté à votre outil d’intégration continue.

Une fois exporté et intégré à votre outil, lors d’un commit, une tâche est lancée qui consiste à :

  • Lancer une instance du serveur Selenium RC
  • Lancer votre test qui se connectera à l’instance du Selenium RC et jouera le test.
  • Récupérer le fichier de log produit par Selenium RC
  • Traiter le fichier de log.

Vous pourriez objecter qu’il est possible de lancer Selenium RC avec un test au format HTML. Certes mais dans la mesure où vous allez vouloir probablement réinitialiser votre application suite à votre test, vous serez contraint de passer par un langage de script.

Nous arrivons au terme de ce premier billet qui avait pour objectif de planter le décor sur Selenium, ses capacités et son fonctionnement. Le prochain billet consistera à rentrer dans le vif du sujet et montrer comment Selenium IDE et Selenium RC peuvent être utilisés.

MvMo 0.2

MvMo, mon application de gestion de CV sort du four en version 0.2

Au programme :

  • Corrections de bugs (à l'exception de deux petits bugs d'affichage - corrigé en version svn)
  • Passage en anglais de tous les champs, labels, etc avant d'envisager de devenir i18n compliant
  • Amélioration de la documentation des vues & modèles principalement
  • Mise à disposition d'un fichier de fixture

Au programme de la 0.3 :

  • Devenir i18n compliant
  • Correction de bug & améliorations diverses

Liens utiles :

Edit du soir : les bugs d'affichages sont résolus en svn

MvMo 0.1

Je vous l'annonçais en avril, mon application de gestion de cv en ligne (et multi-utilisateurs s'il vous plait) est enfin en ligne dans sa version 0.1

MvMo (pour Ma Vie Mon Oeuvre) permet de gérer des cv avec les aspects suivants :

  • Profil
  • Résumé
  • Entreprises & expériences associées
  • Compétences (avec niveau et sens de progression)
  • Formation
  • Langue(s) parlée(s)
  • Centres d'intérêts
  • Expériences associatives
  • Contact(s)
  • Pièce(s) jointe(s)

Voilà ci-après un petit aperçu (oui, j'avoue, en faisant le ménage, l'import sur Google Code et le mix mercurial/subversion, j'en ai perdu mon instance et mon fichier de fixture. La démo en ligne attendra donc un peu...)

MvMo 0.1

Voir en plus grand

Pour le code et tout le reste, c'est là : http://code.google.com/p/mvmo

PS : oui, je reconnais m'être fortement inspiré du modèle de cv de Clever Age et de Niko (pour la partie compétences - et oui je lui ai aussi "piqué" les flèches et étoiles)

Edit du 1/10 midi : Un début d'instructions d'installation sont en ligne pour les plus téméraires et l'issue #1 est corrigée :-)

Getting real : impressions générales...

Après que le buzz soit passé et comme David remettait ça sur le tapis, je me suis dit qu'il fallait que je me mettre à lire Getting Real. J'avais lu le chapitre "There is nothing functionnal about a functionnal spec", qui m'avait fait sourire. Cela pouvait en effet être adapté à certains cas mais dans le cas de gros projets, de telles assertions me laissaient (et me laissent toujours sceptique).

Bref, je me suis dit, autant ne pas mourir idiot, autant lire le bouquin en entier pour m'en faire une vraie idée. J'ai donc acheté la version PDF que j'ai lu entre hier matin et ce matin en allant et revenant du travail (c'est dire si les 177 pages se lisent bien ;-) ).

Arrête de causer et viens en au fait me direz-vous... ok ok, j'y arrive !

Comme marqué dans le titre, ce sont des impressions générales, pour une revue détaillée, il faudra attendre un peu !

Donc globalement :

  • le bouquin est sympa à lire, contient de bonnes idées (pas forcément nouvelles, on retrouve des principes présents dans beaucoup de méthodes (KISS, XP, etc) ou seulement pleines de bon sens)
  • tout ça, c'est valable chez 37signals, il est possible de reproduire une partie de leur règles de conduites mais pour toutes les reproduires, les assertions deviennent très fortes. Comme ils le disent eux même, ça marche chez nous, ça peut ne pas marcher chez vous ou pas totalement. Comme toute méthode, il faut adapter à son propre cas,
  • J'ai vu pas mal de bonnes idées pour mes projets perso, voir même pro,
  • Certaines erreurs pointées du doigt m'ont fait penser à certains (moments de) projets ou missions ou lorsque je vois des clients repondre des méthodologies internes avec des documents de 30 pages mini (quand il est vide) pour chaque phase du projet et un reporting de dingue. Je vois mal un chef de projet faire 80% de reporting et 20% de gestion de projet.
  • Certaines de leurs règles sont valables pour des projets simples ou de petites tailles, voir uniquement pour des projets réalisés en interne. Par contre, je vois mal dire à un client : bon ben finalement pour le prix et le délai qu'on a, on ne développe que 50% du périmètre. Pour un engagement au forfait, c'est pas adapté par ex !

Bref, je pense que tout développeur ou chef de projet devrait lire le livre s'il en a l'occasion. Par contre, comme tout livre de méthodologie, il faut savoir l'adapter à son cas et ne pas se lancer dans une application stricte sous peine d'échec assuré à mon humble avis.

Pour ceux qui l'ont lu, qu'en avez-vous pensé ?

Pour la version commentée en détail, faudra attendre un peu ;-)

- page 1 de 6