CoreProtocols

jeudi 29 mai 2008

J’ai suivi une première initiation aux Core Protocols de Jim et Michele McCarthy animée par Yves Hanoulle et des Octos.

L’expérience était enrichissante, j’ai senti la puissance des protocoles pour aligner une équipe, pour améliorer la confiance de l’équipe et donc son efficacité.

Dans cet article, je vais vous présenter certains protocoles, tel que je les ai perçu, au travers d’une communication fictive entre deux personnes P1 et P2.

Check in

P1:

  • Check In
  • Je suis content de te voir car ça fait longtemps qu’on s’est pas vu
  • Je suis énervé car je suis en retard à cause des bouchons
  • Je suis là

P2:

  • Bienvenue

P2:

  • Check In
  • Je suis aussi content de te voir
  • J’ai peur que l’on arrive pas à faire tout ce qu’on a prévu
  • Je suis triste qu’on se voit pas plus souvent
  • Je suis là

P1:

  • Bienvenue

Le check in permet d’exprimer ses émotions aux autres, ce qui permet aux autres de connaître notre état d’esprit. Le check in permet de vider ses émotions et de s’engager dans la communication: “Maintenant, c’est bon, je suis là, je suis prêt”. Je trouve que le check in n’est pas humain et sectaire, par contre il est efficace, après un check in je suis prêt.

Perfection game

P1: Veux tu que je fasse un perfection game sur ta présentation ?

P2: Oui

P1: Je mets 7/10 J’aime:

  • le contenu est clair
  • le contenu est concis

Pour avoir 10:

  • J’ajouterai des visuels
  • Je diminuerai le nombre de slides

P2: Merci

Le perfection game permet d’améliorer les choses en disant ce qui va bien et comment on peut l’améliorer. C’est une démarche constructive. Il est important de ne pas blesser l’autre et que l’autre ne se sente pas blessé. Ma note correspond à ce que je peux apporter, plus elle est élevée, moins j’ai à apporter, plus elle basse, plus j’ai à apporter.

Pass

J’ai le droit de passer un protocole sans justification, sauf le Decider

Decider

P1: Je propose de changer le modèle de la présentation en mettant celui d’Octo

P2: Pouce en bas

P1: Qu’est ce qui te gène dans ma proposition ?

P2: Le modèle doit être celui du client

P1: OK, je propose alors d’ajouter le logo d’Octo dans le modèle

P2: Pouce en haut

Il existe aussi la main à plat quand on n’a pas d’avis. Le Decider permet à une équipe de prendre des décisions. Si j’ai une meilleure solution, je dois la proposer. Si je n’ai pas mieux, je suis d’accord.

Investigate

P1: Veux tu que je fasse un investigate sur l’objectif de ta présentation ?

P2: Oui

P1: Quel message souhaites tu faire passer ?

P2: Le SOA , c’est de la merde

P1: Quels sont tes interlocuteurs ?

P2: Des pro SOA

P1: Quel est ton objectif, leur faire découvrir autre chose ou les agresser ?

P2: ….

L’Investigate permet à une personne de mieux comprendre les objectifs d’une autre personne, c’est une phase d’empathie, de volonté de comprendre l’autre. Cela permet aussi à la personne investiguée de clarifier ses objectifs.

Check out

P1: Check out

Check out car je ne peux plus tenir mes engagements par rapport à l’équipe ou c’est mieux pour moi que je sois ailleurs. Je n’ai pas besoin de justifier.

Ask For Help

P1: Veux tu m’aider sur ma présentation ?

P2: Oui

P1: Je n’arrive pas à rendre la présentation sexy.

P2: Montre là moi…

Et d’autres

  • Protocol check
  • Intention Check
  • Resolution
  • Personal Alignment

UniversiteDuSI

lundi 26 mai 2008

Ne manquez pas cet évènement unique en France ! Vous découvrirez comment Neil Armstrong a pu marcher sur la lune, un projet réalisé en cascade ou en agile, à votre avis ? Vous pourrez rencontrer des personnalités publiques comme le philosophe Michel Serre, Eliyahu Goldratt le père de la théorie des contraintes ou Bjarne Stroustrup inventeur du C++ et bien d'autres. Et vous pourrez aussi suivre une session sur l'architecture et les méthodes agiles que j'animerai avec Bernard Notarianni, vous y découvrirez les principes de conception émergente, les bienfaits du Domain Driven Development, l'architecture et la communication, les outils agiles et autres particularités des méthodes agiles qui font que l'architecture de votre application resiste aux années ... De quoi faire rêver bien des femmes ...

