Ces principes et conseils analysent les meilleures pratiques des composants d'applications Web en termes de tests, comme les Servlets, les JSP, et les EJB en se concentrant en priorité sur les techniques et approches de tests d'intégration des unités et des fonctions. Nous prendrons par ailleurs le temps d'examiner les solutions proposées en cas de panne.
Rubriques
Concernant J2EE 1.3, les phases de tests et de déboguage doivent également prendre en compte les beans contrôles par les message de dépannage ainsi que le filtrage du servlet.
L'élaboration de tests doit faire partie de l'encodage Java. Il est souvent intéressant de commencer par la phase de tests et de générer votre code sur cette base. En général, les développeurs peuvent passer de
25 à 50% du temps de développement à développer les tests de leurs classes. La réalisation anticipée de tests réguliers contribue à accélérer ultérieurement la phase de développement.
Voici ci-dessous les différents types de tests requis :
- Tests d'unités
- Tests fonctionnels (cas d'utilisation)
- Tests sur l'interaction des unités d'exécution
- Tests de durée (long terme)
- Tests de performance
Dans ce chapitre "Principes et conseils", nous mettrons l'accent sur les tests d'unités et sur les test fonctionnels. Nous identifierons néanmoins également les éléments supplémentaires, qu'il est important de tester dans le développement d'une application Web.
Test d'unités
Le test d'unité est principalement un test basé sur les classes, dans lequel on peut découvrir des erreurs logicielles latentes, telles que les erreurs suivantes :
- un élément inactif
- les conditions frontières
- les erreurs d'algorithme
En plus, la coordination de la conception et du code est vérifiée. Cette vérification facilitera ensuite la modification du code. Les cas de tests sont écrits et exécutés par les développeurs du code.
Tests d'intégration
Les tests d'intégration fonctionnels exécutent les mêmes tests de classes ; ils vérifient par ailleurs le chemin d'accès utilisé dans l'intégration. On découvre une disparité dans la conception et il peut être prouvé que le système fonctionne de bout en bout. Les tests d'intégration peuvent être conçus en réutilisant les zones fixes de tests, à savoir les échantillons et les exemples. Les tests existants peuvent être ré-exécutés de manière groupée.
Vous devez penser à écrire un test pour :
- Chaque cas de d'utilisation
- Chaque chemin d'accès majeur
- Chaque méthode publique de chaque classe
Test de la boîte blanche :
- Examine la structure du programme
- Extrait les données des tests de la logique du programme
Boîte noire :
- Teste les paramètres d'entrée et valide les résultats
- Aucune définition implicite concernant l'implémentation
En pratique, le code tests doit être placé dans un package séparé du code en cours de test. Les classes disposent d'un accès spécial aux membres protégés (champs ou méthodes protégés) des classes définies dans le même paquetage. Si les classes de tests devaient être définies dans le même package que les classes en cours de test, l'accessibilité des classes ne serait pas testée de manière efficace. De façon plus pragmatique, les tests sont utiles pour le développement ; en revanche, ils ne sont pas si utiles pour le déploiement. En conservant les tests dans un package complètement différent, le déploiement se réduit à exclure le package de test.
JUnit (www.junit.org) est un outil utile pour le développement des tests (pour plus d'informations sur l'outil JUnit, voir le chapitre [Fowler]
et [Davis]). Concernant l'outil JUnit, les cas de tests sont écrits en langage Java, et peuvent faire l'objet d'un même contrôle de version que le code en cours de test. En conservant les tests dans le même projet développeur d'applications Websphere Studio (développeur d'applications), vous avez la garantie virtuelle que les tests s'effectuent là où se trouve le code. En même temps, si les tests sont maintenus avec le code, le contrôle de version du développeur d'applications peut garantir la synchronisation de votre code et de vos tests.
Dans l'exemple suivant, le bloc de base de construction de l'outil JUnit est la classe du cas de test. Tous les test sont extraits de cette classe, y compris la classe de test du CompteBancaire qui contient le code de test du GestionnaireduCompteBancaire :
package com.wtb.brokers.tests; // votre package de classe de tests
import junit.framework.*;
s mport com.wtb.brokers.*; // votre package de classes
la classe publique de tests du GestionnaireduCompteBancaire étend le cas de tests
{
public BankAccountBrokerTests(nom de chaîne)
{
super(nom);
}
public void testFind() {}
public void testInsert() {}
public void testUpdate() {}
} |
Par défaut, dans un cas de test de l'outil JUnit, toutes les méthodes prédéfinies par le "test" sont considérées comme des cas de tests individuels et seront exécutées automatiquement par le module d'exécution des tests.
Les méthodes de tests ne sont pas appelées dans un ordre particulier ; on n'envisage pas qu'elles puissent dépendre d'autres tests (c'est à dire que vous ne devez pas définir des tests qui dépendent des résultats d'autres tests) ; après chaque test, s'opère un rafraîchissement. Dans leur forme actuelle, ces tests ne sont pas particulièrement intéressants, du fait que le véritable code de test n'a pas encore été rempli. En fait, le code en cours de test n'a même pas encore été défini. Les étapes restantes constituent un exercice de remplissage et d'exécution de ces méthodes. Une fois que ces méthodes ont été créées, et que les tests s'effectuent avec succès, cette partie du processus de développement itératif est complet.
Il est essentiel de commencer à développer les "plans de tests de réception de l'utilisateur" dans les phases de Création, d'Elaboration et de Construction, en tant qu'éléments des disciplines d'analyse et de conception pour les raisons suivantes :
-
Impliquer la communauté d'utilisateurs dès que possible favorise l'achat du produit, une fois qu'il est déployé.
- S'il est vu en tant qu'élément du processus des exigences, les exigences sont recueillies et clarifiées du point de vue de l'utilisateur.
- Un test de réception de l'utilisateur est un plan développé par l'utilisateur du système ; ce test permet à l'utilisateur d'être rapidement impliqué et de s'assurer que les fonctions développées sont les fonctions requises pour satisfaire les besoins de l'utilisateur et qu'elles sont développées et livrées suivant l'ordre de priorité qui convient.
- Utilisation d'une approche contrôlée par le "Cas d'utilisation" pour les fonctions identifiées qui sont nécessaires. L'approche commune de développement est d'utiliser le cas d'utilisation pour développer les tests de fonctions et du système. Cela est bien et utile. Le plan des tests de réception de l'utilisateur peut identifier les combinaisons (et séquences) des cas d 'utilisation que l'utilisateur espérera naturellement employer. Cela n'est pas toujours évident pour le concepteur, pour les développeurs et les testeurs du logiciel et certaines combinaisons de fonctions peuvent produire des effets secondaires inattendus.
Les éléments suivants, spécifiques au test d'une application Web, doivent être planifiés et exécutés :
- Tester tous les aspects de votre système
- les Java beans
- la logique back-end
- les servlet
- les pages JSP
- les EJB
- Le client d'application (applets, Java clients, etc.)
- Test de chargement utilisant un outil commercial de test de chargement ; la réalisation précoce d'un test de chargement révèle des interactions inattendues :
- conditions d'indétermination
- conflit d'accès
- carence de ressources
- Scénarios d'anomalie de test
- Collecter les premiers nombres de performances (requêtes/sec)
Lorsque vous concevez une application dans des couches distinctes, séparez chaque couche et chaque test de manière individuelle. Utilisez les "routines de test" pour représenter les couches inférieures. Beaucoup de projets ont utilisé les classes de test JUnit avec succès pour tester chaque couche.

Les EJB des tests de couches

Avantages:
-
Capacité à expérimenter l'utilisation des EJB sans crainte d'introduire des erreurs dans les couches supérieures
- Le client d'application client "travaille initialement " peu, du fait que les couches inférieures sont en cours de test.
- Mettez en place un environnement de test approprié :
- séparez les machines (du développement)
- séparez le réseau isolé (ou susceptible d'être isolé)
- Actualisez au minimum l'environnement de production à petite échelle, à savoir qu'une seule machine ne suffit pas pour l'ensemble des composants, à moins que la production ne soit organisée de cette manière.
- Utilisez un outil commercial de test de chargement
- Utilisez un profileur
Eléments à conserver actifs
Beaucoup de composants du système nécessiteront des correctifs, au fur et à mesure que le middleware évolue.
Il vous faudra maintenir votre environnement actif :
- Kit JDK
- WebSphere
- Connectivité JDBC
- Serveur HTTP
- Serveur de base de données
- Autres systèmes backend tels que CICS et MQ
- Système
d'exploitation
Avant d'effectuer les tests
Essayez toujours d'éliminer le premier et vérifiez que le problème identifié ne provienne pas d'une erreur de configuration. Il est important de vérifier que l'environnement est bien configuré et qu'il fonctionne correctement. Assurez-vous que toutes les versions recommandées du produit et modules correctifs sont appliqués. Vérifiez également que l'ensemble des éléments pré-requis est respecté. Si vos serveurs sont connectés au système DNS, veuillez vérifier que les noms des ordinateurs hôtes peuvent être gérés par le système DNS. Pour réaliser ce test, testez par écho tous les serveurs auxquels l'accès se fait par leur nom abrégé et nom qualifié complet.
Si votre application accède à des informations stockées dans une base de données, vérifiez l'adresse URL de connectivité JDBC. Vérifiez également que les variables PATH et CLASSPATH sont définies dans les répertoires appropriés.
Fonction de trace et journalisation
La WebSphere comporte des interfaces intégrées de trace et de journalisation. Tous les composants WebSphere
sont utilisés. La fonction de trace est réalisée par une mémoire tampon tournante ; elle est formatée, lorsqu'elle est vidée et exportée vers stdout, stderr ou vers un fichier. L'utilisation de stdout ou de stderr est plus efficace que l'utilisation d'un fichier standard. Dans de rares cas, le fait d'écrire sur un fichier standard peut masquer les problèmes.
Les messages et la fonction de trace sont générés par le système ou par le code utilisateur, en réponse à des événements. Les messages offrent une très bonne vue des événements majeurs et ils sont toujours collectés et affichés en bas de l'écran de la console. La fonction de trace est contrôlée par les paramètres que vous définissez et elle est utile lorsque d'autres informations que celles fournies par les messages sont nécessaires.
Vous devez savoir que la fonction de trace peut avoir une répercussion négative sur les performances et qu'elle doit être utilisée avec parcimonie, lorsqu'on passe à la phase de production.
Utiliser la fonction de trace sur les serveurs d'application
Les serveurs d'application peuvent produire des erreurs liées à des configurations erronées ou à des bogues dans votre application. Lorsque vous utilisez la fonction de trace sur le serveur d'application, seul le code IBM sera soumis à la fonction de trace ; cela peut cependant vous aider à résoudre certains problèmes. Par exemple : pour les classes ou fichiers de ressources qui ne sont pas convenablement localisés ou pour les pilotes JDBC qui ne s'exécutent pas correctement.
Votre propre servlet ou votre code EJB s'exécutant dans le serveur d'applications peut être soumis à la fonction de trace.
Voir le chapitre Centre d'aide et d'information du produit pour plus de détails sur la fonction de trace et sur le déboguage.
Visualiseur de performances
Le Visualiseur de performances est une option d'installation de la WebSphere. Il utilise l'interface API client de l'infrastructure du moniteur de performances, pour afficher les données des modules qui étaient des niveaux organisés. A présent, les valeurs des modules EJB sont positionnées sur bas, moyen, haut et max.
Avec le visualiseur de performances, vous pouvez enregistrer les données dans un fichier texte pour les ré-exécuter et les réviser.
Dans la figure ci-dessous, le visualiseur de performances affiche les informations de la machine JVM pour un serveur d'applications spécifique situé sur un noeud.

|