Barre horizontale de naviagtion

mardi 30 mars 2010

linq


List lstComm = COMMUNE_DAO.GetAll().Where(comm => comm.Id_pays == 5).ToList();
List lstCanton = CANTON_DAO.GetAll().ToList();

var res = from com in lstComm
join can in lstCanton on com.Code_canton equals can.Code_canton
select new
{
com.Nomcom,
code_contonCommune=com.Code_canton ,
code_contonCanton=can.Code_canton ,
can.Nomcant
};

foreach (var elem in res)
{
string chaine =elem.Nomcant + elem.Nomcom ;
string test = elem.code_contonCanton + elem.code_contonCommune;
}

Linq 2




List lstComm = COMMUNE_DAO.GetAll().Where(comm => comm.Id_pays == 5).ToList();
List lstCanton = CANTON_DAO.GetAll().ToList();

var res = from com in lstComm
join can in lstCanton on com.Code_canton equals can.Code_canton
select new
{
com.Nomcom,
can.Nomcant
};

foreach (var elem in res)
{
string chaine =elem.Nomcant + elem.Nomcom ;
}

Linq

List lstComm = COMMUNE_DAO.GetAll().Where(comm => comm.Id_pays == 5).ToList();

List lstCanton = CANTON_DAO.GetAll().ToList();



var res = from com in lstComm

join can in lstCanton on com.Code_canton equals can.Code_canton

select new

{

com.Nomcom,

can.Nomcant

};



foreach (var elem in res)

{

string chaine =elem.Nomcant + elem.Nomcom ;

}

jeudi 11 mars 2010

Introduction aux tests unitaires avec Visual Studio 2008

Introduction aux tests unitaires avec Visual Studio 2008
Introduction
Les tests unitaires sont un moyen très efficace pour tester le code que vous écrivez. Bien que très puissant et surtout très utiles tout au long du développement d’une application, ceux-ci sont encore trop peu utilisés. Il est vrai que c’est un sujet qui a été souvent abordés sur les blogs mais encore trop peu de gens font des tests unitaires afin de tester leurs applications, c’est pourquoi j’ai décidé de faire ce billet.
Il existe plusieurs moyens de réaliser des tests unitaires. Parmi ceux-ci on pourra citer le Framework de tests NUnit ou tout simplement le Framework fournit par Visual Studio à partir de la version professionnelle (pour un rappel des différentes versions de Visual Studio, rendez-vous sur cette page).
Dans ce billet, nous allons nous intéresser aux outils fournits par Visual Studio pour introduire le concept de test unitaire.
Il est possible d’utiliser ces derniers dans plusieurs cas de figure. Le cas le plus courant, et tout simplement pour tester une application que l’on développe : on souhaite s’assurer qu’une méthode retourne le résultat attendu en fonction des paramètres qui lui sont passés.
Un autre cas possible d’utilisation des tests unitaires est le « Test Driven Development » qui lui consiste en l’écriture des tests au fur et à mesure que l’on développe l’application. Ainsi, c’est le test qui nous permet de développer nos classes, méthodes…La technique de « Test Driven Development » sera largement mise en avant dans la future version de votre IDE favoris : Visual Studio 2010.
Sans plus attendre, rentrons dans le vif du sujet et commençons à nous intéresser au Framework de test fournit par Visual Studio 2008.
Les outils de test de Visual Studio 2008
La première étape pour créer des tests unitaires sous Visual Studio consiste en la création d’un projet de tests, comme le montre l’écran ci-dessous :

