Bertrand Bougon

j’ai honte, mais j’ai honte!

Oui j’ai honte!

Hier j’ai mis de côté les fondamentaux d’XP. Ah quelle horreur! Je ne chercherai pas d’excuse, la motivation? la fatigue? LE COURAGE (ah oui je l’ai laissé tomber pour le coup)??

Bref tout ça pour dire que j’avais à faire un petit développement (pour Alfresco => beurk, j’y vais de l’onomatopée aujourd’hui) et Alfresco ça n’est pas la panacée pour tout développeur qui a un tant soit peu de l’estime pour lui même (et pour les tests unitaires je ne vous en parle pas, petit aparté, je rédigerai un article sur Alfresco, j’ai déjà le titre en tête « Alfresco, ou l’illusion d’une GED »).
Et  pour ce petit développement j’ai été découragé, découragé de le faire, découragé de faire des tests. Cela m’a tellement contrarié que j’ai twitté « j’ai honte, mais j’ai honte! », c’est là que les Dieux me sont venus en aide et d’infosaurus (rassure toi tu n’es pas un Dieu) de me répondre « Et on peut le voir, ce code ? ;)  », ça m’a reboosté et suis donc reparti ce matin avec en tête de reprendre (supprimer) ce que j’avais fait et repartir sur de bonnes bases.

J’ai finalement gagné ma journée. J’ai écris mes petits tests, et comme je n’ai pas envie de polluer mon wiki avec du code Alfresco, je vous laisse un petit exemple de ce que j’ai fait :

Classe de test :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package fr.home.web.evaluator.doclib.indicator;
 
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
 
import org.json.simple.JSONObject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
 
import fr.home.web.evaluator.doclib.indicator.exceptions.MalformedObjectException;
 
public class CustomStatusEvaluatorTest {
 
	@Rule
	public ExpectedException exception = ExpectedException.none();
 
	@Test
	public void jsonObjectHasExpectedPropertyValue() {
		JSONObject json = FactoryTestForJSONObject.createCleanObjectWithStatusName("Draft");
		assertTrue(new CustomStatusEvaluator().evaluate(json, "Draft"));
	}
 
	@Test
	public void jsonObjectHasAFileName() {
		JSONObject json = FactoryTestForJSONObject.createCleanObjectWithStatusName("Draft");
		assertEquals("filename", new CustomStatusEvaluator().getFileName(json));
	}
 
	@Test
	public void jsonObjectHasNoFileNameReturnsException() {
		exception.expect(MalformedObjectException.class);
		exception.expectMessage("The JSONObject given in parameter has no file name.");
		new CustomStatusEvaluator().getFileName(FactoryTestForJSONObject.createDirtyJSONObjectWithNoFileName());
	}
 
	@Test
	public void jsonObjectHasNoStatusAspectReturnsException() {
		exception.expect(MalformedObjectException.class);
		exception.expectMessage("No aspect defined for the file 'filename'.");
		new CustomStatusEvaluator().evaluate(FactoryTestForJSONObject.createDirtyJSONObjectWithNoAspect(), "test:test");
	}
 
	@Test
	public void jsonObjectHasNoCustomStatusAspectReturnsException() {
		exception.expect(MalformedObjectException.class);
		exception.expectMessage("The JSONObject given does not contain the status 'custom:status'");
		new CustomStatusEvaluator().evaluate(FactoryTestForJSONObject.createDirtyJSONObjectWithMalformedAspect(), "Draft");
	}
}

Implémentation :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
 
package fr.home.web.evaluator.doclib.indicator;
 
import org.alfresco.web.evaluator.BaseEvaluator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
 
import fr.home.web.evaluator.doclib.indicator.exceptions.MalformedObjectException;
import fr.home.web.evaluator.doclib.indicator.exceptions.UnimplementedMethodException;
 
public class CustomStatusEvaluator extends BaseEvaluator {
 
	private static final String NODE = "node";
	private static final String FILENAME = "fileName";
 
	private static final String ASPECT_CUSTOM = "custom:status";
	private static final String PROP_CUSTOM_STATUS = "custom:statusName";
 
	@Override
	public boolean evaluate(JSONObject arg0) {
		throw new UnimplementedMethodException(CustomStatusEvaluator.class, "evaluate");
	}
 
	public boolean evaluate(JSONObject jsonObject, String propertyValue) {
		JSONArray nodeAspects = getNodeAspects(jsonObject);
 
		if(null == nodeAspects) {
			throw new MalformedObjectException("No aspect defined for the file '" + getFileName(jsonObject) + "'.");
		}
 
		if(!nodeAspects.contains(ASPECT_CUSTOM)) {
			throw new MalformedObjectException("The JSONObject given does not contain the status '" + ASPECT_CUSTOM + "'");
		}
 
		return getProperty(jsonObject, PROP_CUSTOM_STATUS).equals(propertyValue);
	}
 
