So erhalten Sie ein Verzeichnis, während Sie den Komponententest ausführen


76

Hallo, wenn ich meinen Unit-Test ausführe, möchte ich das Verzeichnis abrufen, in dem mein Projekt ausgeführt wird, um eine Datei abzurufen.

Angenommen, ich habe ein Testprojekt namens MyProject. Test, den ich durchführe:

AppDomain.CurrentDomain.SetupInformation.ApplicationBase

und ich erhalte "C:\\Source\\MyProject.Test\\bin\\Debug".

Das ist nah an dem, wonach ich suche. Ich will das bin\\DebugTeil nicht.

Weiß jemand wie ich stattdessen bekommen könnte "C:\\Source\\MyProject.Test\\"?


1
Wenn wir Sie also richtig verstanden haben, haben Sie eine Datei in Ihrem Projekt und möchten die Datei abrufen, während Sie den Anwendungs- / Komponententest ausführen?
Abhilash

11
Auch - Sie sind besser dran, den Ort auf diese Weise zu bekommenPath.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
abhilash

Ja, ich möchte die Datei abrufen, während der
Komponententest ausgeführt wird

Antworten:


68

Ich würde es anders machen.

Ich schlage vor, diese Datei in die Lösung / das Projekt aufzunehmen. Klicken Sie dann mit der rechten Maustaste -> Eigenschaften -> In Ausgabe kopieren = Immer kopieren.

Diese Datei wird dann in ein beliebiges Ausgabeverzeichnis kopiert (z. B. C: \ Source \ MyProject.Test \ bin \ Debug).

Bearbeiten: In Ausgabe kopieren = Kopieren, wenn Neuere die bessere Option ist


3
Und vergessen Sie NICHT, dass Sie auch die "Build-Aktion" auf NONE setzen müssen.
Jiří Herník

3
Die Frage, wie eine Datei beim Erstellen in den Ausgabeordner kopiert wird, unterscheidet sich von der gestellten Frage.
Rick O'Shea

8
@ RickO'Shea Die ursprüngliche Frage war ein XY-Problem . Der Fragesteller stellte in seinem Kommentar klar, was er tun wollte - "Ja, ich möchte die Datei abrufen, während der Komponententest ausgeführt wird". Ich habe lediglich eine Lösung für sein eigentliches Problem bereitgestellt (und nicht für seinen Lösungsversuch).
Ilian Pinzon

8
Ich habe diese Copy To OutputTechnik auch verwendet und sie funktioniert, wenn Unit-Tests einzeln ausgeführt werden. Es funktioniert jedoch nicht, wenn sie im Kontext eines geordneten Tests ausgeführt werden. Ich erhalte eine Fehlermeldung wie: Es System.IO.FileNotFoundException: Could not find file 'C:\SVN\MyProject\TestResults\myName_MACHINE 2017-04-26 12_44_09\Out\MySpreadsheet.xlsx gibt eindeutig ein anderes Unterverzeichnis, das zum Speichern der Testergebnisse erstellt wurde, und IDK, warum mein ausführender Code dort suchen würde.
bkwdesign

1
@IlianPinzon Sie können keine Lösung nennen, die Sie mit einem XY-Problem nicht einverstanden sind. ;) Dies ist eine gültige Frage und verdient eine direkte Antwort.
Extragorey

40

Normalerweise rufen Sie Ihr Lösungsverzeichnis (oder Projektverzeichnis, abhängig von Ihrer Lösungsstruktur) folgendermaßen ab:

string solution_dir = Path.GetDirectoryName( Path.GetDirectoryName(
    TestContext.CurrentContext.TestDirectory ) );

Dadurch erhalten Sie das übergeordnete Verzeichnis des Ordners "TestResults", der durch Testen von Projekten erstellt wurde.


9
Antwort 2016: Path.GetDirectoryName (Path.GetDirectoryName (TestContext.CurrentContext.TestDirectory))
DavidActualX

6
TestDir ist als veraltet (2016) markiert. Denken Sie an die Verwendung von TestContext.TestRunDirectory.
uli78

