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\\"?

AnonyMouse
quelle
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

Ilian Pinzon
quelle
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.

Darien Pardinas
quelle
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));
Jeremy Thompson
quelle
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));
}
user1207577
quelle
+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 + @"..\..\";
AHM
quelle
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");
Noelicus
quelle
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.

Andre LAC Bittencourt
quelle
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;
Häuser
quelle
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 + "..\\..\\");
Sau001
quelle
0

Sie können es so machen:

using System.IO;

Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, @"..\..\"));
Ogglas
quelle
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.

Louis Go
quelle