Problèmes avec l'attribut DeploymentItem

94

Je maintiens actuellement un "ancien" système écrit en C # .net, supprimant certaines fonctionnalités obsolètes et faisant quelques refactorisations. Merci mon Dieu, le gars précédent a écrit des tests unitaires (MSTests). Je suis assez à l'aise avec les tests JUnit, mais je n'ai pas encore fait grand chose avec les tests MST.

Les méthodes de test ont un DeploymentItemattribut, spécifiant un fichier texte qui est analysé par la méthode de logique métier qui est testée et un 2ème DeploymentItemoù juste un chemin a été spécifié contenant un tas de fichiers TIF qui doivent également être déployés.

[TestMethod()]
[DeploymentItem(@"files\valid\valid_entries.txt")]
[DeploymentItem(@"files\tif\")]
public void ExistsTifTest()
{
   ...
}

Les tests fonctionnaient auparavant, mais maintenant je devais changer les noms des fichiers TIF contenus dans le répertoire \ files \ tif. Selon une règle, les noms de fichiers TIF doivent correspondre à un certain modèle qui est également vérifié par la ExistsTifTest()méthode. Maintenant, j'ai dû changer les noms de fichiers afin de les adapter aux nouvelles exigences et soudainement les fichiers TIF ne sont plus déployés comme avant.

Quelqu'un peut-il me dire pourquoi cela se produit ou quelle peut en être la cause? La même chose se produit également si j'ajoute un nouveau fichier texte dit "my2ndTest.txt" à côté du "valid_entries.txt" dans le répertoire \ files \ valid \ avec l'attribut DeploymentItem correspondant sur la méthode de test. Le fichier n'est pas déployé?

J'ai maintenant déployé les images en définissant le chemin de déploiement directement dans le testrunconfig, mais j'aimerais comprendre pourquoi ces choses se produisent ou pourquoi par exemple mon nouveau fichier "my2ndTest.txt" n'est pas déployé alors que les autres le font.

Juri
la source
2
Un gros problème ici est de réaliser que tous les éléments spécifiés dans DeploymentItemAttribute seront copiés vers l'emplacement d'où vos assemblys de test s'exécutent. En d'autres termes, si vous espériez que cela préservera votre structure de répertoires, vous n'aurez pas de chance. Si vous avez besoin de le copier dans un répertoire spécifique, utilisez la version à deux paramètres DeploymentItem (source, outputDir). FYI - vous pouvez aller à l'ancienne pour savoir où les fichiers sont exécutés pour MsTest en déposant dans un System.Console.WriteLine (System.Environment.CurrentDirectory) dans l'un de vos tests. NCrunch n'a pas eu ce problème!
CodeMonkeyKing

Réponses:

111

DeploymentItem est un peu en désordre.

Chaque fichier de votre solution aura un paramètre «Copier dans le dossier de sortie» dans VS.NET. Vous avez besoin que ce soit "Copier toujours" (ou similaire) afin d'obtenir les fichiers dans le dossier de sortie.

Vérifiez que vous disposez de cet ensemble pour les nouveaux fichiers. Si vous ne disposez pas de cet ensemble, les fichiers ne seront pas copiés dans le dossier de sortie et ne pourront pas être déployés du dossier de sortie vers le dossier dans lequel MSTest s'occupe de tout.

Personnellement, si j'ai des fichiers dont j'ai besoin pour mes tests unitaires, j'ai trouvé qu'incorporer ces fichiers en tant que ressources dans un assembly, et avoir cet assembly "décompressé" lui-même pendant les tests est une façon plus prévisible de faire les choses. YMMV.

Remarque: ces commentaires sont basés sur mon expérience avec VS2010. Les commentaires à ma réponse suggèrent que ce n'est pas un problème avec VS2012. Je reste fidèle aux commentaires selon lesquels l'utilisation de ressources embarquées implique moins de «magie» et, pour moi, rend l'étape «organiser» de mes tests unitaires beaucoup plus explicite.

Martin Peck
la source
3
La copie dans le répertoire de sortie n'affecte jamais la façon dont MSTest déploie les fichiers. Cette réponse est incorrecte.
kzu
19
Sur VS2010 Premium, cette modification (et aucune autre modification) entraînait le déploiement du fichier. Ainsi, je conclus sur la base de preuves réelles que cela affecte le déploiement de MsTest.
JonStonecash
1
D'accord. J'ai vu ce changement unique tourner DeploymentItem à l'envers.
Martin Peck
2
Cela ne semble plus nécessaire sur VS2012. Mes éléments de déploiement sont en cours de déploiement avec «Copier dans le dossier de sortie» défini sur «Ne pas copier».
Mike
29
C'est formidable de voir comment DeploymentItem ne vous avertit pas lorsqu'il est incapable de copier le fichier unique que vous l'avez fourni.
74

Dans VS2010, mes Local.testsettings avaient la case «Activer le déploiement» décochée et l'attribut DeploymentItem ne fonctionnait pas. Je l'ai vérifié et tout a bien fonctionné. J'espère que ça aide!

Ivan Muzzolini
la source
2
Je me cogne la tête contre un mur de briques depuis des lustres en essayant de le faire fonctionner ... merci!
mat-mcloughlin
12
Je pense que cela aurait été bien si le cadre émettait un avertissement indiquant que les attributs DeploymentItem sont ignorés si ce paramètre est désactivé. J'ai également mis une belle impression concave dans mon bureau.
Alan McBee - MSFT
2
Notez que Local.testsettings est dans les éléments de la solution
Matthew Lock
J'ai également dû ajouter le répertoire contenant les éléments que je voulais déployer dans Local.testsettings également: i.imgur.com/p1z3m9R.png
Matthew Lock
L'utilisation de VS2017 en 2018 en cochant `` Activer le déploiement '' est toujours la solution à ce problème. Et malheureusement encore maintenant un avertissement de Visual Studio. Alors merci pour cette solution.
Don H le
19

J'ai également rencontré des problèmes similaires, mais j'ai trouvé une solution simple en 3 étapes pour cela:

En supposant que la structure de vos dossiers ressemble à ceci: SolutionFolder\ TestProjectFolder\ SubFolder\

  1. Allez dans «Solutions Items / Local.testsettings»> «Deployment»> Cochez «Enable Deployment»
  2. Si vous utilisez VS2010, assurez-vous que tous les fichiers que vous souhaitez déployer ont leur propriété «Copier dans le dossier de sortie» définie sur «Copier toujours» ou «Copier si plus récent»
  3. Attribuez votre TestMethod avec l'un des éléments suivants:
    • [DeploymentItem(@"TestProjectFolder\SubFolder")]pour déployer tout le contenu de <SubFolder>dans le répertoire Test Run
    • [DeploymentItem(@"TestProjectFolder\SubFolder", "TargetFolder")] pour déployer tout le contenu de <SubFolder>to <TargetFolder>dans le répertoire Test Run

Une dernière remarque sur MSTest (au moins pour VS2010):

Si vous voulez que le <TargetFolder>ait le même nom que le <SubFolder>, l'utilisation [DeploymentItem(@"SubFolder", @"SubFolder")]échouera silencieusement lorsque le coureur MSTest rencontre un cas de bord idiot. C'est pourquoi vous devez préfixer le <SubFolder>avec le <TestProjectFolder>comme tel:[DeploymentItem(@"TestProjectFolder\SubFolder", @"SubFolder")]

Murari Kumar
la source
La note sur l'échec de la dénomination du sous-dossier est un joyau.
RJ Lohan
1
VS 2015 semble être un peu différent. J'avais besoin de supprimer la partie "TestPojectFolder" dans l'attribut DeploymentItem.
uli78
15

Pour nous l' espérons aider quelqu'un d' autre: j'ai essayé toutes les suggestions ici et encore mon point de déploiement était pas recopié.

Ce que je devais faire ( comme suggéré ici ) était d'ajouter un deuxième paramètre à l'attribut DeploymentItem:

[DeploymentItem(@"UnitTestData\TestData.xml", "UnitTestData")]
Peter K.
la source
10

Si vous allez dans votre fichier .testrunconfig et sous déploiement, décochez "Activer le déploiement", les tests s'exécuteront dans leur emplacement normal et tout fonctionnera comme il le fait lors de l'exécution de l'application en dehors d'un test unitaire.

Josh Fermer
la source
J'ai également eu des problèmes avec cela. En tant que PM, je n'ai pas accès à tous les outils utilisés par les développeurs. Dans ce cas, ReSharper a copié le fichier correctement alors que MSTest n'a pas réussi à le faire. -> J'ai rencontré des erreurs alors que le développement était OK. Changez pour «Test-> Modifier les paramètres de test -> Paramètres locaux -> Déploiement», y compris le fichier en question, a corrigé ce problème pour mon utilisation MSTest.
sonstabo
9

Cela ne concerne probablement pas votre problème exact, mais voici quelques conseils que j'ai trouvés avec l'attribut [DeploymentItem].

  1. Copier dans le répertoire de sortie doit être défini sur Copier toujours.

Il ne fonctionne PAS lorsqu'il est utilisé avec l'attribut [TestInitialize]

[TestInitialize]
[DeploymentItem("test.xlsx")]
public void Setup()
{

Il devrait être sur votre [TestMethod], par exemple

    [TestInitialize]
    public void Setup()
    {
        string spreadsheet = Path.GetFullPath("test.xlsx");
        Assert.IsTrue(File.Exists(spreadsheet));
        ...
    }

    [TestMethod]
    [DeploymentItem("test.xlsx")]
    public void ExcelQuestionParser_Reads_XmlElements()
    {
        ...
    }
Matt Frear
la source
1
C'est une limitation incroyablement ennuyeuse. J'ai l'impression que dans de nombreux cas, le temps de déploiement devrait être dans Initialize. Que faire si tous mes tests utilisent les mêmes artefacts de support? Je suppose que je suis censé copier et coller des décorateurs dans des dizaines de méthodes de test? Ridicule.
Ryanman
5

Après avoir essayé toutes les autres suggestions énumérées ici, je ne pouvais toujours pas comprendre ce qui se passait. Enfin, j'ai découvert qu'aucun fichier de paramètres n'était sélectionné dans le menu Paramètres de test / test, ce qui signifiait que le déploiement n'était pas activé. J'ai cliqué sur l'élément de menu Test / Paramètres de test / Sélectionner le fichier de paramètres de test, sélectionné le fichier Local.TestSettings, puis tout a fonctionné.

Mike
la source
4

Je ne sais pas si cela répond exactement à la question, mais cela peut aider certains. Tout d'abord, j'ai trouvé que la case «Activer le déploiement» doit être cochée pour que le déploiement fonctionne. Deuxièmement, le document dit que le chemin source est "relatif au chemin du projet", ce que j'ai d'abord pris pour signifier le dossier du projet. En fait, il semble faire référence au dossier de sortie de construction. Donc, si j'ai un dossier de projet appelé 'TestFiles' et un fichier qu'il contient Testdata.xml, utiliser l'attribut de cette façon ne fonctionne pas:

[DeploymentItem(@"TestFiles\Testdata.xml")] 

Je peux marquer le Testdata.xmlfichier Copy Always, de sorte que la construction place une copie sous le dossier de sortie (par exemple, Debug\TestFiles\TestData.xml). Le mécanisme de déploiement trouvera alors la copie du fichier située sur ce chemin ( TestFiles\Testdata.xml) par rapport à la sortie de la construction. Ou, je peux définir l'attribut de cette façon:

[DeploymentItem(@"..\\..\TestFiles\Testdata.xml")] 

et le mécanisme de déploiement trouvera le fichier d'origine. Donc, soit fonctionne, mais j'ai remarqué qu'en utilisant le, Copy Alwaysje rencontre parfois le même problème que j'ai lors de l'édition du fichier app.config dans un projet - si je ne change pas de code ou ne force pas une reconstruction, rien ne déclenche la copie des fichiers marqués comme être copié lors de la construction.

user1546704
la source
Le chemin relatif était le problème pour moi et cela l'a résolu. J'ai ajouté 2 ensembles d'instructions DeploymentItem en fonction de la manière dont les tests ont été exécutés.
Ed Bayiates
3

J'ai d'abord désactivé l'indicateur de déploiement. Mais même après l'avoir activé, pour une raison inconnue, même les DLL cibles ne seraient toujours pas copiées. J'ai accidentellement ouvert la fenêtre Test Run et tué toutes les exécutions précédentes et comme par magie, j'ai trouvé toutes les DLL et tous les fichiers dont j'avais besoin dans le dossier de test lors de la prochaine exécution ... Très déroutant.

Schultz9999
la source
2

J'avais d'énormes problèmes en essayant d'obtenir des fichiers à déployer - en essayant toutes les suggestions ci-dessus.

Puis j'ai fermé VS2010; redémarré, chargé la solution et tout a fonctionné. (!)

J'ai fait quelques vérifications; Après avoir défini l'indicateur «Activer le déploiement» sur local.TestSetting, vous ne devez pas simplement réexécuter le test à partir de la fenêtre Résultats du test. Vous devez supprimer le test précédent de l'interface utilisateur, par exemple en exécutant un autre test ou en rouvrant votre solution.

Stephen Westlake
la source
2

N'utilisez pas DeploymentItem.

Il est très difficile de le configurer correctement et cela ne fonctionnait pas avec mon exécuteur de test ReSharper ni avec celui natif pour MSTEST dans Visual Studio 2017.

À la place, cliquez avec le bouton droit sur votre fichier de données et sélectionnez les propriétés . Sélectionnez Copier dans le répertoire de sortie: Toujours .

Maintenant, dans votre test, faites ceci. Le répertoire est simplement le répertoire du fichier relatif au projet de test. Facile.

    [TestMethod()]
    public void ParseProductsTest()
    {
        // Arrange
        var file = @"Features\Products\Files\Workbook_2017.xlsx";
        var fileStream = File.Open(file, FileMode.Open);
        // etc.
    }

Cela semble bien fonctionner avec les systèmes de construction et de test automatisés.

Jess
la source
1

Comme j'ai toujours trouvé l'attribut DeploymentItem un désordre, je fais le déploiement de ces fichiers en utilisant le script de post-construction. - Assurez-vous que les fichiers que vous souhaitez copier ont la propriété Copier toujours. - Modifiez le script de post-construction de votre projet de test pour copier les fichiers du dossier cible de construction (Bin \ Debug) vers l'emplacement où votre test les attend.

Ismail Hawayel
la source
1

Essayez ceci pour VS2010. Vous n'avez donc pas besoin d'ajouter DeployItems pour chaque tif
Supprimez le

[DeploymentItem(@"files\valid\valid_entries.txt")]  
[DeploymentItem(@"files\tif\")]  

Ajoutez une configuration de test.
- cliquez avec le bouton droit sur le nœud de solution dans l'explorateur de solutions
- Ajouter -> Nouvel élément ...
- Sélectionnez le nœud Paramètres de test à gauche, sélectionnez l'élément à droite
- Cliquez sur Ajouter

Appelez-le par exemple TDD

Choisissez TDDsous TestMenu> Edit Testsettings.

Cliquez sur le déploiement. Activez-le puis ajoutez les fichiers et répertoires souhaités. Il y aura un chemin relatif à la solution. Les fichiers seront mis sur. Les fichiers d'origine sont par exemple ici:

D:\Users\Patrik\Documents\Visual Studio 2010\Projects\DCArrDate\WebMVCDCArrDate\Trunk\WebMVCDCArrDate\Authority.xml  

Lorsque j'exécute mon test unitaire, il est copié dans

D:\Users\Patrik\Documents\Visual Studio 2010\Projects\DCArrDate\WebMVCDCArrDate\Trunk\WebMVCDCArrDate.Tests\bin\Debug\TestResults\Patrik_HERKULES 2011-12-17 18_03_27\Authority.xml  

dans testcode, je l'appelle depuis:

[TestMethod()]
public void Read_AuthorityFiles_And_ParseXML_To_Make_Dictonary()  
{  
  string authorityFile = "Authority.xml";  
  var Xmldoc = XDocument.Load(authorityFile);  

Il n'est pas nécessaire de choisir Copier toujours; placez les fichiers dans le projet de test; ajoutez des chemins codés en dur dans le testcode. Pour moi, cette solution fonctionnait le mieux. J'ai essayé avec DeploymentItem, copiez toujours mais ce n'était pas à mon goût.

Patrik Lindström
la source
1

Pour ceux qui préfèrent éviter le désordre de DeploymentItem et adopter l'approche suggérée par @Martin Peck (réponse acceptée), vous pouvez utiliser le code suivant pour accéder au contenu de la ressource embarquée:

public string GetEmbeddedResource(string fullyQulifiedResourceName)
{
    var assembly = Assembly.GetExecutingAssembly();
    // NOTE resourceName is of the format "Namespace.Class.File.extension";

    using (Stream stream = assembly.GetManifestResourceStream(fullyQulifiedResourceName))
    using (StreamReader reader = new StreamReader(stream))
    {
        string result = reader.ReadToEnd();
    }
}

Pour plus de détails, consultez ce fil de discussion SO

Sudhanshu Mishra
la source
1
J'ai eu des problèmes avec Assembly.GetExecutingAssembly () lors de l'exécution sur un serveur de construction -> il renverrait le testeur au lieu de l'assemblage de test réel. Obtenir l'assemblage en le reflétant sur un type fixe dans l'assembly de test (par exemple votre classe de test) a résolu cela pour moi.
Arno Peters
1

Pour moi, la cause première était autre chose: le code de production exercé par mes tests était de renommer et / ou de supprimer le fichier de test .xml en cours de déploiement.

Par conséquent, lorsque j'exécutais mes tests individuellement, ils réussissaient, mais lorsque je les exécutais tous ensemble, le deuxième test et les suivants échouaient avec des erreurs "fichier non trouvé" (que j'avais initialement mal diagnostiquées comme étant DeploymentItem attribut ne fonctionnant pas).

Ma solution consistait à demander à chaque méthode de test individuelle de faire une copie du fichier déployé (en utilisant cette technique ), puis de faire en sorte que le code de production testé utilise le fichier copié au lieu de l'original.

Jon Schneider
la source
1

Nous avons passé beaucoup de temps à résoudre le problème des éléments de déploiement pour le résoudre en local unittest run et teamcity unittest reun également. Ce n'est pas facile.

ProcessExplorer est un très bon outil pour déboguer ce problème . À l'aide de l'explorateur de processus, vous pouvez vérifier où Visual Studio recherche les éléments de déploiement et apporter la correction au projet. Filtrez simplement toutes les opérations de fichiers où le chemin contient le nom de fichier de votre élément de déploiement et vous le verrez.

Tomas Kubes
la source
Je sais que c'est une réponse très ancienne, mais si vous êtes en mesure d'expliquer comment vous utilisez ProcessExplorer, ce serait utile. Je ne vois pas du tout comment afficher les opérations sur les fichiers, encore moins les filtrer ...
David
1

Outre l'attribut Deployment devant être vérifié, j'ai découvert autre chose à propos de l'attribut DeploymentItem.

[TestMethod()]
[DeploymentItem("folder\subfolder\deploymentFile.txt")]
public void TestMethod1()
{
   ...
}

Votre deploymentFile.txt doit être relatif au fichier de solution et non au fichier testfile.cs.

entrez la description de l'image ici

Paven lui-même
la source
J'ai finalement réussi à faire fonctionner ma source DeploymentItem par rapport au projet de test. J'ai donc un projet dans ma solution, "Service.Tests". En dessous, j'ai un dossier "FilesForTests" qui contient les fichiers que je souhaite copier. J'ai utilisé [DeploymentItem(@"FilesForTests\MyFile.txt", "FilesForTests")]. Je pense que nous disons la même chose?
David
1

J'ai travaillé dessus dans VS2013. Mes conclusions pour que cela fonctionne:

  • Copier dans le répertoire de sortie doit être défini sur Copier si plus récent / Copier toujours: OBLIGATOIRE.
  • "Activer le déploiement" dans .TestSettings: NON REQUIS. Je l'ai fait fonctionner sans un fichier .TestSettings du tout.
  • Spécifier un dossier comme 2ème paramètre: OPTIONNEL. Forme la disposition du dossier de sortie, fonctionne très bien sans.
  • ESPACES dans le nom du fichier: cela m'a causé un mal de tête - le fichier n'a jamais été copié. La suppression des espaces a corrigé ce problème. Je n'ai pas encore examiné les personnages d'évasion.

Un conseil que j'ai également appris à la dure: n'oubliez pas d'ajouter cet attribut à chaque test individuel. Le fichier copie le premier test attribué dans le testrun, mais est resté manquant lorsque l'ordre des tests a changé et que les tests non attribués ont tenté de trouver le fichier en premier.

Arno Peters
la source
J'ai tout essayé ici avant d'arriver à votre réponse qui était la toute dernière. Le coupable: ESPACES DANS LE FILENAME! Bonne légende.
joelmdev
1
Utilisation de Visual Studio 2019. «Copier si plus récent» l'a corrigé. Je déteste "Copier toujours" parce que cela force le projet à se reconstruire sur de nombreux scénarios comme le débogage ou la construction incrémentielle.
Gerardo Grignoli le
D'accord. J'ai mis à jour ma réponse pour inclure la copie si plus récente.
Arno Peters
0

Mon grand "gotcha" était la façon dont DeploymentItem gère les répertoires. J'utilisais la version à deux paramètres avec les deux comme chemin de répertoire contenant les sous-répertoires que je voulais déployer. Je n'avais pas réalisé au départ qu'il ne copiait que le contenu de la racine du répertoire et non pas toute la structure de dossiers récursifs!

J'avais essentiellement [DeploymentItem (@ "Foo \", @ "Foo \")] et je m'attendais à ce qu'il déploie mon Foo \ Bar. J'ai spécifiquement dû le changer en [DeploymentItem (@ "Foo \ Bar \", @ "Foo \ Bar \")] et maintenant cela fonctionne comme un charme.

StalePhish
la source
0

J'ai également rencontré des problèmes similaires. J'ai toutes les étapes mentionnées ci-dessus mais toujours pas de chance. J'utilise VS2010. Ensuite, j'ai trouvé que $ Menu> Test> Sélectionnez le paramètre de test actif> Trace et test d'impact a été sélectionné. Il a commencé à fonctionner après avoir changé Trace et tester l'impact en Local . Cette page contient des informations très ingénieuses sur la copie de fichiers dans le dossier des résultats des tests, je pense également ajouter cette expérience.

MJK
la source