Launch SOAP UI Mock with JUnit

vendredi 29 août 2008

SOAP UI permet de créer des mocks à partir d'un WSDL ou d'une connexion sur un Web service de test. Quand ces mocks sont créés par les fournisseurs de service, il peut être intéressant de pouvoir les utiliser directement dans les tests JUnit ou dans une page Fitnesse plutôt que de devoir installer SOAP UI et de lancer les mocks, voici ce que propose ce tutorial. Ajouter les dépendances dans le projet Maven:
   <dependency>
    <groupId>xmlbeans</groupId>
    <artifactId>xbean</artifactId>
    <version>2.3.0-trunk-patched</version>
   </dependency>
   <dependency>
    <groupId>xmlbeans</groupId>
    <artifactId>xbean_xpath</artifactId>
    <version>2.3.0</version>
   </dependency>
   <dependency>
    <groupId>xmlbeans</groupId>
    <artifactId>xmlpublic</artifactId>
    <version>2.3.0</version>
   </dependency>
   <dependency>
    <groupId>xmlbeans</groupId>
    <artifactId>jsr173</artifactId>
    <version>xmlbeans-2.3.0</version>
   </dependency>
   <dependency>
    <groupId>eviware</groupId>
    <artifactId>soapui</artifactId>
    <version>2.0.2</version>
   </dependency>
   <dependency>
    <groupId>eviware</groupId>
    <artifactId>soapui-xmlbeans</artifactId>
    <version>2.0</version>
   </dependency>
   <dependency>
    <groupId>xmlbeans</groupId>
    <artifactId>xbean_xpath</artifactId>
    <version>2.3.0</version>
   </dependency>
   <dependency>
    <groupId>commons-httpclient</groupId>
    <artifactId>commons-httpclient</artifactId>
    <version>3.0.1-soapui</version>
   </dependency>
   <dependency>
    <groupId>bouncycastle</groupId>
    <artifactId>bcprov-jdk15</artifactId>
    <version>138</version>
   </dependency>
   <dependency>
    <groupId>jetty</groupId>
    <artifactId>jetty</artifactId>
    <version>6.1.5</version>
   </dependency>
   <dependency>
    <groupId>jetty</groupId>
    <artifactId>jetty-util</artifactId>
    <version>6.1.5</version>
   </dependency>
   <dependency>
    <groupId>jetty</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5-6.1.5</version>
   </dependency>
   <dependency>
    <groupId>wsdl4j</groupId>
    <artifactId>wsdl4j</artifactId>
    <version>1.6.2-fixed</version>
   </dependency>
   <dependency>
    <groupId>groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <version>1.5.1</version>
   </dependency>
   <dependency>
    <groupId>saxon</groupId>
    <artifactId>saxon</artifactId>
    <version>8.8</version>
   </dependency>
   <dependency>
    <groupId>saxon</groupId>
    <artifactId>saxon-dom</artifactId>
    <version>8.8</version>
   </dependency>
Et le repository SOAP UI pour télécharger les jars:
<repositories>
       <repository>
           <id>eviwareRepository</id>
           <url>http://www.eviware.com/repository/maven2</url>
       </repository>
   </repositories>
  
Dans votre test JUnit, il vous suffit de démarrer les mocks de la façon suivante:
 private static List runners;
 private static List runners;

 @BeforeClass
 public static void startSoapUIMocks() throws Exception {
  runners = new ArrayList();
  WsdlProject project = new WsdlProject("/etc/mocks/soapui-project-sample.xml");
  for (int c = 0; c < project.getMockServiceCount(); c++) {
   MockService mockService = project.getMockServiceAt(c);
   mockService.addMockRunListener(new LogListener());
   runners.add(mockService.start());
  }
 }
...
}

class LogListener implements MockRunListener {
 public void onMockRunnerStart(MockRunner mockRunner) {
 }

 public void onMockRunnerStop(MockRunner mockRunner) {
 }

 public void onMockResult(MockResult result) {
 }

 public void onMockRequest(MockRunner runner, HttpServletRequest request, HttpServletResponse response) {
 }
}

Et de les arrêter comme suit:
 @AfterClass
 public static void endSoapUIMocks() throws Exception {
  for (MockRunner runner : runners)
   runner.stop();
 }

Pas si dur finallement ?

Raisons de l'échec de projets agiles

mardi 26 août 2008