Le Template de test Visual Studio vous générera alors toute une solution possédant directement une référence vers la librairie Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll, sur laquelle nous aurons l’occasion de nous pencher dans quelques lignes.
Trois fichiers sont également crées avec le projet de test :
• AuthoringTests.txt : ce fichier texte présente tout simplement les grandes lignes et concepts de la mise en place et de l’exécution de tests unitaires
• ManualTest1.mht : ouvrable dans un éditeur de texte tel que Word, ce fichier au format MHTML fournit tout simplement un exemple de Template pour faire faire des tests manuels aux utilisateurs de votre application. Ici, nous ne nous intéresserons pas aux tests manuels, mais bien aux tests unitaires automatisés.
• UnitTest1.cs : Fichier de code nous permettant d’écrire une première classe de tests unitaires.
Pour bien comprendre ce que sont les tests unitaires, nous allons supprimer ces 3 fichiers et créer notre propre classe de tests en détaillant bien toutes les étapes. Une fois les fichiers supprimés, ajoutez une nouvelle classe au projet :

Tout est à présent prêt pour accueillir nos premiers codes de tests. Avant cela, prenons le temps de nous intéresser à la bibliothèque de classe Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll suscitée.
Les classes de tests de Visual Studio
Le principal espace de noms qui va nous intéresser pour cette introduction aux tests unitaires est Microsoft.VisualStudio.TestTools.UnitTesting.
La principale classe que nous allons utiliser dans cet espace de noms est la classe statique Assert qui comme son nom l’indique va nous permettre de réaliser des assertions dans nos méthodes de tests.
Note: une assertion consiste à donner une proposition comme vrai, par exemple le retour de la méthode SayHello est « HelloWorld », et de s’assurer que c’est vraiment le cas.
La classe Assert possède une multitude de méthode statique permettant d’effectuer des assertions. Parmi celles-ci on retrouve IsTrue, IsFalse, IsNotNull…Pour une liste complète des méthodes disponibles, rendez-vous sur cette page. Nous verrons dans la suite comment utiliser celles-ci.
Vous retrouverez également de nombreux attributs dans cet espace de noms. Parmi ceux-ci, nous pouvons en citer deux que vous manipulerez à coup sûr lors de la création de vos premiers tests :
• TestClassAttribute: cet attribut ne peut être déclaré qu’au dessus de la définition d’une classe et permet tout simplement d’identifier une classe du projet comme étant une classe de tests. Toute classe ornée de cet attribut sera ainsi évaluée lors de l’exécution du projet de tests par Visual Studio.
• TestMethodAttribute: cet attribut ne peut être déclaré qu’au dessus de la définition d’une méthode et permet tout simplement d’identifier une méthode définie dans une classe de test comme étant un test à exécuter par Visual Studio.
Ainsi, toutes vos différentes classes de test seront surplombées de l’attribut TestClassAttribute et les seules méthodes qui seront exécutées comme test unitaire seront celles précédées de l’attribut TestMethodAttribute.
Deux autres attributs pourront être utiles dans certains cas : TestInitializeAttribute et TestCleanupAttribute qui précéderont des méthodes permettant d’initialiser et restaurer l’environnement de test, respectivement. Les méthodes surplombées de ces deux attributs seront exécutés avant et après que les méthodes de test soient exécutées, respectivement.
Nous terminerons cette présentation rapide des classes permettant de réaliser des tests unitaires avec Visual Studio en parlant de la classe TestContext. Comme son nom l’indique, cette classe va permettre de récupérer le contexte dans lequel est exécuté le test unitaire. Pour être plus précis, il s’agit de récupérer des informations sur le test en cours (chemin du répertoire de déploiement, chemin du répertoire de logs…). Pour pouvoir récupérer une instance de TestContext, il vous suffit de définir une propriété de type TestContext nommée TestContext dans votre classe de test. Elle sera alors automatiquement instanciée.
Après cet aperçu très théorique des tests unitaires, nous allons passer – enfin, diront certains –à l’écriture de notre classe de test.
Première classe de test
Commençons par mettre en place la structure de notre classe de test :
1: [TestClass]
2: public class MyFirstTestClass
3: {
4: private TestContext testContext;
5:
6: public TestContext TestContext
7: {
8: get { return testContext; }
9: set { testContext = value; }
10: }
11:
12: [TestInitialize]
13: public void InitTest()
14: {
15:
16: }
17:
18: [TestMethod]
19: public void FirstTestMethod()
20: {
21:
22: }
23:
24: [TestCleanup]
25: public void EndTest()
26: {
27:
28: }
29: }
Si à ce stade vous placez des points d’arrêts au début de chaque méthode InitTest, FirstTestMethod et EndTest et que vous exécutez le tests (via le menu Debug, Start Debugging ou en appuyant sur F5) vous constaterez ce que nous avons vu dans la partie précédente à propos des 3 attributs mis en jeu.
Comment se passe un test ?
Cette question est tout à fait légitime à ce stade de la lecture. En effet, nous avons parlé d’assertions quelques lignes plus haut. Vous aurez compris que celles-ci vont être faites dans les méthodes de tests, ici dans la méthode FirstTestMethod :
1: [TestMethod]
2: public void FirstTestMethod()
3: {
4: //première assertion : on crée une instance de DateTime,
5: //elle est du type DateTime
6: Assert.IsInstanceOfType(DateTime.Now, typeof(DateTime));
7: }

