Mises à jour récentes Activer/désactiver les fils de commentaires | Raccourcis clavier

  • Quentin 17:35 le 30 March 2012 Permalien | Réponse
    Tags :   

    Test against legacy code 

    Le projet sur lequel je travaille en ce moment n’est pas à la pointe des nouvelles techniques de développement. Un des problèmes qui nous rapidement dérangé est l’injection de dépendances. Pour récupérer un service (dans ce cas, une ejb2), on doit appeler une méthode statique qui va nous fournit une instance de l’ejb.

    public interface OrderFacade {
    	void createOrder(final Client client, final Order order) throws Exception;
    }
    
    /**
     * Legacy class used to retrieve the real implementation of a Facade. In the
     * current project at work, I don't really know it's really doing. Let's just
     * assume its create the facade implementation with a complex context.
     */
    public class FacadeHelper {
    	public static Object getService(final Class facadeInterface) {
    		// Do some complex thing to retrieve implementation based on interface
    		// from param.
    		return new OrderFacadeImpl();
    	}
    }
    
    public class OrderController {
    
    	public boolean doSomethingWithOrder(final Client client, final Order order) {
    
    		try {
    			getOrderFacade().createOrder(client, order);
    		} catch (Exception e) {
    			// Remember : never swallow exception like this.
    			// It's a real pain in production.
    			return false;
    		}
    
    		return true;
    	}
    
    	/**
    	 * We need to get an fresh facade implementation a each call. Don't really
    	 * know the reason but I need.
    	 */
    	protected OrderFacade getOrderFacade() {
    		return (OrderFacade) FacadeHelper.getService(OrderFacade.class);
    	}
    }
    

    Le problème se situe dans l’écriture des tests unitaires. Pour pouvoir tester une méthode contre un mock, nous devons surcharger la classe et lui injecter le mock.

    public class OrderControllerTest {
    
    	/**
    	 * Creating an internal class to inject the stub.
    	 */
    	private class OrderControllerMock extends OrderController {
    
    		@Override
    		protected OrderFacade getOrderFacade() {
    			return new FailingToCreateOrderFacadeStub();
    		}
    
    	}
    
    	@Test
    	public void testDoSomethingWithOrder() {
    		OrderController controller = new OrderControllerMock();
    
    		boolean orderCreatingSucceded = controller.doSomethingWithOrder(
    				new Client(), new Order());
    		Assert.assertFalse(orderCreatingSucceded);
    	}
    
    }
    

    Cette solution ne nous satisfaisait pas du tout. En alternative, nous avons d’abord penser à utiliser une librairie comme Powermock et mocker la méthode statique de récupération du service pour qu’elle revoie notre mock à la place. Malheureusement, nous sommes obligés d’utiliser junit 3 alors que powermock nécessite la version 4. Je précise que j’ai écrit les exemples de code chez moi où je n’ai aucune contrainte concernant les versions.

    A la place, nous avons décidé d’utiliser des adapteurs afin de pouvoir injecter un mock lors des tests.

    public interface ServiceAdapter {
    	T getService();
    }
    
    public class LegacyServiceAdapter implements ServiceAdapter {
    
    	private final Class type;
    
    	public LegacyServiceAdapter(final Class type) {
    		this.type = type;
    	}
    
    	@SuppressWarnings("unchecked")
    	public T getService() {
    		return (T) FacadeHelper.getService(type);
    	}
    }
    
    public class InstanceServiceAdapter implements ServiceAdapter {
    
    	private final T instance;
    
    	public InstanceServiceAdapter(final T instance) {
    		this.instance = instance;
    	}
    
    	public T getService() {
    		return instance;
    	}
    }
    

    Nous avons donc une interface qui fournit une méthode pour récupérer un service. Cette interface est implémenté par deux classes :

    • LegacyServiceAdapter : Est chargé de faire appel au FacadeHelper.
    • InstanceServiceAdapter : Prend directement une instance en paramétre. Va nous servir pour les tests.

    Maintenant que nous avons ces adapteurs à notre disposition, il nous reste à modifier OrderController (la classe qui sert d’exemple).

    public class NewOrderController {
    
    	private final ServiceAdapter orderService;
    
    	public NewOrderController() {
    		orderService = new LegacyServiceAdapter(OrderFacade.class);
    	}
    
    	public NewOrderController(final OrderFacade orderFacade) {
    		orderService = new InstanceServiceAdapter(orderFacade);
    	}
    
    	public boolean doSomethingWithOrder(final Client client, final Order order) {
    
    		try {
    			orderService.getService().createOrder(client, order);
    		} catch (Exception e) {
    			// Remember : never swallow exception like this.
    			// It's a real pain in production.
    			return false;
    		}
    
    		return true;
    	}
    }
    

    La nouvelle version de notre controller propose deux constructeurs : le constructeur par défaut est en charge de la création de l’adapteur qui nous sert à récupérer une facade réelle; l’autre constructeur prend en paramètre une instance de la facade pour l’InstanceSerciveAdapter.

    Le code du controler en est simplifier. Au lieu de créer une classe juste pour injecter le mock, nous pouvons maintenant fournir directement notre mock grâce au contructeur.

    @Test
    public void testDoSomethingWithOrder() {
    	OrderFacade orderFacade = new FailingToCreateOrderFacadeStub();
    	NewOrderController controller = new NewOrderController(orderFacade);
    	boolean orderCreatingSucceded = controller.doSomethingWithOrder(
    		new Client(), new Order());
    	Assert.assertFalse(orderCreatingSucceded);
    }
    
     
  • Quentin 22:23 le 16 March 2011 Permalien | Réponse
    Tags : ,   

    NUnit : les assertions qui parlent. 

    Une des choses qui me semblent la plus importante en développement est le test d’une application. Comment je pourrais être sur du comportement d’une application si je ne la teste pas. Malgré tout, la qualité des tests est très différente en fonction du langage utilisé. Personnellement, j’aime quand mes tests « parlent« .

    Comme de nombreux frameworks de test, NUnit a commencé comme un portage de JUnit. Pourtant à un moment de son histoire, il a su s’en écarter pour évoluer. Prenons un exemple simple pour bien comprendre l’idée, une simple assertion en JUnit puis en NUnit.

    Version JUnit :

    assertEquals(2+2, 4);
    

    Version NUnit :

    Assert.AreEqual(2+2, 4);
    

    Bon, au final pas trop de différences. Comme je le disais, NUnit a commencé comme une traduction. Il est donc normal qu’il se ressemble fortement. Mais NUnit propose une autre syntaxe que je préfère grandement.

    Autre version NUnit :

    Assert.That(2+2, Is.EqualTo(4));
    

    Avant d’aller plus loin, je précise que je sais que cette version est plus verbeuse. La ligne de code est plus longue, plus de parenthèses… Pourtant, je trouve qu’on y gagne beaucoup. Si on transforme un peu cette ligne en retirant le superflu, on obtient la phase :

    Assert that 2+2 is equal to 4.

    Une phrase syntaxiquement correcte en anglais qui a du sens.Plutôt que de comprendre le code, il suffit de le lire comme s’il s’agissait d’une phrase.

    D’autres frameworks de test permettent de représenter les tests comme des phrases. Je pense par exemple à Machine.Specification qui utilise intelligemment les lambdas pour ses tests. De manière général, les frameworks de BDD font en sorte de traduire une « histoire » par du code.

     
  • Quentin 20:40 le 17 November 2010 Permalien | Réponse
    Tags : , ruby,   

    Continious Testing avec Watchr 

    Je suis quelqu’un de très fainéant (c’est un problème ?) et je cherche donc toujours à optimiser mes efforts de travail. Taper une combinaison de touche pour lancer des tests, c’est trop long. Je cherchais donc quelque chose de plus efficace.

    J’ai découvert Watchr qui est un outils flexible développer en Ruby avec lequel on peut lancer des tests (ou autres chose) en continue et voir les résultats. Watchr est simple d’usage. Il lance un script quand vous sauvegardez un des fichiers qu’il observe.

    Exemple de sortie de test - Source : rubyinside.com

    Ce sont des pratiques qui proviennent du monde agile et des approches de développement TDD / Red-Green-Refactor. On lance ces tests en continue pour savoir sans attendre si on casse quelque chose. J’ai beaucoup de mal à retrouver ce type d’outils dans d’autres types de projet comme .net et java.

    Ma solution a donc été d’utiliser Watchr et d’écrire un script ruby qui prend la forme suivante :

     
    watch ("pattern") do |match|
     	do something ... 
    end 
    

    Maintenant qu’on a la template de base, je vais vous donner un exemple simple pour F#. L’idée est d’écrire un bout de code dans un fichier .fsx (fichier de script) et de lancer automatique le code.

     
    watch ("^.*.fs(x?)$") do |match| # On écoute tous les fichiers .fs et .fsx
     	fsi fichier.fsx		 # On interprète le fichier contenant le script 
    end 
    

    Revenons maintenant à mon problème de départ qui est de lancer mes tests Nunit en continue. Pour cela, j’ai cherché comment compiler mes sources à partir du script Ruby. J’ai fini par me tourner vers une solution utilisant Rake + Albacore qui va décrire mon processus de compilation. Rake est un system de build pour Ruby et Albacore une extension développée par Derick Bailey pour MSBuild.

     
    require 'albacore' 
    #Albacore::log_level = :verbose  
    task :default => ['tests:test']  
    namespace :tests do
         desc "Build using Albacore"
         msbuild :build do |msb|     
             # path_to_command is optional but I needed to change it for F#
             msb.path_to_command = "C:/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe"    
             msb.properties :configuration => :Debug
             msb.targets :Build
             msb.solution = "project.sln"
             msb.verbosity = "quiet"
             msb.parameters "/nologo"
        end 
        desc "Run tests with Nunit"
        nunit :test => [:build] do |nunit|
            nunit.path_to_command = "/nunit-console-x86.exe"     
            nunit.assemblies "./project/bin/Debug/project.dll"
            nunit.options '/xml=results.xml'   
        end 
    end 
    

    Ce script Rake me permet de compiler mon programme, de lancer les tests avec Nunit ce qui génère un fichier xml avec le résultat des tests. Le script Watchr va ensuite lire le xml pour afficher les tests qui échouent ou un message indiquant que tout va bien.

     
    require 'rexml/document'
    require 'colored'
    begin
      require 'win32console' if RUBY_PLATFORM =~ /w*32/
    rescue LoadError
      raise 'You must gem install win32console to use color on Windows'
    end
    
    # Run test when a F# file has been modified
    watch( '^.*.fs$') do |match|
      system 'cls'
    
      # Build project and check if build succeded
      build = system 'rake tests:build'
      if build then
        # Run tests
        system 'rake tests:test'
        show_results if File.file? 'results.xml'
      end
    end
    
    # Display tests result
    # I'm just doing some xml parsing and print to the console
    def show_results
      system 'cls'    
      result_file = File.new('results.xml')
      doc = REXML::Document.new result_file
    
      nb_failure = REXML::XPath.match(doc, '//test-case[@success="False"]').count
    
      if nb_failure == 0 then
          puts "All tests are green !".on_green.white
    
          puts
          REXML::XPath.each(doc, '//test-case') do |test|
             puts test.attributes['name'].on_green 
          end
      else
          puts "#{nb_failure} test have failed ! Fix this immediately !".on_red
          REXML::XPath.each(doc, '//failure') do |fail|
              message = fail.elements.each("message"){|m| m}.first.text 
              stack = fail.elements.each("stack-trace"){|m| m}.first.text
    
              puts
              puts "Message #{message}".on_red
              puts "StackTrace : #{stack}".on_red
    
          end
      end
    end 
    

    Vous pouvez voir ci-dessous des exemples de sortie dans les deux cas, échec et succès.

     
  • Quentin 22:04 le 3 November 2010 Permalien | Réponse
    Tags :   

    Session PDC 2010 

    La Keynote : toujours aussi intéressant. Donne la vision global de Microsoft. Cette année, beaucoup de cloud computing et de Windows Phone.

    Building Windows Phone 7 applications with the Windows Azure Platform : Très bonne session sur le développement d’une application avec un coté serveur dans le cloud. Les exemples proposés sont simples et pertinents. Utile pour toutes les personnes qui voudraient développer une application mais qui n’a pas beaucoup de moyen.

    The Future of C# and Visual Basic : Une introduction impressionnante aux nouveaux mots clés async et await. Ces 2 mots clés rendent le développement parallèle beaucoup plus simple. J’essaierais d’écrire un article dessus. Contrairement au titre, je n’ai pas vu de VB. C’est surement dû au fait que VB et C# suive la même ligne directrice à présent.

    The Future of F#: Data and Services at your Finger Tips : Notre monde est de plus en plus riche en information. Les langages ont besoins de devenir plus souple face aux différentes sources de données (xml, json, wmi, …). F# règle le problème avec des Types Providers. Ceux-ci ajoutent des types de données (namespace et classe) dynamiquement. Le tout peut être couplé avec le nouveau DataMarket disponible dans Windows Azure.

    LINQ, Take Two – Realizing the LINQ to Everything Dream : La session semblait intéressant mais je dormais à moitié donc je ne saurais pas trop dire. J’ai trouvé les concepts trop survolés pour être bien compris.

    Je continue de regarder les sessions et je vous tiendrais au courant des sessions qui sont intéressantes.

     
  • Quentin 22:28 le 27 October 2010 Permalien | Réponse
    Tags :   

    Je viens juste de réaliser que la PDC 2010 allait commencer dans quelques heures maintenant. Je suis en ce moment même en train de regarder une des sessions de l’année passée sur le langage de modélisation M.

    J’en profite donc pour donner mes centres d’intérêts pour cette année :

    1. Fsharp
    2. Langage M / Oslo (je ne suis pas sûr qu’ils en parlent)
    3. Windows Phone 7

    Si je fais comme l’année dernière, je vais surement regarder des dizaines de sessions plus intéressantes les unes que les autres. Et moi qui me plains toujours de ne pas avoir assez de temps, je dois le faire exprès.

    Pour ceux qui voudraient retrouver des vidéos des sessions 2009, vous y aurez accès sur le site de la PDC ici.

     
  • Quentin 19:10 le 12 October 2010 Permalien | Réponse
    Tags :   

    Autotest – une solution 

    Je suis un grand fan de TDD et j’aime voir rapidement si mes tests passent (ou pas).

    J’ai découvert AutoTest il y a quelques années, quand je m’intéressais au Ruby. Il s’agit d’un outils qui va exécuter vos tests automatiquement, ce qui vous permet de savoir directement si le test est validé.

    Des outils comparables existent en .Net. J’ai passé la semaine dernière à essayer de les faire fonctionner, sans grand succès. J’ai donc essayer de voir si je pouvais utiliser AutoTest directement pour exécuter mes tests en .Net. A la place, je me suis rabattu vers Watchr, un gem ruby qui permet d’exécuter des scripts quand un fichier à été sauvegardé.

    Vous aurez donc droit dans quelques jours à une solution qui fonctionne. En attendant, vous pouvez toujours découvrir Watchr sur GitHub.

     
  • Quentin 19:44 le 2 October 2010 Permalien | Réponse
    Tags : fsharp   

    FSharp et le pattern matching 

    Je m’intéresse un peu à la programmation fonctionnelle en ce moment et une des fonctionnalités que je trouve très intéressante est le pattern matching.

    Pour faire comprendre l’intérêt, prenons un exemple classique : la fonction Factorielle.

    Exemple de Pattern matching

    En C # :

    public class Factorielle
    {
        public static int fact(int n)
        {
            if (n == 0)
            {
                return 1;
            }
            else
            {
                return n*fact(n - 1);
            }
        }
    }
    

    En F# :

    let rec fact n =
        match n with
        | 0 -> 1
        | _ -> n * fact(n-1)
    

    ou encore plus court :

    let rec fact = function
        | 0 -> 1
        | x -> x * fact(x-1)
    

    Pour commencer, un avantage de F# est de n’avoir besoin de définir que la fonction.
    En C#, rien que pour la fonction factorielle, on doit :

    • créer une classe,
    • définir la déclaration de la fonction,
    • préciser qu’elle est public …

    Si on regarde bien, on voit aussi qu’on ajoute beaucoup de parenthèses et d’accolades pour pas grand-chose. En théorie, si le code est bien écrit, les accolades ne devraient servir à rien. On devrait pouvoir facilement voir où sont les blocs de code.

    En gros, on se retrouve avec un code plein de bruit.

    Pourtant, tout ce qui est important dans la fonction factorielle, c’est qu’en lui transmettant 0, on veut comme résultat 1 et pour les autres cas, on veut n * fact(n-1).

    En F#, on se concentre sur l’essentiel.

    Pattern matching sur une liste

    Pour continuer sur le pattern matching, on va créer une fonction qui va faire la somme des éléments d’une liste.

    Pour implémenter ça, on a deux cas à prendre en compte : une liste vide et les autres cas. Pour la liste vide, on renvoi 0 et dans les autres cas, on retourne la somme de la tête de la liste et la somme du reste de la liste.

    // xs est la liste à additionner.
    let rec sum xs =
        match xs with
        | [] -> 0
        | head::tail -> head + sum tail
    

    Dans ce cas, on créer un pattern head::tail et F# va de débrouiller pour extraire les données de la liste suivant la définition de la fonction cons : (::) -> a -> [a] -> [a]; ce qui ce traduirait par une fonction générique en C#, List<T> operator ::(this T el, List<T> xs).

    Pour bien comprendre ça, on peut voir comment construire un liste de plusieurs façons :

    [1..5]
    = [1,2,3,4,5]
    = 1 :: [2,3,4,5]
    = 1 :: 2 :: [3,4,5]
    ...
    1 :: 2 :: 3 :: 4 :: 5 :: []
    

    Toutes les syntaxes ci-dessus sont équivalentes. Dans la ligne 6, on utilise l’opérateur cons (::) pour créer une liste en ajoutant des éléments à la liste vide. Si on donne la liste [1,2,3,4,5] à la fonction sum, celle-ci va décomposer la liste en suivant le principe inverse.

    Pattern matching sur plusieurs arguments

    C’est la partie du pattern matching que je trouve la plus intéressante. On peut facilement prendre en compte plusieurs arguments pour le pattern.

    let mafonction a b =
        match a,b with
        | _,0 -> 0
        | 0,_ -> 0
        | _ -> a + b;;
    

    Même si le code produit en fsharp est plus consit et expréssif qu’en C#, j’aurai aimé avoir une syntaxe comme en Haskell. En prenant pour exemple la fonction factorielle :

    fact 0 = 1
    fact n = n * fact(n-1)
    

    Pour finir, je vous conseille le site Wikibooks > F Sharp Programming pour en apprendre plus sur le langage. Vous trouverez plus d’information sur F# en général mais aussi sur le pattern matching.

     
  • Quentin 19:18 le 1 October 2010 Permalien | Réponse  

    Hello world! 

    Hello World !

    Source : Wikipedia

    WordPress a décidé de nommer mon premier article Hello World! et je pense que le nom est bien choisi.

    Je vais donc essayer de me présenter :

    Je m’appelle Quentin Proust, je suis des études d’ingénieur en informatique et je passe le plus clair de mon temps à expérimenter sur des technologies ou des concepts.

    Je suis plutôt orienté technologie Microsoft et j’ai été accepté en tant que MSP cette année.

    Hello World !

    C’est un nom qui est bien choisi. Dans ce blog, je vais surtout parler des découvertes que je fais dans mes expériences quotidiennes avec des logiciels, des langages et des notions de développement.

    Voilà dans les grandes lignes ! See you soon.

     
c
créer un nouvel article
j
message/commentaire suivant
k
message/commentaire précédent
r
Réponse
e
Modifier
o
afficher/masquer les commentaires
t
remonter
l
connexion
h
afficher/masquer l'aide
shift + esc
Annuler
Suivre

Recevez les nouvelles publications par mail.

%d blogueurs aiment cette page :