XP n'a rien de magique ! Si vous pouvez améliorer la façon de créer des produits logiciels avec moins d'anomalies en utilisant XP, vous pouvez aussi ne pas créer de réelles améliorations dans votre processus de développement logiciel. Quelques raisons essentielles: - Ne pas savoir quand une story est terminée. Une story est terminée quand:
  • Vous avez des tests unitaires JUnit sur chaque classe créée
  • Un test d'intégration JUnit
  • Un code refactoré au fur et à mesure, meilleur design, meilleur lisibilité, gestion des erreurs, meilleure ergonomie de code (c.f. Code smell de Martin Fowler)
  • Des tests de recette automatiques qui passent au vert (Fitnesse, GreenPepper)
- Accumuler la dette technique
  • Sans tests automatiques et sans refactoring régulier (amélioration du design), votre application accumule une dette technique qu'il faudra nettoyer sur 1 ou 2 itérations, sinon votre application ne sera pas différente d'une application développée en cascade, c'est à dire elle ne tiendra pas dans la durée, vous serez obligé de la refaire
- Ne pas faire de rétrospectives ou ne pas respecter le plan d'actions
  • Les retrospectives sont là pour améliorer le fonctionnement de l'équipe, elles ont généralement lieues après chaque itérations, elles permettent de ressortir un plan d'actions pour l'itération suivante. Ce qui peut arriver, c'est de ne pas faire de retrospectives, de faire des retrospectives où les vraies douleurs ne sont pas remontées pour x raisons ou de ne pas appliquer le plan d'actions satué pendant la rétrospective
- L'engagement de l'équipe n'est pas assez fort
  • L'équipe n'est pas sous pression, n'est pas engagée collectivement vers un objectif. Si la qualité pour l'équipe n'est pas importante, du coup elle code à l'arrache des stories sans refactorer et même sans faire de tests afin de montrer qu'elle possède une bonne vélocité. Il vaut mieux avoir une vélocité plus faible. Dans un projet, la vélocité n'est qu'un indicateur pas une valeur à augmenter à tout prix, ..., ce qui est important c'est que la vélocité soit stable par rapport à une qualité de livrable constante. L'enjeu n'est parfois pas clair pour l'équipe mais aussi pour les managers de cette équipe, dans ces cas là, soit les managers viennent sur le plateau régulièrement (à la méthode Lean), soit l'équipe se fixe elle-même son propre enjeux
- Le client (XP) ou le product owner (Scrum) n'est pas clairement défini
  • On se retrouve avec des priorisations / dépriorisations régulières qui font que le produit n'est plus stable fonctionnellement. Beaucoup de stress et de doutes se fait ressentir dans ces cas là, ça nuie à la motivation de l'équipe.
- Des stories non découpées en tâches (de moins d'une journée) qui ne sont pas suivies par un taskboard
  • On perd beaucoup en focalisation de l'équipe. Si on n'a pas de taskboard, alors chacun travaille sur ce qu'il souhaite et pas sur ce qui est demandé et important. Rien de nouveau, chacun de nous est confronté à cela tous les jours dans sa gestion du temps, il faut faire des choix, dans une équipe XP, ces choix sont choisis en vue de l'atteinte de l'objectif que s'est fixé l'équipe
Qu'est ce qui est donc le plus important alors ? Qu'est ce qui fait qu'une équipe est agile ? Est ce que les membres doivent être tous des top guns ? Ce qui fait la différence, c'est l'attitude des différents membres de l'équipe, non pas leurs compétences, mais plutôt leur volonté de vouloir s'améliorer collectivement, de vouloir aller plus loin, de vouloir partager quelque chose dans le respect des cinq valeurs fondamentales: communication, simplicité, feedback, courage et respect.

Ecrire de vraies assertions dans vos tests avec Hamcrest

lundi 25 août 2008

Hamcrest permet d'écrire des tests plus compréhensibles grâce à des assertions commençant par assertThat. Quelques exemples:
String message = "hello world !";
      String message2 = "hello world !";
      assertThat(message, notNullValue());
      assertThat(message, equalTo("hello world !"));
      assertThat(message, is(message2));
      List messages = new ArrayList();
      messages.add(message);
      messages.add(message2);
      assertThat(messages.size(), greaterThan(0));
      assertThat(message, allOf(notNullValue(), not(equalTo("toto"))));
      assertThat(messages, hasItem(message));

Hamcrest permet aussi d'écrire ses propres "Matcher", pour plus d'infos sur le sujet, je vous conseille de jeter un coup d'oeil au tutorial. Pour ajouter Hamcrest dans votre projet Maven 2:
<dependency>
      <groupid>org.hamcrest</groupid>
      <artifactid>hamcrest-all</artifactid>
      <version>1.1</version>
  </dependency>

Couverture de tests dans Eclipse

Vous voulez connaitre la couverture de code réalisée par vos tests dans Eclipse ? Connaître la couverture de vos tests ? Utiliser Eclemma !