La méthode static IsInstanceOfType de la classe Assert nous permet de tester que le type de l’instance passée en premier paramètre et bien conforme au second paramètre.
Si vous exécutez ce test en faisant F5, vous ne serez pas surpris de voir qu’il passe sans problème :

Ecrivons une deuxième assertion, fausse cette fois ci :
1: [TestMethod]
2: public void FirstTestMethod()
3: {
4: //première assertion : on crée une instance de DateTime,
5: //elle est du type DateTime
6: Assert.IsInstanceOfType(DateTime.Now, typeof(DateTime));
7:
8: //Deuxième assertion : "Hello" est égale à "Hello World"
9: Assert.AreEqual("Hello World", "Hello");
10: }
Si vous exécutez à nouveau le test, vous constaterez que comme nous l’avions prévu, celui si ne passe pas :

Remarquez au passage que le message d’erreur est assez explicite. Nous avions fait l’assertion d’obtenir “Hello World” alors que nous passons la valeur “Hello”.
Ce message d’erreur est personnalisable. En effet, toutes les méthodes de la classe Assert définissent une surcharge permettant de personnaliser le message d’erreur retourné dans le cas où l’assertion n’est pas vérifiée :
1: [TestMethod]
2: public void FirstTestMethod()
3: {
4: //première assertion : on crée une instance de DateTime,
5: //elle est du type DateTime
6: Assert.IsInstanceOfType(DateTime.Now, typeof(DateTime));
7:
8: //Deuxième assertion : "Hello" est égale à "Hello World"
9: Assert.AreEqual("Hello World", "Hello","Hello != Hello World");
10: }

Si vous exécutez le test vous obtenez alors votre message d’erreur personnalisé :

Bien sûr nous utilisons ici des exemples très simples, mais il est tout à fait possible de pousser très loin les méthodes de tests.
Maintenant que vous avez compris les grandes lignes de la création de tests unitaires, intéressons nous au cas du test d’un librairie dans laquelles vous auriez définie des entités métiers.
Etude d’un cas réel
Créez un nouveau projet de type bibliothèque de classe. Notre librairie est composée d’une classe abstraite Employee définissant 3 propriétés de type string : Name, FirstName et City. Elle défini aussi deux méthodes abstraites : Work et SayHello. Ces deux méthodes ont un retour de type string. La classe abstraite Employee est implémentée par les classes Pilot et Technician :

Code de l’implémentation pour la classe Pilot :
1: public class Pilot : Employee
2: {
3: public override string Work()
4: {
5: return String.Format("The pilot {0} {1} is working...",
6: this.FirstName, this.Name);
7: }
8:
9: public override string SayHello()
10: {
11: return String.Format("Hello I'm {0} {1} and I'm a pilot",
12: this.FirstName, this.Name);
13: }
14: }
Et pour la classe Technician :
1: public class Technician : Employee
2: {
3: public override string Work()
4: {
5: return String.Format("The technician {0} {1} is working...",
6: this.FirstName, this.Name);
7: }
8:
9: public override string SayHello()
10: {
11: return String.Format("Hello I'm {0} {1} and I'm a technician",
12: this.FirstName, this.Name);
13: }
14: }