3
Was ist TestContext.TestDir?
Kiquenet

5
Dies funktioniert nicht mit xUnit. Verwenden Sie Path.GetDirectoryName (Assembly.GetExecutingAssembly (). Location)
zezba9000

1
TestContext ist tatsächlich veraltet!
Lorenzo Isidori


11

Weiter zu @ abhilashs Kommentar.

Dies funktioniert in meinen EXE- Dateien , DLLs und beim Testen aus einem anderen UnitTest-Projekt im Debug- oder Release-Modus:

var dirName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location.Replace("bin\\Debug", string.Empty));

3
Dies ist richtig, aber die einfache Antwort lautet: Path.GetDirectoryName (Assembly.GetExecutingAssembly (). Location)
zezba9000

1
Sowohl Debug- als auch Release-Modus ... Ihr Code macht den Zweck meiner Antwort zunichte.
Jeremy Thompson

8
/// <summary>
/// Testing various directory sources in a Unit Test project
/// </summary>
/// <remarks>
/// I want to mimic the web app's App_Data folder in a Unit Test project:
/// A) Using Copy to Output Directory on each data file
/// D) Without having to set Copy to Output Directory on each data file
/// </remarks>
[TestMethod]
public void UT_PathsExist()
{
    // Gets bin\Release or bin\Debug depending on mode
    string baseA = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
    Console.WriteLine(string.Format("Dir A:{0}", baseA));
    Assert.IsTrue(System.IO.Directory.Exists(baseA));

    // Gets bin\Release or bin\Debug depending on mode
    string baseB = AppDomain.CurrentDomain.BaseDirectory;
    Console.WriteLine(string.Format("Dir B:{0}", baseB));
    Assert.IsTrue(System.IO.Directory.Exists(baseB));

    // Returns empty string (or exception if you use .ToString()
    string baseC = (string)AppDomain.CurrentDomain.GetData("DataDirectory");
    Console.WriteLine(string.Format("Dir C:{0}", baseC));
    Assert.IsFalse(System.IO.Directory.Exists(baseC));


    // Move up two levels
    string baseD = System.IO.Directory.GetParent(baseA).Parent.FullName;
    Console.WriteLine(string.Format("Dir D:{0}", baseD));
    Assert.IsTrue(System.IO.Directory.Exists(baseD));


    // You need to set the Copy to Output Directory on each data file
    var appPathA = System.IO.Path.Combine(baseA, "App_Data");
    Console.WriteLine(string.Format("Dir A/App_Data:{0}", appPathA));
    // C:/solution/UnitTestProject/bin/Debug/App_Data
    Assert.IsTrue(System.IO.Directory.Exists(appPathA));

    // You can work with data files in the project directory's App_Data folder (or any other test data folder) 
    var appPathD = System.IO.Path.Combine(baseD, "App_Data");
    Console.WriteLine(string.Format("Dir D/App_Data:{0}", appPathD));
    // C:/solution/UnitTestProject/App_Data
    Assert.IsTrue(System.IO.Directory.Exists(appPathD));
}

+1 für die Assert.IsTrue(System.IO.Directory.Exists(directory));Idee. Ich habe es angepasst und verwendet Assert.That(System.IO.Directory.Exists(directory), Is.True);. Gleiche Sache, aber besser lesbar
RSM

6

Normalerweise mache ich das so und füge dann einfach "..\..\"den Pfad hinzu, um zu dem gewünschten Verzeichnis zu gelangen.

Was Sie also tun könnten, ist Folgendes:

var path = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"..\..\";

Nicht sicher, wie Sie ".. \ .. \" zu AppDomain.CurrentDomain.SetupInformation.ApplicationBase hinzufügen, um in das Verzeichnis zu gelangen
AnonyMouse

Ja, tut mir leid. Ich habe die Formatierung korrigiert und ein Beispiel hinzugefügt.
AHM

Oder Sie könnten so etwas tun: Path.GetFullPath (AppDomain.CurrentDomain.SetupInformation.ApplicationBase + ".. \\ .. \\ .. \\")
Zar Shardan