Concordion

dimanche 25 mai 2008

On parle beaucoup de Fitnesse et de GreenPaper pour écrire des tests exécutables, on parle peu de Concordion.

Par rapport à un Fitnesse ou un Greenpaper, Concordion a les avantages suivants:

  • Il s’apparente à des spécifications exécutables plutôt que des tests exécutables
  • Il n’est pas limité au format tableau
  • Pas de difficulté avec le classpath
  • Les fixtures sont sous forme de tests JUnit
  • Pas de serveur à installer
  • Pour le partage en équipe, on utilise le référentiel de code (Subversion, CVS)
  • Il s’intègre aux rapports Maven Sunfire

Exemple d’écriture de tests exécutables pour un blog

Un blog doit permettre de lister le titre et le contenu des articles, d’ajouter des articles et de supprimer des articles.

Test de la récupération des articles

  • Ajouter la ligne suivante pour gérer les caractères spéciaux:
<meta http-equiv=“Content-Type” content=“text/html; charset=UTF-8” />
  • Ajouter des données dans la base de données à partir d’un tableau:
<h3>Insertion d’articles en base de données</h3>
<table concordion:execute=“addArticleInDatabase(#title,#content)”>
    <tr><th concordion:set=“#title”>Titre</th><th concordion:set=“#content”>Contenu</th></tr>
    <tr><td>Titre 1</td><td>Contenu 1</td></tr>
</table>
  • Vérifier le contenu des articles
<h3>Vérification de la liste des articles</h3>
<table concordion:verifyRows=“#article : getArticles()”>
    <tr><th concordion:assertEquals=“#article.getTitle()”>Titre</th><th concordion:assertEquals=“#article.getContent()”>Contenu</th></tr>
   	<tr><td>Titre 1</td><td>Contenu 1</td></tr>
</table>

Test de l’ajout de l’article

  • Ajouter un article
<h2>Ajout d’un article</h2>
<p>Ajout de l’article de titre <span concordion:set=“#title”>Titre 3</span> et de contenu <span concordion:set=“#content”>Contenu 3</span><span concordion:execute=“addArticle(#title,#content)”/></p>
  • Vérifier l’ajout de l’article
<table concordion:verifyRows=“#article : getArticlesInDatabase()”>
    <tr><th concordion:assertEquals=“#article.getTitle()”>Titre</th><th concordion:assertEquals=“#article.getContent()”>Contenu</th></tr>
   	<tr><td>Titre 1</td><td>Contenu 1</td></tr>
   	<tr><td>Titre 3</td><td>Contenu 3</td></tr>
</table>

Suppression d’un article

  • Suppression d’un article:
<h2>Suppression d’un article</h2>
<p>Suppression de l’article d’id <span concordion:set=“#id”>1</span><span concordion:execute=“deleteFirstArticle(#id)”/></p>
  • Vérifier la suppression de l’article:
<table concordion:verifyRows=“#article : getArticlesInDatabase()”>
    <tr><th concordion:assertEquals=“#article.getTitle()”>Titre</th><th concordion:assertEquals=“#article.getContent()”>Contenu</th></tr>
   	<tr><td>Titre 3</td><td>Contenu 3</td></tr>
</table>

Création des fixtures

  • Les fixtures sont des tests JUnit, il est possible de dériver sa classe de test de ConcordionTestCase en JUnit 3, ou d’utiliser le runner CondordionRunner avec la déclaration: @RunWith(ConcordionRunner.class)
  • Il est possible d’utiliser un autre runner dans le test comme le runner Spring qui permet de charger le contexte et d’initialiser les bean Spring automatiquement:
	@Test
public void run  throws IOException {
	ResultSummary resultSummary = new ConcordionBuilder().build().process(
			this);
	resultSummary.print(System.out);
	resultSummary.assertIsSatisfied();
}
  • Voici le code du test du blog:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { “classpath:applicationContext.xml” })