	public String getFileName(JSONObject jsonObject) {
		JSONObject node = (JSONObject) jsonObject.get(NODE);
		String fileName = (String) node.get(FILENAME);
		if(null == fileName) {
			throw new MalformedObjectException("The JSONObject given in parameter has no file name.");
		}
		return fileName;
	}
 
}

Agile tour Bordeaux

L’agile tour Bordeaux 2011, c’est pour bientôt!

Toutes les informations, disponibles ici Agile tour bordeaux

Kata URLSplitting

Cela faisait bien longtemps (d’aucuns diront trop) mais voici en ligne la solution du Kata URLSplitting (pas de vidéo, désolé, je la ferai un autre jour … peut être).

J’affectionne particulièrement ce problème de TDD URLSplitting parce que simple mais pas tant que ça.

la solution et au passage un petit site sur des exercices TDD.

Kata Palindrome

Voici le deuxième Kata que j’ai réalisé (en à peu prêt 22 minutes et il y a même la vidéo!).

Définition du Palindrome

Solution du kata

La vidéo (un peu longue pour un kata, 22 minutes) :

NB : on peut être dérouté par le montage (j’ai utilisé camtasia qui par défaut zoome et dé-zoome sur les parties actives de l’écran)

Mon premier Kata

J’ai la chance actuellement d’être en mission chez MBS (Filiale d’Orange). Chaque semaine un atelier se tient, un sujet est choisi et durant une heure, une heure trente, nous débattons, formulons, nous exerçons sur ce sujet.

Aujourd’hui le sujet de cet atelier était un Kata sur FizzBuzz. Atelier fort intéressant qui a donné lieu à un Randori par la suite.

Je me suis donc dit ce soir en rentrant à la maison, je vais faire mon premier Kata (seul) à la maison. Je dois dire que cela n’a pas été facile. Il est toujours facile d’émettre des avis lorsque l’on regarde quelqu’un ou quelque chose, ca l’est beaucoup moins lorsque l’on passe à la pratique. J’ai donc mis pas loin de quarante cinq minutes à achever ce Kata alors qu’en temps normal il en faudrait trois fois moins et par dessus le marché je ne suis pas entièrement satisfait de la solution. Mais qu’importe, c’est fait pour s’entraîner, un autre jour je trouverai une autre solution qui sera bien meilleure.

Revenons à nos moutons et ce Kata FizzBuzzien.

Tout d’abord, pour ceux qui ne savent pas ce qu’est un Kata, une petite explication ici.
Ensuite, passons à l’explication de FizzBuzz.

Un FizzBuzz est un petit jeu (d’aucuns diront qu’il s’agit d’un jeu de soiffards) tout simple et qui consiste à compter et à remplacer les multiples de trois par « Fizz » et les multiples de cinq par « Buzz », en d’autres termes cela donne :

1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz

Les pièges consistent bien évidemment aux fizz et buzz qui se suivent mais surtout aux fizzbuzz qui se trouvent être un multiple de trois et de cinq.

Au final, lorsque j’ai repris l’exercice ce soir (chez moi en mode tout seul à la maison entre les « Chéri débarrasse moi la table s’il te plait » et « Papa tu peux me faire la fusée qui monte et qui descend ») en n’omettant pas de vider ma petite tête (en même temps j’aurai été incapable de me souvenir de la solution que l’on a mis en place, qui plus est ce n’était pas dans le langage que j’ai utilisé ce soir), j’ai mis mon petit bout de temps et cela a donné ceci.

Du test des méthodes privées

Ce billet fait suite à une discussion que j’ai eu il y a quelques semaines avec un de mes amis (http://www.sismik.fr) lui aussi Agiliste dans l’âme et concernant les tests des méthodes privées.

Tester une méthode privée, comment est-ce possible?
Surtout partant du principe de TDD (je ne vais pas refaire ce qui a été dit, suivez plutôt: http://www.infoq.com/news/2008/01/private-methods-tdd-design). Les méthodes privées, ca sent un peu le « code smell » et effectivement quand une méthode privée apparaît, c’est qu’on a potentiellement un problème de design.

Au final, on en revient à la conclusion, on ne peut pas tester une méthode privée.

De retour

Après avoir mis en suspens mon site depuis plusieurs mois, voici la nouvelle mouture.

Plutôt que de réinventer la roue et repartir sur une refonte complète de mon site (bien que le projet était intéressant en lui-même, mon ambition étant de créer un CMS light en PHP full DDD avec développement dirigé par les tests TDD), un bon wordpress était tout indiqué.
Orientée Blog, un wiki va aussi être mis en place afin de publier des projets, des exemples de code, des kata, dojo…