Mon ancien site est accessible à l'adresse suivante : http://old.harobed.org. En savoir plus…

Mon bilan de Agile Open France 2012

La forme, le principe

Contrairement aux manifestations, type conférences comme PyCon, RMLL, Fosdem, l'Agile Open France est du type Méthodologie open space (pas les bureaux ouverts !) ou Barcamp.

Je vous invite à lire l'article Wikipedia Méthodologie open space car il correspond très bien à ce que j'ai vécu.

Voici un extrait :

Selon Harrison Owen1, le succès d'un Open Space repose sur le respect d'une loi, étayée par quatre principes. Pendant le rituel d'ouverture, ces éléments sont cités et expliqués aux participants.

Les quatre principes :

  • Les personnes qui se présentent, sont les bonnes ;
  • Ce qui arrive,est la seule chose qui pouvait arriver ;
  • Ça commence quand ça commence ;
  • Quand c’est fini, c’est fini.

La loi des deux pieds : Si vous n’êtes en train ni d’apprendre, ni de contribuer, passez à autre chose !

Dans l'open space auquel j'ai participé, deux éléments supplémentaires ont été ajouté lors du rituel d'ouverture :

  • « Être un bourdon, ce n'est pas sale ! » : ce n'est pas grave si l'on passe d'un groupe à l'autre… on peut partir d'une discussion (suivre la loi des deux pieds), on peut s'insérer dans une discussion sans problème
  • « Être un papillon, ce n'est pas sale ! » : si on n'est perdu… ce n'est pas grave… attention toutefois à ne pas tuer les papillons :)

Si vous souhaitez encore approfondir le sujet, je vous invite à lire le Guide utilisateur des Forums Ouverts .

Le lieu

L'hôtel Arnold était entièrement réservé pour l'Agile Open France 2012… le cadre était vraiment très pratique.

L'hôtel était vraiment très bien, très beau, les chambres spacieuses, les repas étaient très bons, les employés de l'hôtel étaient vraiment très agréables…

Des petits salons très confortables, fauteuils, canapés, open bar, équipé de tableaux, de rétroprojecteurs…

Vraiment, le cadre était parfait.

Les principaux sujets auxquels j'ai participé

De mémoire, j'ai participé aux sujets suivants (les titres ne sont sans doute pas exacts, l'ordre est arbitraire) :

  • Les Farfadet du génie logiciel
  • Le service Heroku : discussions et retours d'expériences
  • Le langage Erlang : discussions, retours d'expériences, initiation
  • Le langage Ruby discussions, comparaisons Python/Ruby, retour d'expériences
  • J'ai assisté rapidement à une petite session Node.js
  • J'ai été acteur dans une session à propos de Bernard Stiegler et de Michel Serres
  • J'ai participé à la session « Pourquoi mon éditeur texte il déchire »
  • J'ai participé à la session « Pourquoi j'aime mon langage »
  • J'ai été acteur dans une session « Open Money, devises numériques » : Bitcoin, Théorie Relative de la Monnaie 2.0
  • J'ai vécu une belle expérience lors d'une session/expérience sur le « Dialogue »… : très enrichissant… et j'ai constaté que j'étais vraiment entouré de personnes très intelligentes (ou à l'écoute… en éveil… je n'arrive pas à trouver le bon mot) ou alors c'est le contexte qui fait progresser tout le monde… je ne sais pas…
  • Discussions à propos du déploiment d'applications web Python, j'ai découvert entre autre l'outil Fabtools (développé par Ronan Amicel) basé sur Fabric
  • Discussions à propos des technologies NoSQL, retours d'expériences de MongoDB, CouchDB
  • Discussions à propos des Fablab, imprimantes 3D et ce que cela peut changer dans la société
  • Discussions à propos de « Pourquoi les sites des technos Ruby sont beaux, plus beaux que les outils Python » (je ne parle pas des réalisations faites avec ces outils, mais les sites web de ces outils, le coté marketing de Ruby qui est très bien réussi)
  • Discussions à propos de la réalisation d'applications mobiles : native vs html vs autre outils
  • J'ai assisté à une discussion au sujet de « Mon designer : un équipier agile »
  • Discussions à propos de Pylons, Pyramid, framework avec et sans opinions, j'y ai découvert le projet Ptah surcouche de Pyramid avec des opinions.
  • Discussions à propos de The Twelve-Factor App
  • Discussions à propos de « Comment vendre de l'agile ? »
  • Discussions à propos de « Est-ce que passé une taille critique, une startup doit se structurer, comme par exemple mettre en place des entretiens individuels annuels d'évaluation ? »
  • Discussions à propos de « Est-ce qu'il faut encore développer ses applications vs utiliser des outils clés en main ? »
  • Discussions à propos de « Comment répondre à des offres, est-ce qu'il faut répondre à des offres, comment répondre à un cahier des charges… ». J'ai adoré cette discussion, avec des retours d'expériences, exploration de pistes…
  • Discussions à propos de « Comment travailler en équipe quand les membres ont des compétences différentes, utilisent des technologies différentes ? »

