« Billets plus récentsBillets plus anciens »

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

Pyramid est framework extensible mais pas directement Pluggable car il est sans opinion

Voici un billet important concernant Pyramid et la différence entre « extensibility » et « pluggability » : Chris McDonough on pluggable apps.

Ce billet fait référence à un mail de Chris McDonough.

Voici quelques extraits de ce mail :

Pyramid doesn't provide enough "rails" to make it possible to integrate truly honest-to-god, download-an-app-from-a-random-place and-plug-it-in-to-create-a-system "pluggable" applications.
Because Pyramid itself isn't opinionated (it doesn't mandate a particular kind of database, it offers multiple ways to map URLs to code, etc), it's unlikely that someone who creates something "application-like" will be able to casually redistribute it to J. Random Pyramid User and have it "just work" by asking him to config.include a function from the package.
This is particularly true of very high level components such as blogs, wikis, twitter clones, commenting systems, etc.
The "integrator" (the Pyramid developer who has downloaded a package advertised as a "pluggable app") will almost certainly have made different choices about e.g. what type of persistence system he's using, and for the integrator to appease the requirements of the "pluggable application", he may be required to set up a different database, make changes to his own code to prevent his application from "shadowing" the pluggable app (or vice versa), and any other number of arbitrary changes.
  • D'un point de vue technique, Pyramid est un framework sans opinion :
  • Au niveau "fonctionnel" aussi Pyramid est sans opinion :
    • choisissez les urls que vous voulez
    • choisissez les modèles de template que vous voulez
    • choisissez les principes de fonctionnement de votre application comme vous voulez…

Pour toutes ces raisons, le framework Pyramid n'est pas directement "Pluggable".

For this reason, we claim that Pyramid has "extensible" applications, not pluggable applications.

Pyramid permet de réaliser des applications extensibles mais le framework n'est pas en lui même "Pluggable".

Dans cet extrait, on a l'impression que Pyramid ne permet pas de créer des applications "Pluggable", mais cela ne correpond pas à ce qu'explique le mail (il faut lire la suite du mail).

Autre extrait :

Any Pyramid application can be extended without forking it as long as its configuration statements have been composed into things that can be pulled in via "config.include".

Dit autrement : les outils fournis par Pyramid permettent de réaliser des applications extensibles, elles peuvent être fortement modifié sans avoir besoin de les forker.

Bien souvent, même dans des applications biens développées en programmation orienté objet, il est nécessaire de modifier une classe A utilisée par une autres classes B. Pour que la classe B utilise votre nouvelle classe A, vous êtes obligé d'effectuer des changements dans le code source de l'application… par conséquent vous êtes obligé de forker.

Grâce à la Zope Component Architecture (ZCA) vous pouvez effectuer cette modification sans modifier le code source de l'application, il suffit de lui dire d'utiliser une autre classe via le système de configuration de la ZCA.

Autre extrait :

Truly pluggable applications need to be created at a much higher level than a web framework, I fear, as no web framework can offer enough constraints to really make them "work out of the box".

En effet, il est possible (sera possible) de trouver des plugins pour des applications (basées sur le framework Pyramid ) et non pas directement des plugins basés sur le framework Pyramid .

Les applications devront faire des choix / avoir des opinions (template, couches modèles…), cela permettra la mise à disposition de plugins facilement installables.

D'un point de vu personnel, c'est ce type de choix que j'ai fait au sein de la société IS-Webdesign où je travaille. Pour pouvoir réaliser une application facilement extensible et mettre en place un système de plugins, j'ai choisi le framework Pyramid (avant cela Repoze BFG ).

Autre extrait :

It would be a noble goal to build an application with Pyramid that provides these constraints and which truly does offer a way to plug in applications (Joomla, Plone, Drupal come to mind).

Intéressant, je suis curieux de voir quand va apparaitre la première application de ce type. À noter que j'ai déjà vu des mails à propos de ce type de projet sur la mailing list de Repoze (mais je ne sais plus où).

C'est à ce niveau qu'intervient l'équipe du TurboGears qui a décidé aussi de rejoindre le mouvement Pylons… et plus particulièrement Pyramid. Le but de TurboGears est justement d'avoir des "opinions" et par conséquent de permettre la mise à disposition de plugins.

Read and Post Comments

Solution simple d'hébergement d'application web Python ?

Je rêve de quelque chose comme Heroku.

Qu'est ce que « Heroku » ?

C'est une solution rapide de déploiement d'applications webs basées sur le langage Ruby et plus précisément Ruby On Rails.