@Transactional
public class BlogTest {
	@Autowired
	private HibernateTemplate hibernateTemplate;
	@Autowired
	private BlogService blogService;
	public void addArticleInDatabase(String title, String content) {
		Article article = new Article(title, content);
		hibernateTemplate.save(article);
	}
	public Iterable<Article> getArticles() {
		return blogService.listArticles();
	}
	public void addArticle(String title, String content) {
		blogService.addArticle(new Article(title, content));
	}
	@SuppressWarnings(“unchecked”)
	public Iterable<Article> getArticlesInDatabase() {
		return hibernateTemplate.find(“from Article”);
	}
	public void deleteFirstArticle(Long id) {
		blogService.deleteArticle(id);
	}
	@Test
	public void run() throws IOException {
		ResultSummary resultSummary = new ConcordionBuilder().build().process(
				this);
		resultSummary.print(System.out);
		resultSummary.assertIsSatisfied();
	}
}

Utilisation avec Maven 2

  • Ajouter la dépendance dans le fichier pom.xml:
		<dependency>
			<groupId>org.concordion</groupId>
			<artifactId>concordion</artifactId>
			<version>1.3.0</version>
			<scope>test</scope>
		</dependency>
  • Ajouter le plugin Concordion au plugin Surefire:
		<plugins>
			<plugin>
				<artifactId>maven-surefire-plugin</artifactId>
				<configuration>
					<systemProperties>
						<property>
							<name>concordion.output.dir</name>
							<value>target/concordion</value>
						</property>
					</systemProperties>
				</configuration>
			</plugin>
		</plugins>

Code de l’exemple

Ressources

DomainDrivenDesignMethodo

Deux types d’approches sont possibles pour concevoir des produits logiciels:

  • l’approche cascade
  • l’approche itérative

L’approche cascade consiste à demander aux experts métier de définir leurs besoins qui sont communiqués aux analystes qui construisent un modèle métier et donnent le résultat aux développeurs. Cette approche possède des limites dont la principale est qu’il n’y a pas assez de feedback des analystes vers les experts métiers ou des développeurs vers les analystes. Le design de l’application s’en ressent.

L’approche itérative comme Extreme Programming prône la conception émergente, c’est à dire que la conception de l’application se fait au fur et à mesure grâce aux communications effectuées entre experts métiers et développeurs. Grâce à des tests de recette automatiques, il est possible de changer la conception du logiciel sans connaître de régressions. Un des problèmes avec les méthodes agiles est que la décision sur la conception de l’application est faite au plus tard et donc l’application ne progresse pas en terme de compréhension métier.

Il est donc essentiel de faire ressortir le domaine métier de l’application pour que l’application puisse évoluer au cours du temps, c’est le principal objectif du Domain Driven Design. Un bonne conception va faire accélérer le développement. Cette conception doit évoluer au cours du temps par rapport aux retours du code et des besoins métiers. Cette conception n’est pas figée, elle évolue.

Je vous conseille l’ouvrage d’Eric Evans Domain-Driven Design: Tackling Complexity in the Heart of Software ou de télécharger gratuitement le pdf Domain Driven Design quickly

Dans les projets agiles sur lesquels j’ai pu travailler, j’ai constaté qu’au début la vélocité de l’équipe était bonne et qu’à un moment elle chutait, ceci était du la plupart du temps à un problème de conception de l’application, le modèle existant ne permettait plus de gérer la complexité de l’application. Ce que j’aime faire pour résoudre ce problème est d’introduire le fonctionnement de l’application dans les tests de recette automatisés (Fitnesse / Concordion). Un exemple: “Une identité peut se connecter au portail grâce à un login et un mot de passe. Chaque identité possède un porte-feuille de contrats en fonction de ses abonnements. Ses contracts sont de type: …. ”, ceci permet de faire sortir les différentes entités de l’application et leurs relations. Ca a l’avantage d’être compréhensible par tous, développeurs, experts métiers ou exploitants.

Conclusion: Faites du Domain Driven Design même en Agile !!!

CXF

vendredi 16 mai 2008

Qui n’a pas souffert sur Axis 1, puis Axis 2 avec le code verbeux et dégueulasse qui prend la moitié des packages de votre application quand vous avez osé généré un client ?

Dans ma recherche du moteur SOAP le plus agile, j’ai essayé CXF qui est la fusion du Ex Celtix et Ex XFire. Un article intéressant et des arguments forts me mettent sur la voie.

Mes objectifs sont:

  • avoir un code léger
  • utiliser les annotations des web services (@Webservice)
  • intégrer Spring
  • pourvoir tester mon web service par un test JUnit simple
  • faire émerger mon web service en TDD
  • pouvoir utiliser Maven 2

TDD sur mon web service

  • Charger un serveur de web service en static