1
AppDomain.CurrentDomain.BaseDirectory + @ "\ .. \ .. \ Images \ test.jpg" funktioniert zum Beispiel für mich
Marty

Dies funktioniert nicht, es wird nur ".. \ .. \" an die Zeichenfolge angehängt. Sie müssen etwas wie Path.GetFullPath (Path.Combine (AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @ ".. \ .. \ .. \", "project \\ fille.json") ausführen.
Damian Green

4

Für NUnit mache ich Folgendes:

// Get the executing directory of the tests 
string dir = NUnit.Framework.TestContext.CurrentContext.TestDirectory;

// Infer the project directory from there...2 levels up (depending on project type - for asp.net omit the latter Parent for a single level up)
dir = System.IO.Directory.GetParent(dir).Parent.FullName;

Bei Bedarf können Sie von dort aus bei Bedarf wieder zu anderen Verzeichnissen navigieren:

dir = Path.Combine(dir, "MySubDir");

Danke, das hat bei mir fast geklappt. Ich muss drei Stufen NUnit.Framework.TestContext.CurrentContext.TestDirectoryhöher gehen, weil ich zurückkomme {pathToSolution}\TestProject\bin\Debug\netcoreapp2.2. Auch AppContext.BaseDirectorygibt die gleiche Sache.
Drew

Eigentlich egal, AppContext.BaseDirectoryhat einen nachgestellten Backslash, der im Vergleich zur NUnit-Eigenschaft ein zusätzliches Level erfordert.
Drew


1

Die beste Lösung, die ich gefunden habe, war, die Datei als eingebettete Ressource in das Testprojekt einzufügen und sie aus meinem Komponententest zu erhalten. Mit dieser Lösung muss ich mich nicht um Dateipfade kümmern.


1

Im Allgemeinen können Sie dies verwenden, unabhängig davon, ob Sie eine Test-, Konsolen- oder Web-App ausführen:

// returns the absolute path of assembly, file://C:/.../MyAssembly.dll
var codeBase = Assembly.GetExecutingAssembly().CodeBase;    
// returns the absolute path of assembly, i.e: C:\...\MyAssembly.dll
var location = Assembly.GetExecutingAssembly().Location;

Wenn Sie NUnit ausführen, dann:

// return the absolute path of directory, i.e. C:\...\
var testDirectory = TestContext.CurrentContext.TestDirectory;

1

Mein Ansatz besteht darin, den Standort der Einheitentestbaugruppe zu ermitteln und dann nach oben zu fahren. Im folgenden Snippet folderProjectLevelgibt Ihnen die Variable den Pfad zum Unit-Test-Projekt.

string pathAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location;
string folderAssembly = System.IO.Path.GetDirectoryName(pathAssembly);
if (folderAssembly.EndsWith("\\") == false) {
    folderAssembly = folderAssembly + "\\";
}
string folderProjectLevel = System.IO.Path.GetFullPath(folderAssembly + "..\\..\\");

0

Sie können es so machen:

using System.IO;

Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @"..\..\"));

0

Laut https://github.com/nunit/nunit/issues/742#issuecomment-121964506

Für NUnit3 wird System.Environment.CurrentDirector niemals geändert, daher ist dies der Lösungspfad.

Z.B:

string szProjectPath = System.Environment.CurrentDirectory + @"\where\your\project\is";

Ich bevorzuge einen festen Standort anstelle von GetParent (). Ein Nachteil von GetParent besteht darin, dass beim Ändern des Builds von AnyCPU auf x86 der Standardpfad von bin \ Debug in bin \ x86 \ Debug geändert wird. Müssen Sie einen anderen Elternteil bekommen, und es ist Schmerzen im Nacken.

Sie können auch weiterhin auf Ihre Testbaugruppen unter zugreifen TestContext.CurrentContext.TestDirectory.

Bearbeiten: Hinweis: Es gibt viele Änderungen in NUnit3. Ich werde vorschlagen, die Dokumentation über "Änderungen brechen" durchzulesen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.