Voici un extrait de la présentation visible sur la page d'accueil du projet.

  1. Création d'une instance sur le serveur d'hébergement :

    $ sudo gem install heroku
    $ heroku create sushi
    Created http://sushi.heroku.com/
    git@heroku.com:sushi.git
    
    L'instance est créée sur le serveur, c'est ultra simple non ?
    Une seule commande pour faire cela : heroku create sushi.
  2. Déploiement de votre application (le tout basé sur git) :

    $ git push heroku master
    -----> Heroku receiving push
    -----> Rails app detected
    -----> Launching..... done
           http://sushi.heroku.com deployed
    

    Un simple push permet de mettre à jour votre site web.

  3. Autres commandes de configuration :

    $ heroku sharing: add fugu@sushi.com
    $ heroku domains: add sushi.com
    $ heroku rake db:migrate
    $ heroku db:push
    $ heroku addons:add memcahed
    

    Ici l'on peut voir comment il est facile d'ajouter un utilisateur, un domaine…

Défaut de "heroku" ?

À mes yeux heroku a un défaut rédibitoire : la plateforme n'est pas libre. Je ne peux pas l'installer sur mes serveurs. Pour utiliser heroku il est obligatoire de passer par leur plateforme l'hébergement.

Cependant, je vois heroku comme un modèle à suivre.

Est-ce que cela existe en Python ?

Un exemple à suivre ? en effet et plusieurs solutions dans le monde Python ont vu le jour :

  • djangy pour du déploiement Django, vraiment semblable à heroku
  • ep.io pour du déploiement WSGI (« We take your Django, Flask, Pylons or other WSGI code »)
  • Gondor pour du déploement Django

Là aussi le problème est que ces solutions ne sont pas libres.

Une solution ouverte ?

Oui, quelque chose d'ouvert existe, mais je ne l'ai pas encore testé : Silver Lining.

Je vous invite à lire la documentation, la solution est totalement libre. C'est un système basé sur Ubuntu (j'aurais aimé Debian).

Faudrait vraiment que j'expérimente cela.

Read and Post Comments

Traduction du billet de Ian Bicking « À propos des librairies de génération de formulaires HTML »

En mars 2007, Ian Bicking a écrit un billet à propos des librairies de génération de formulaires web : « On form libraries »

J'ai trouvé ce billet très intéressant… bien que j'aie quelques commentaires à faire… mais cela fera l'objet d'un autre billet de ma part.

J'ai décidé de traduire ce document et voici le résultat ci-dessous.

Concernant la traduction, j'ai pris une assez grande liberté. J'ai retravaillé certaines phrases pour les rendre - je l'espère - plus simples à comprendre.
J'ai aussi pris certaines libertés au niveau de la mise en forme.
Mon document n'est donc pas une traduction fidèle, j'ai toutefois essayé de garder autant que possible l'esprit du billet original.
Traduction

À propos des librairies de génération de formulaires HTML

Il y a un certain temps (ntd - février 2005), j'ai écrit un billet à propos de la génération de formulaires web. J'y faisais part de mon expérience acquise lors du développement de FunFormKit, du développement des premières versions de FormEncode, et j'y expliquais aussi ce qu'est devenu FormEncode (uniquement une librairie de validation).

Depuis, sont arrivées quelques nouvelles librairies de génération de formulaires web dans l'écosystème Python; ToscaWidgets, Django newforms, et quelques autres dont j'ai entendu parler.
Je n'aime pas critiquer gratuitement le travail des autres, mais je tiens à dire que je pense que ces librairies ont adopté une mauvaise stratégie pour atteindre leurs objectifs.
Écrire une librairire de génération de formulaires est une tâche difficile. Il faut trouver le bon compromis entre une certaine simplicité d'utilisation et l'étendue des fonctionnalités.
Potentiellement, le nombre de fonctionnalités pour ce type d'outil est très élevé. Exemples :
  • comment modifier finement le code HTML généré ?
  • comment contrôler la mise en forme (le layout) ?
  • comment gérer la répétition d'éléments ?
  • comment gérer les éléments qui requièrent du Javascript ?
  • comment gérer les ressources coté serveur du type CSS ou Javascript ?
  • Comment gérer les communications client-serveur, par exemple supporter l'auto-complétion ?
Une librairie qui gère autant de fonctionnalités ne peut pas rester simple à utiliser. Une "petite" librairie qui reste simple ne pourra gérerer qu'une petite partie de ces fonctionnalités.
Cependant, pour générer des formulaires "simplistes", il n'est pas utile d'avoir recours à une librairie de génération de formulaires.