Nous souhaitons maintenant tester ces 4 méthodes afin de s’assurer que leur comportement est bon sur différentes instances de Technician et Pilot.
La logique voudrait que nous écrivions au minimum une méthode de test pour chaque méthode, soit ici 4. Dans un projet plus conséquent ce chiffre peut atteindre des milliers de méthodes à écrire. Pour cela Visual Studio nous facilite quelque peu la tâche, puisqu’il va nous permettre de générer la structure de nos classes de tests comme nous l’avons fait étape par étape au début de ce billet.
Pour se faire, commencez par ajouter une référence vers la librairie fraîchement créée au sein de votre projet de test puis ajoutez un nouvel item de type “Unit test”:

Un assistant s’ouvre alors à vous et vous permet de choisir les méthodes que vous souhaitez tester dans les assemblages référencés :

Nous choisissons ici de tester les méthodes SayHello et Work des classes Technician et Pilot. Le bouton “Settings…” vous permet de définir quelques options pour le code qui va être généré par Visual Studio :

Note : [Class] sera remplacé par le nom de la classe testée et [Method] par le nom de la méthode testée.
Après avoir validé ce petit assistant, vous verrez apparaître deux fichiers dans votre projet de test : PilotTest.cs et TechnicianTest.cs :

Ces fichiers contiennent respectivement les classes de test PilotTest et TechnicianTest (précédée de l’attribut TestClass) et chacune deux méthodes de test WorkTest et SayHelloTest (précédées de l’attribut TestMethod).
Vous remarquerez que Visual Studio génére du code dans ces classes en prenant en compte le type de retour de la méthode.
Vous remarquerez que toutes les méthodes se termine par l’appel de la méthode “Inconclusive” sur la classe Assert. Cet appel permet tout simplement de dire que si le test réussi, il ne faut pas tirer de conclusion trop attive car il s’agit de code généré :

Nous retirerons ces appels une fois les méthodes de test écrites. Ce qui pourrait donner pour la classe TechnicianTest :
1: ///
2: ///A test for Work
3: ///

4: [TestMethod()]
5: public void WorkTest()
6: {
7: Technician target = new Technician();
8: target.FirstName = "Julien";
9: target.Name = "Corioland";
10: string expected = "The technician Julien Corioland is working...";
11: string actual;
12: actual = target.Work();
13: Assert.AreEqual(expected, actual);
14: }
15:
16: ///
17: ///A test for SayHello
18: ///

19: [TestMethod()]
20: public void SayHelloTest()
21: {
22: Technician target = new Technician();
23: target.FirstName = "Julien";
24: target.Name = "Corioland";
25: string expected = "Hello I'm Julien Corioland and I'm a technician";
26: string actual;
27: actual = target.SayHello();
28: Assert.AreEqual(expected, actual);
29: }

Si nous exécutons le projet à ce stade de l’écriture des méthodes de test, nous obtenons bien 2 tests réussis sur 4 :

Nous pourrions faire de même pour la classe Pilot afin de nous assurer du bon fonctionnement de nos méthodes !
Conclusion
Cet article avait pour but d’expliquer les fondamentaux des tests unitaires avec Visual Studio qui permettront à chacun d’entre vous de bien démarrer dans cette discipline. N’oubliez pas que les tests unitaires sont le meilleur moyen de tester vos applications afin qu’elles soient le plus robuste possible.
Bien sûr nous n’avons vu ici qu’une infime partie partie du domaine des tests et il faut garder à l’esprit qu’il existe et existera (surtout dans Visual Studio 2010) beaucoup d’outils pour tester vos applications, mais aussi générer des données aléatoires ou encore créer des batteries et enchaînements de tests automatisés.
J’espère que ce billet donnera envie aux plus réfractaires d’entre-vous de se lancer dans les tests unitaires !
A bientôt
Sources : UnitTestSamples.zip (164.71 kb)