@BeforeClass
public static void initJaxFactory() {
JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
sf.getServiceFactory().setDataBinding(new AegisDatabinding());
sf.setServiceClass(BlogService.class);
sf.setAddress(“http://localhost:8080/service”);
sf.create();
}
  • Tester que c’est un web service
@Test
public void shouldBeAWebService() throws Exception {
URL url = new URL(“http://localhost:8080/service/listArticles”);
URLConnection connection = url.openConnection();
Assert.assertNotNull(connection.getContent());
}
  • Vérifier la génération automatique du WSDL
@Test
public void shouldGenerateWsdl() throws Exception {
URL url = new URL(“http://localhost:8080/service?wsdl”);
URLConnection connection = url.openConnection();
Assert.assertNotNull(connection.getContent());
showResponse(connection);
}
  • Tester la création d’un client
@Test
public void shouldBeAWebServiceClient() {
createWebServiceClient();
}
private IBlogService createWebServiceClient() {
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setServiceClass(IBlogService.class);
factory.setAddress(“http://localhost:8080/service”);
IBlogService client = (IBlogService) factory.create();
return client;
}
  • Tester l’appel de la méthode listArticles du web service à partir du client
@Test
public void shouldListArticlesViaWebService() throws Exception {
IBlogService client = createWebServiceClient();
Assert.assertEquals(1, client.listArticles().size());
}
  • Code du web service
@WebService
public interface IBlogService {
 List<Article> listArticles();
}
@WebService
public class BlogService {
 public List<Article> listArticles() {
  List<Article> articles = new ArrayList<Article>();
  articles.add(new Article());
  return articles;
 }
}

Créer un client avec Spring

Le fichier Spring:

<?xml version=“1.0” encoding=“UTF-8”?>
<beans xmlns=“http://www.springframework.org/schema/beans”
 xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
 xmlns:context=“http://www.springframework.org/schema/context”
 xmlns:tx=“http://www.springframework.org/schema/tx”
 xmlns:p=“http://www.springframework.org/schema/p”
 xsi:schemaLocation=“http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
          http://cxf.apache.org/jaxws
          http://cxf.apache.org/schema/jaxws.xsd          
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-2.5.xsd”>
 <bean id=“client” class=“spike.cxf.IBlogService”
  factory-bean=“clientFactory” factory-method=“create” />
 <bean id=“clientFactory”
  class=“org.apache.cxf.jaxws.JaxWsProxyFactoryBean”>
  <property name=“serviceClass” value=“spike.cxf.IBlogService” />
  <property name=“address”
   value=“http://localhost:8080/service” />
 </bean>
</beans>
  • Le test avec Spring 2.5:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { “classpath:applicationContext.xml” })
public class BlogServiceSpringTest {
 @Autowired
 private IBlogService client;
 @BeforeClass
 public static void initJaxFactory() {
  JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
  sf.getServiceFactory().setDataBinding(new AegisDatabinding());
  sf.setServiceClass(BlogService.class);
  sf.setAddress(“http://localhost:8080/service”);
  sf.create();
 }
 @Test
 public void shouldListArticlesViaWebService() throws Exception {
  Assert.assertEquals(1, client.listArticles().size());
 }
}

Conclusion

Le truc génial est que CXF fournit un serveur pour lancer le web service, on n’a donc pas besoin de déployer le web service sur un serveur d’application pour le tester dans un test JUnit. De plus, créer un client est super simple contrairement à un Axis 2. Le code est léger, l’utilisation avec Spring est simple et tout ça avec Maven 2. Ce framework permet aussi de faire du REST avec des annotations, un prochain post de blog.

Ressources

SpringTDD

dimanche 11 mai 2008

Pour ceux qui ont participé à ma session SpringTDD aux XPDays, voici les supports pour la démo:

XpDay2008

jeudi 1 mai 2008

L’événement XP days 2008 a lieu le 5 et 6 mai à Paris à partir de 9h00 à l’espace FIAP Jean Monnet, 30 rue Cabanis, Paris 14è, métro Glacière ou Saint-Jacques.

Mon sujet de présentation est Spring TDD. Au cours de cette session, je montrerai comment on peut faire du vrai TDD avec Spring à partir d’un exemple. Je dis bien du vrai TDD et pas du test d’intégration car le fichier XML Spring sera couvert par les tests.

J’introduirai Spring 2.5 qui permet de simplifier le développement grâce à l’ajout des annotations. Terminé les fichiers XML Spring où l’on ne retrouve pas où on a configuré l’injection de dépendances.