Cycle de vie de la création d'une librairie de génération de formulaires

Je vais maintenant expliquer pourquoi, à cause de leur conception, ils ne peuvent pas obtenir un bon compromis entre simplicité et fonctionnalité.
Il existe des problèmes qui n'ont pas de solution. Et contrairement aux apparences, c'est le cas des outils de générations de formulaires.
Le cycle de vie de création et de maintenance d'une librairie de génération de formulaires est pratiquement toujours le même.
Un développeur a certain besoins. Généralement il n'aime pas écrire du code HTML bien que cela ne le dérange pas de travailler avec un langage de template qui est plus difficile à utiliser. Il n'est sans doute pas très excité par les tâches manuelles et fabriquer une librairie de génération de formulaires est une agréable diversion.
Dans tous les cas, il fait le bon choix (enfin, celui qu'il pense être le bon) et il essaie d'utiliser une librairie existante.
Il se trouve que la librairie est complexe à utiliser, elle ne correspond pas à la façon dont il a appréhendé le problème, il est difficile d'identifier l'origine des erreurs, les petits ajustements qu'il souhaite apporter (lui, son chef ou son client) sont à l'origine de la plupart de ses difficultés.
Et là, il se dit « Je peux faire cela plus simplement ! ».
Le développeur a raison. Il sait exactement ce dont il a besoin (maintenant), et ce qui peut améliorer sa productivité.
Il crée donc une nouvelle librairie de génération de formulaires web.
Le problème est que la vie de cette nouvelle librairie ne s'arrête pas là. Elle ne peut pas s'arrêter là ! Pourquoi ? Parce que quelqu'un utilise cette librairie, et par conséquent le code doit être maintenu.
Une librairie de génération de formulaires est une chose difficile à maintenir, car elle a toujours besoin d'évoluer.
Des nouveaux types de champ doivent être ajoutés. Des nouveaux cas particuliers doivent être pris en compte. Pour ce qui concerne l'interface utilisateur, des cas particuliers, non prévus initialement, doivent pouvoir être traités.
Une bonne interface utilisateur est généralement spécifique au besoin, adapté au cas par cas. L'interface utilisateur doit être construite en fonction du besoin de l'utilisateur final et non pas en fonction des contraintes du développeur.
Avec le temps, le développeur a de nouveaux besoins.
Par exemple, une simple liste de cases à cocher contient un très grand nombres de choix. Il faut maintenant pouvoir l'afficher sur deux colonnes.
Conséquence : pour gérer ce nouveau cas, le développeur ajoute un peu de code à la fois dans la librairie et dans l'application.
Ensuite, le développeur souhaite que les champs textes contiennent le nom des champs (leurs labels) quand leurs contenus sont vides. Suite à cela, le système de validation devient un peu plus complexe à gérer.
Ensuite, le développeur aura peut être besoin de gérer des formulaires à plusieurs étapes… Ou alors des formulaires avec des champs optionnels…
De fil en aiguille, à chaque fois du code est ajouté à la librairie ainsi que dans l'application (à condition bien sûr, dans le meilleur des cas d'avoir le contrôle de ces deux parties).
Avec le temps, la librairie devient de plus en plus complexe, tandis que pendant ce temps, le développeur se familiarise avec son propre code et devient de plus en plus distant des autres développeurs qui devront peut être un jour intervenir dans son projet.
Et là, nous n'avons même pas abordé le sujet des non programmeurs qui souhaitent seulement modifier un tout petit peu le rendu HTML du formulaire. Ensuite vient le problème de turnover…

Et un jour, c'est la catastrophe, quelqu'un vient et dit « Je peux faire cela plus simplement ! » et c'est reparti pour un tour, on recommence l'histoire depuis le début.

Une autre approche