À savoir, que parallèlement à ces sujets, il y en avait toujours trois, quatre ou même cinq autres.

Mon bilan

De toutes les manifestations que j'ai fait, c'est la meilleur, c'est là où j'ai appris le plus de choses en si peu de temps… et encore je n'ai pas pu assisté à toutes les discussions, toutes les sessions…

Je ne pense pas avoir passé dans ma vie, 48h aussi riches !

Vraiment le format Open Space est vraiment très bien pour échanger des expériences… philosopher…
De plus ce format permet de rendre tout de monde accessible… pas de pudeur… il est possible de parler avec vraiment tout le monde.
Read and Post Comments

Screencast de présentation de Tacot

J'ai créé un screencast de présentation de Tacot.

J'ai plus ou moins suivi le contenu de la documentation… Dans la vidéo j'ai fait quelques erreurs d'expression alors soyez indulgents… ce n'est pas facile de faire un screencast valide du premier coup.

Je vous conseille de visualiser la vidéo en mode 720p afin de bien pouvoir lire le contenu de la console. Après la réalisation du screencast je me suis rendu compte que j'aurais dû agrandir la taille des polices.

Lien vers la documentation de Tacot.

Read and Post Comments

Idée d'une librairie basée sur Selenium pour tester des formulaires web

Introduction

Je viens de commencer à utiliser Selenium pour tester des formulaires, divers pages de listes de données… dans une application métier.

