White box unit testing with AspectDNG 5
Last time, Tom was kidding me (softly) about the fact that we can do almost everything we want with AspectDNG. I begin to think he wasn’t wrong…
Once again, here is a very, very complex system that should be hard tested:
<!- code formatted by http://manoli.net/csharpformat/ ->
<span class="rem">// Main.cs</span>
<span class="kwrd">using</span> System;
<span class="kwrd">public</span> <span class="kwrd">class</span> ComplexSystem {
<span class="kwrd">private</span> <span class="kwrd">int</span> m_secret;
<span class="kwrd">public</span> ComplexSystem() {
m_secret = 0;
}
<span class="kwrd">private</span> <span class="kwrd">void</span> SecretOperation(<span class="kwrd">int</span> oper) {
m_secret += oper;
}
<span class="rem">// should always return a multiple of 2</span>
<span class="kwrd">public</span> <span class="kwrd">int</span> PublicOperation() {
<span class="kwrd">if</span> ((m_secret % 2) != 0) {
SecretOperation(1);
}
<span class="kwrd">return</span> m_secret;
}
}
This can be safely compiled to a Main.dll.
Ok, this ComplexSystem is the central point of your next application, you NEED to test it. What can be better than NUnit ? But here is the problem, you would like to be sure that the secret operation have a correct behaviour, and that the m_secret field is well setted… Two way to do that, first you use boring Reflection, or you can even take a look behind your back, you ensure that you’re alone, you change the visibility of all this, but you promise yourself that you’ll change it as soon as tests passed. Also you may note that somewhere not to forgot, this is a SECRET operation.
What about introducing a new way of testing this ? Using AspectDNG ? Something I may call white box unit testing ? Here is one aspect to do that :
<!
<span class="rem">// Tests.cs</span>
<span class="kwrd">using</span> System;
<span class="kwrd">using</span> NUnit.Framework;
<span class="rem">// dummy complex system, may have been generated</span>
<span class="kwrd">public</span> <span class="kwrd">class</span> ComplexSystem {
<span class="kwrd">public</span> <span class="kwrd">int</span> m_secret;
<span class="kwrd">public</span> <span class="kwrd">void</span> SecretOperation(<span class="kwrd">int</span> oper) {}
<span class="kwrd">public</span> <span class="kwrd">int</span> PublicOperation() { <span class="kwrd">return</span> 0; }
}
[TestFixture]
<span class="kwrd">public</span> <span class="kwrd">class</span> TestComplexSystem {
<span class="kwrd">private</span> ComplexSystem m_complexSystem;
[SetUp]
<span class="kwrd">public</span> <span class="kwrd">void</span> SetUp() {
m_complexSystem = <span class="kwrd">new</span> ComplexSystem();
}
[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> TestPublicOperation() {
Assert.AreEqual(0, m_complexSystem.PublicOperation() % 2);
m_complexSystem.SecretOperation(1);
m_complexSystem.SecretOperation(1);
m_complexSystem.SecretOperation(1);
Assert.AreEqual(0, m_complexSystem.PublicOperation() % 2);
Assert.AreEqual(4, m_complexSystem.PublicOperation());
}
[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> TestFieldSecret() {
Assert.AreEqual(0, m_complexSystem.m_secret);
m_complexSystem.SecretOperation(1);
Assert.AreEqual(1, m_complexSystem.m_secret);
}
[Test]
<span class="kwrd">public</span> <span class="kwrd">void</span> TestSecretOperation() {
<span class="kwrd">int</span> cursor = m_complexSystem.m_secret;
m_complexSystem.SecretOperation(12);
Assert.AreEqual(12, m_complexSystem.m_secret - cursor);
}
}
What can we see there ? I use a dummy ComplexSystem, that looks like really close to the real one no ? It is just a trick, with that, I’ll be able to compile this single file into a Tests.dll assembly. Once this is done, all I have to do it to inject the content of my TestComplexSystem into the real ComplexSystem. This can be done with the standard MetaAspect Insert from AspectDNG.
When weaving is done, after using a simple insert advice, here is the result :

“Et voila”, the ComplexSystem is now a test fixture itself. Pretty simple no ?
And this sample works with Mono. Of course it is a very lightweight one, but hey, it looks good !
UPDATE: You can download the sources of the example here. Just compile as described in the post, and run AspectDNG -w on the AspectDNG.xml provided.
So, what do you think about this kind of unit testing ? I’m curious about you opinion !
Trackbacks
Use the following link to trackback from your own site:
http://evain.net/blog/articles/trackback/9

Franchement c’est plaisant! je pousse jusqu’à génial !
Je dirais pas que c’est de l’AOP mais bon.
Les tests ne sont plus limités par de bêtes contraintes de visibilité et en plus on ne met pas en l’air le code final pour le tester!
La qualite du code devrait s’améliorer… enfin reste quand même à implementer les tests :-)
Sinon, faudrait ce faire une liste non exhaustive des applications du tissage avec AspectDNG avec des exemples simples (comme celui la). Car bcp de responsables technique ou de chefs de projet sont plutôt rétissants aux nouvelles techniques dès qu’on leur demande de changer un peu la maniere de voir, de developper… (mais je désespère pas, ils changeront surement d’avis..)
@+
Seb
100% d'accord. Déjà il faut que la documentation d'AspectDNG s'améliore (c'est un euphémisme).
Voici ce qu'on pourrait en attendre:
- liste des tissages possibles bien sûr
- langages disponibles (xpath ou langage regexp like)
- spécification de tissage XML ou Attributes
- quick start
En parallèle, pour répondre au besoin de "exemples de tissages", je suis en train de finaliser le PetShopAOP, comprenez le PetShopDNG simplifié au maximum et rendu distribué, traçable, optimisé, persistant... par tissage d'aspects avec AspectDNG.
Je devrais rendre ma copie d'ici une ou deux semaines, article à l'appui.
Ensuite, pour aller encore plus loin... que diriez-vous d'écrire enfin le "AspectDNG in Action"? Y a-t-il un lectorat pour ce livre? Quelles sont les attentes de ces lecteurs potentiels?
Tom
et Oui il ya encore un bout de chemin avant un aspectDNG 1.0 :-)
En fait on peut (vous pouvez…) deja pour commencer mettre les examples sur le home du projet en plus des tests unitaires qui sont deja de bons exemples mais assez loin des attentes directs des utilisateurs.
Pour AspectDNG in Action ca serait pas mal en effet le PetShop peut etre pris comme cas d’etude. Je ne sais pas si tu vois un AspectDNG in action dans le sens description d’un cas d’etude (demarceh etc)ou comme une doc tres detaillee des fonctionnalites d’aspectDNG ou un catalogue de recette de cuisine (du style XSLT in action))?
Seb
(PS : pas eu le temps de retester la bouture 0.6.2)
Attention, bientôt 0.6.3, nous frisons l’exces de vitesse… Atteindrons-nous la version 1.0 pour l’été comme promis, suspense…
Le contenu de AspectDNG in Action est à définir. Mais le PetShopAOP sera expliqué bien avant. Histoire que ceux qui prennent le train en marche aient un exemple costaud de tissage sur une petite appli réaliste.
Tom
Hi. I’ve been doing some tests using AspectDNG.
My question is:
Using NAnt, is it possible to tell to aspectdng-weave task where third party DLLs are located? Something like "references" or "includes"?
Thanks.