La partie validation
Je pense que le problème n'est pas pris par le bon coté. Je pense qu'il y a une meilleur approche, mais je suis trop fainéant pour la réaliser.
Bon…, je vais expliquer le principe, avec le petit espoir que quelqu'un réalisera le code :) .
Tout d'abord, la partie « validation » : j'aime la façon dont FormEncode fonctionne, je pense que la stratégie est bonne.
L'étape de validation est totalement indépendante du reste du système, vous pouvez programmer le type de validation que vous souhaitez, vous pouvez l'intégrer dans un autre système…
La partie « formulaire »
Ensuite, la partie « formulaire ».
La solution la plus simple est d'écrire directement le formulaire en code HTML avec son langage de template préféré.
Mais ceci est ennuyeux, les développeurs vont se plaindre… Pourquoi ?
  1. Remplir les valeurs par défauts dans les champs est ennuyeux. Il faut prendre en compte différents cas : les valeurs de la requête (par exemple en mode modification), les valeurs par défauts lorsque le formulaire est vide…
  2. La mise en place de l'affichage des messages d'erreurs est aussi une tâche ennuyeuse.
  3. Il faut écrire correctement les balises <label>… ce qui est une tâche rébarbative… c'est peut être ce qui explique que de très nombreux sites, même de grande notoriété, n'intègrent pas ces balises.
  4. Je suppose que l'HTML est généralement casse-pieds, bien que le langage soit seulement légérement plus verbeux que le code de programmation qui permet de le remplacer.
  5. La partie Javascript peut être ennuyeuse, beaucoup de développeurs web ne sont pas très à l'aise avec ce langage.
  6. Il est ennuyeux de placer correctement les fichiers ressources Javascript et CSS, et d'effectuer ensuite la liaison des classes CSS avec les bonnes balises…
  7. Les appels Ajax sont réellement ennuyeux à mettre en place.
  8. Les imbrications de champs, les répétitions de groupes de champs… sont une autre source d'ennuis.
  9. Et pour finir, il est difficile de réutiliser tout cela.
Ma réponse est que tous ces problèmes peuvent être résolus sans librairie de génération de formulaires.
formencode.htmlfill répond aux points 1 et 2. Ce n'est pas parfait, mais c'est utilisable.
Quelque chose comme WebHelpers peut être utile pour le point 4.
Aucun de ce ces outils ne doit être la solution ultime. Ils peuvent tous être améliorés mais attention, il ne faut pas pousser trop loin leurs perfectionnement ! Sinon ils vont devenir de trop grands consommateurs de temps.
Un peu de « Unobtrusive JavaScript » peut résoudre le problème numéro 5.
Je pense que la mise en oeuvre d'un outil spécifique pour le point 6, pourrait être pratique : j'imagine quelque chose comme <input type="date" js-require="DateInput"> qui chargerait automatiquement les bons fichiers Javascript et CSS, et qui appellerait du code là où est le champ DateInput.

Les nouvelles spécifications Web Forms 2.0 de WHAT-WG peuvent parfaitement gérer les points 7 et 8… un outil construit sur ce modèle ferait parfaitement l'affaire.

Une fois que vous avez tout cela, je pense que le point 9 peut être plus ou moins atteint.
En conclusion, vous n'avez pas besoin d'un framework de génération de formulaires, vous avez juste besoin d'un outil tout simple qui génère du code HTML et qui respecte certaine conventions.
Ce qui est remarquable , c'est que cette technique est uniquement basée sur des abstractions déjà présentes : HTML et Javascript.
De plus, chaque outil peut être utilisé de manière indépendante. Il est possible de remplacer chaque brique par autre chose, une nouvelle implémentation… qui correspond parfaitement au besoin du projet.
Ce qui est difficile à accepter, c'est que ces outils semblent terriblement simplistes, ils ont peu de fonctionnalités comparé aux systèmes de génération de formulaires automatique.
Doucement mais surement, ces petits outils peuvent gagner la course, quelque soit la manière… pendant ce temps, les autres systèmes de génération de formulaires vont souffrir du mal du cycle de la réimplémentation… Tandis que de simples outils vont mieux supporter les épreuves du temps.
Et même si ces simples outils n'arrivent pas à atteindre l'objectif souhaité, il est possible d'en remplacer un ou plusieurs sans mettre en péril tout l'édifice.

Maintenant, ça serait génial que quelqu'un se lance dans la fabrication des pièces manquantes, car j'essaie vraiment de ne pas commencer de nouveaux projets supplémentaires.

Ian Bicking

Depuis cette date, tous les outils décrits dans ce billet n'ont pas été réalisés. Toutefois formencode et formencode.htmlfill remplissent très bien leurs rôles respectifs.

Je tiens aussi à souligner que depuis, les librairies de génération de formulaires ont bien évolué, comme par exemple WTForms que j'ai étudié hier. Cette dernière reste très très simple d'utilisation.

Dans un prochain billet, je donnerai mon point vu personnel sur ce sujet.

Read and Post Comments
« Billets plus récentsBillets plus anciens »

Mes flux :