Mes objectifs :

  • tester l'ajout de nouvelles entités (1)
    • les données sont injectées dans un formulaire d'une page html
    • une page de résultat est utilisées pour vérifier que les données ont bien été enregistré (ça peut être une page d'édition)
  • tester la modification d'une entités (2)
    • les données sont injectées dans un formulaire d'une page html
    • une page de résultat est utilisées pour vérifier que les données ont bien été enregistré (ça peut être une page d'édition)
  • tester la validité d'une page de liste (3)
  • tester la validité des résultats d'un moteur de recherche (4)

Pour le moment je me suis concentré uniquement sur les points 1 et 2.

Première méthode (à l'arrache)

J'ai commencé par réaliser des fonctions du type :

  • login()
  • add_customer(data)
  • edit_customer(data)
  • check_customer(data)
  • add_customer(data)
  • edit_customer(data)
  • check_customer(data)

Les fonctions de type "add" et "edit" prennent en paramètre des données à injecter dans des pages. Les fonctions de type "add" correspondent aux pages d'ajout d'entités, les fonctions de type "edit" correspondent aux pages de modification d'entités.

Ensuite j'ai des fonctions "check", là aussi je passe en paramètre des données qui seront utilisées comme valeur de vérification face à des pages de résultats ou pages d'éditions (une page d'édition contient déjà des données, le but ici est de vérifier leurs validitées).

Ma variable "data" est du type :

data = [
    ("reference", u"C1345"),
    ("firstname", u"Stéphane),
    ("lastname", u"Klein"),
    ...
]

Dans mes fonctions ("add", "check"…) j'ai une boucle qui parcourt la structure de données et utilise les fonctions suivantes soit pour injecter des données, soit pour tester la validité des données.

def inject_value(driver, name, value):
    element = driver.find_element_by_id(name)
    if element.tag_name == 'input':
        if element.get_attribute("type") == "checkbox":
            if element.is_enabled() != value:
                element.click()
        else:
            element.clear()
            element.send_keys(value)

    elif element.tag_name == 'select':
        option_element = element.find_element_by_xpath(".//option[@value='%s']" % value)
        option_element.click()

    elif element.tag_name == 'textarea':
        element.clear()
        element.send_keys(value)

def check_value(driver, name, value):
    element = driver.find_element_by_id(name)
    if element.tag_name == 'input':
        if element.get_attribute("type") == "checkbox":
            return element.is_enabled() == value
        else:
            return element.get_attribute("value") == value

    elif element.tag_name == 'select':
        return element.get_attribute("value") == value

    elif element.tag_name == 'textarea':
        return element.text == value

Pour le moment, cela fonctionne correctement mais je trouve mon code fastidieux pour plusieurs raisons :

  • j'aimerais pouvoir définir des valeurs par défaut pour les formulaires
  • j'aimerais pouvoir choisir d'autres types de "selecteur", pour le moment je fais des recherches uniquement par ID
  • j'aimerais pouvoir facilement indiquer le type de champ, car pour le moment je fais de l'auto détection… mais cela ne sera pas toujours faisable

Ce que j'aimerais avoir

À noter que ce code n'est pas complet… c'est un brouillon.

from sealchemy import Form, TextField, SelectField, BooleanField

...

class AddCustomer(Form):
    __submit__ = Submit(name="_same")

    reference = TextField(default=u"C1345")
    type_user = SelectField(default=u"external")
    firstname = TextField(required=True)
    lastname = TextField(required=True)
    activated = BooleanField(default=True)
    comment = TextAreaField(default=u"")

    def go_to_page(self):
        self.driver.get("/customers/add/")

class EditCustomer(Form):
    __submit__ = Submit(name="_same")

    reference = TextField(default=u"C1345")
    type_user = SelectField(default=u"external")
    firstname = TextField(required=True)
    lastname = TextField(required=True)
    activated = BooleanField(default=True)
    comment = TextAreaField(default=u"")

    def go_to_page(self, id):
        self.driver.get("/customers/%s/" % id)

    def go_to_last_inserted(self):
        """Va sur la page du dernier client qui a été ajouté"""
        ...

Cela ressemble beaucoup à l'API de wtforms que j'utilise dans mon projet. Cela ressemble aussi à FormAlchemy que j'aime aussi.

__submit__ permet d'indiquer le champ à utiliser par la commande submit.

Note : je n'utilise pas une seule classe pour faire mes traitements "add" et "edit" car les formulaires d'ajouts et d'édition sont en pratique souvent différents.

L'interface de la classe de type Form :

class IForm(zope.interface.Interface):
    def inject():
        """Cette méthode injecte les données vers le formulaire HTML"""

    def submit():
        """Cette méthode lance le submit du formulaire"""

    def inject_and_submit():
        """Exécute inject et ensuite submit"""

    def check():
        """Cette méthode retourne True si les données correspondent aux
           données présentes dans le formulaire HTML"""

    def clear():
        """Réinitialise la valeur de tous les champs de l'instance avec
           les valeurs par défauts"""

    def populate(values):
        """Affecte des valeurs aux champs de l'objet."""

La classe Session de mon projet :

class MyProject(Session):
    def __init__(self, login, password):
        ...

    def login(self):
        ...

    add_customer = AddCustomer()
    edit_customer = EditCustomer()

Dans MyProject, j'ai ajouté les propriétés add_customer et edit_customer afin que ces objets aient accès à l'objet driver de Selenium.

Exemple d'utilisation :

session = MyProject(login="username", password="password", url="http://localhost:5000/")
session.login()

values = {
    "reference": u"C1871",
    "firstname": u"Stéphane",
    "lastname": u"Klein",
}
session.add_customer.populate(values)
session.add_customer.go_to_page()
session.add_customer.inject_and_submit()
session.edit_customer.go_to_last_inserted()
session.edit_customer.populate(values)
assert session.edit_customer.check()

Plus d'informations à propos des classes Field

Les classes de type Field comme TextField, BooleanField … ont un constructeur avec plusieurs paramètres :

  • name (optionnel) : définit la méthode de recherche du champ par l'attribut "name"
  • id (optionnel) : définit la méthode de recherche du champ par l'attirbut "id"
  • xpath (optionnel) : définit la méthode de recherche via xpath
  • required (optionnel) : définit si le champ est requis ou non
  • default (optionnel) : définit la valeur par défaut du champ

Par défaut, si j'ai ceci :

class ...(Form):
    firstname = TextField()

C'est équivalent à cela :

class ...(Form):
    firstname = TextField(name="firstname")

Conclusion, questions

Je vous ai donc présenté l'API que j'imagine créer sous le nom de "sealchemy".

J'ai plusieurs questions :

  • est-ce que vous pensez que cette librairie serait utile ?
  • est-ce que l'API, le mode de fonctionnement est judicieux ?
  • est-ce que cela vous intéresse ?
  • est-ce que vous avez déjà créé quelque chose du même genre ?
  • quelle est votre méthode pour faire ce genre de test ?

Merci d'avance pour vos commentaires.

Read and Post Comments

Quelques notes en vrac

Liste des applications / outils que j'utilise

Il y a quelques semaines, sur mon site, j'ai créé une nouvelle page qui s'intitule « Liste des applications / outils que j'utilise ».

Quelles sont les motivations qui m'ont poussé à réaliser cette page ?

  • je trouve intéressant de savoir quels sont les outils que X ou Y utilise au quotidien… on y découvre souvent des choses intéressantes (donc n'hésitez pas à réaliser ce type de page). Un site qui a le même esprit est « Ils utilisent ça ».
  • il arrive que l'on me demande quelle librairie j'ai choisi pour réaliser telle ou telle tâche
  • parfois, je ne sais plus quelle librairie javascript j'ai choisi pour réaliser une tâche, dans ce cas cette page me sert de "pense-bête"

Dans le même esprit, j'ai commencé la page « Liste des applications Android que j'utilise » mais pour le moment elle n'est pas très étendue.

virtualenvwrapper

Depuis 3 semaines, j'utilise de plus en plus régulièrement virtualenvwrapper.

Cet outil est vraiment très pratique. Un petit résumé rapide d'utilisation (mais je vous conseille fortement de lire la documentation pour en savoir plus sur les divers fonctionnalités de l'outil, comment l'installer…) :

Je crée le dossier qui contiendra mon projet :

$ mkdir ~/projets/mon_projet/

Je crée un nouvel environement qui porte le même nom que mon projet :

$ mkvirtualenv mon_projet
New python executable in mon_projet/bin/python
Installing setuptools............done.
virtualenvwrapper.user_scripts creating /home/harobed/.virtualenvs/mon_projet/bin/predeactivate
virtualenvwrapper.user_scripts creating /home/harobed/.virtualenvs/mon_projet/bin/postdeactivate
virtualenvwrapper.user_scripts creating /home/harobed/.virtualenvs/mon_projet/bin/preactivate
virtualenvwrapper.user_scripts creating /home/harobed/.virtualenvs/mon_projet/bin/postactivate
virtualenvwrapper.user_scripts creating /home/harobed/.virtualenvs/mon_projet/bin/get_env_details

Quand j'active l'environement mon_projet je souhaite être déplacé directement dans le dossier ~/projets/mon_projet :

$ echo "cd ~/projets/mon_projet" >> /home/harobed/.virtualenvs/mon_projet/bin/postactivate

J'active l'environement mon_projet :

$ workon mon_projet
(mon_projet)$ pwd
/home/harobed/projets/mon_projet

À noter que les commandes fournies par virtualenvwrapper supportent pour la plupart l'auto complétion, par exemple workon <tab> affiche les environements disponibles sur votre système.

Consultez la documentation de virtualenvwrapper pour en savoir plus.

Mozilla Sync

Depuis que je suis passé à Firefox 4, j'utilise Firefox Sync pour centraliser mes bookmarks.

Avant cela, j'utilisais avec plaisir delicious mais l'extension delicious pour Firefox 4 n'est pas disponible.

En tout les cas, Firefox Sync fonctionne vraiment très bien, c'est très facile à configurer, c'est totalement transparent à l'usage… un très beau travail, réalisé entre autre par Tarek Ziade pour la partie serveur (codé en Python).

Read and Post Comments

jquery.expandBox plugin

Je viens de publier une nouvelle version (0.2.0) du plugin jquery.expandBox.

« Et ça sert à quoi ? » et bien à étendre des elements HTML dans une page.

Exemples :

$('#bloc2').expandBoxVertically();
+-----------+                              +-----------+
|   bloc 1  |                              |   bloc 1  |
+-----------+                              +-----------+
|   bloc 2  |                              |           |
+-----------+                              |           |
|           |                              |   bloc 2  |
|     du    |  => étendre le "bloc 2" =>   |           |
|    vide   |                              |           |
|           |                              |           |
+-----------+                              +-----------+
|   bloc 3  |                              |   bloc 3  |
+-----------+                              +-----------+
$('#bloc2, #bloc3').expandBoxHorizontally();
+--------+--------+--------+----------------+
|        |        |        |                |
| bloc 1 | bloc 2 | bloc 3 |     du vide    |
|        |        |        |                |
+--------+--------+--------+----------------+

                      |
                      v

             étendre les blocs 2 et 3

                      |
                      v

+--------+-----------------+----------------+
|        |                 |                |
| bloc 1 |      bloc 2     |     bloc 3     |
|        |                 |                |
+--------+-----------------+----------------+

Pour en savoir plus sur les fonctionnalités de jquery.expandBox plugin, comment l'utiliser, où le télécharger… je vous conseille de vous rendre sur la page du projet….

Il y a 8 mois, au moment où j'ai réalisé ce plugin, j'ai cherché si ce type de plugin existait déjà.
Je n'ai rien trouvé (j'ai peut être mal cherché).

La fonctionnalité « The flexible box model » de la norme CSS 3 permet d'étendre des blocs d'une manière plus élégante que le plugin jquery.expandBox mais cette fonctionnalité n'est pas encore disponible pour tous les navigateurs.

J'espère que la documentation est compréhensible et que ce plugin vous sera utile.

Si vous avez des remarques, suggestions… n'hésitez pas à m'envoyer un mail à stephane@harobed.org

Read and Post Comments

Billets plus anciens »

Consultez mes archives pour avoir une vue d'ensemble de mes anciens billets.