How can I load this file into an NUnit Test? - c#

I have the following IntegrationTest project structure ...
If i wish to use that test data 126.txt in an NUnit Test, how do I load that plain txt file data?
NOTE: The file is -linked- and I'm using c# (as noted by the image).
cheers :)

You could specify in the properties of the file to be copied to the output folder and inside the unit test:
string text = File.ReadAllText(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "126.txt"));
As an alternative you could embed this file as a resource into the test assembly and then:
var assembly = Assembly.GetExecutingAssembly();
using (var stream = assembly.GetManifestResourceStream("ProjectName.Tests.IntegrationTests.TestData.126.txt"))
using (var reader = new StreamReader(stream))
{
string text = reader.ReadToEnd();
}

If you do not want the files as ManifestResources, but just as file on the system. See Trouble with NUnit when determining the assembly's directory for more info and this answer in particular
Also interesting is the info from NUnit https://bugs.launchpad.net/nunit-vs-adapter/+bug/1084284/comments/3
But here is the quick info:
Path.Combine(TestContext.CurrentContext.TestDirectory, #"Files\test.pdf")
Where Files\test.PDF is just a file in your test project, with build action content and copy to output directory copy if newer
All credits go out to the people in the other post, but took me a while to find that answer, and that is the reason why i am adding the answer to this post.

This question is currently answered, but for googlers searching for other possibilities:
If you get a DirectoryNotFoundException because the test is looking in C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common... rather than in bin\Debug\..., it means your test adapter is executing from a path that isn't your test project output directory.
To solve this, you can get that bin\Debug\... directory by looking for the directory of the test DLL like so:
using System.IO;
using System.Reflection;
// Get directory of test DLL
var dir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// dir is now "C:\...\bin\Debug" or wherever the executable is running from
I threw that in a TestHelpers static class in the test project so that I can use it in every test that needs to load external files.
Code is courtesy of this answer.

Found a gotcha with using TestContext.CurrentContext.TestDirectory. This works perfectly in a Setup, but when I call it from within a method supplied to a TestCaseSource, the static method is called before all other code, and returns the following:
C:\Users\<username>\.nuget\packages\nunit\3.10.1\lib\netstandard2.0
However, using TestContext.CurrentContext.WorkDirectory gives the desired result in both places:
C:\SVN\MyApp\trunk\MyApp.Tests\bin\Debug\netcoreapp2.1

Related

Excel files are not being read when executing Selenium C# Scripts on Azure Releases

I have some Selenium C# tests hosted on Azure which they need to look for the pre-built excel file in project tree, stored inside bin folder, to execute some file upload validation scenarios.
When they are executed locally these scenarios pass without any problem, but when it comes to be executed on the Azure they receive the following error.
invalid argument: File not found : D:\a\r1\a_Selenium_Tests\TestApplication\bin\Debug\netcoreapp3.1\Files\SC003_CT014_ActiveEmployees.xlsx
The files do exists in the following path: ...\bin\Debug\netcoreapp3.1\Files...
And the code I use to them is:
string root = Directory.GetCurrentDirectory() + "\\Files\\" + file;
Do you know if there's a missing file configuration or building the filePath in another way?
Thanks for your help :D
Directory.GetCurrentDirection() returns the current working directory, not the folder in which the DLL file resides. The current working directory is a different thing. In your case, the current working directory is probably something like D:\a\r1\. Instead, you need to get the folder in which the test assembly resides:
var binDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
// ^^^^^^^^^
var excelFilePath = Path.Combine(binDirectory, "Files", "SC003_CT014_ActiveEmployees.xlsx");
Note: Replace GetType() with typeof(ClassName) if you are executing your code from a static method, or you would like to specify a path to a different assembly than the one that is currently executing.

How to zip files/directories in VB.NET?

I would like to zip a folder containing files and subfolders in VB.NET. My solution targets .NET 4.0 Client Profile.
I see that there is a ZipFile class for .NET 4.5, and System.IO.Packing for .NET 4.0 (but not Client Profile). So, those won't help. I note that there is also a GZipStream class, but I never see .gz files floating around, so not sure if that's a good approach. I would prefer a basic .zip file that I know my users can work with.
There are a handful of third-party solutions, such as http://icsharpcode.github.io/SharpZipLib/, but I assume they are far more bloated than the 10-20 lines of code I am looking for. Maybe that's the right answer...I don't know.
Just hoping for a few lines of VB.NET code to zip some files in a solution targeting .NET 4.0 CP.
Create ZIP from "source" folder.
Imports System.IO.Compression
ZipFile.CreateFromDirectory("source","destination.zip",CompressionLevel.Optimal,False)
Extract ZIP to "destination" folder.
ZipFile.ExtractToDirectory("destination.zip","destination")
Unable to comment in the comments section due to lack of reputation (due to being new here).
On the two answers indicating that using System.IO.Compression can be used that were commented as not working in NET 4.0 CP, this should be noted, as the original answers did not include an often overlooked fact.
A reference needs to be added to the project in order to activate "System.IO.Compression". This is not obvious to many new VS users, and unless the refrence is added, it indeed seems like "System.IO.Compression" does not work in NET 4.0.
In this case, the reference that needs to be added is System.IO.Compression.Filesystem (v4.0.0.0). One may also wish to add the reference: System.IO.Compression.
The "Add Reference..." dialog is under the "Project" menu in VS.
The MSDN Website has a class that can help you out here called ZipFile
using System;
using System.IO;
using System.IO.Compression;
namespace ConsoleApplication {
class Program {
static void Main(string[] args) {
string startPath = #"c:\example\start";
string zipPath = #"c:\example\result.zip";
string extractPath = #"c:\example\extract";
'Creates Zip File to directory as specified (startPath). And puts it in a specifed folder (zipPath)
ZipFile.CreateFromDirectory(startPath, zipPath);
'
Extracts Zip File to directory as specified(extractpath)
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
}
}
Hope this helps!
Simply you can do it using Ionic.Zip.Dll
Here is the function for this,accepting two variables source path and destination path
public static void ExecuteBackupAsZip(string SourcePath, string DestinationPath)
{
using (var zip = new Ionic.Zip.ZipFile())
{
try
{
zip.AddDirectory(SourcePath);
zip.Save(DestinationPath);
}
catch { Console.WriteLine("Failed to execute backup"); }
}
}
Same challenges as "an odder guest". That is can't commment due to low rep as new user and have to add a new answer. (Frequent reader though). Running on vb.Net 4.6 and got no errors on the suggestions above, but no output zip file was generated. Then after some googling added references System.IO.Compression.Filesystem and System.IO.Compression and ended up with the following one-liner:
System.IO.Compression.ZipFile.CreateFromDirectory(FilePath1, FilePath3_ZippedFile)
Where FilePath1 is the path to the source folder (c:\whateverfolder) and FilePath3_ZippedFile is the path to the resulting output zip-file(c:\anotherfolder\MyZipFile.zip).
Sorry if you think my input is redundant, but I know for newcommers like my self we need the answers feed with tee spoons.
Word of caution: If you try to create the zip-file in the source folder you might have issues. My code then only included one of the files from the source folder in the zip-file. (No error messages). Changing the target location to another folder solved this without other edits to the code.

while calling mstest from powershell, extra directory is being added in the relative paths in c#

I will try to make it clear
I have a MSTest Project called IntegrationTests
I have a PowerShell script inside IntegrationTests folder. This script runs the test using MSTest command line arguments.
The tests are being successfully called but after all the tests run there is a call to one method in my test method that creates report. When its trying to load the report.xslt file it is adding extra folder "TestResults"
Unexpected
................
System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\dev\Desktop\Test Runner\IntegrationTests\TestResults\Report Generator\Reports\report.xslt
Expected
................
C:\Users\dev\Desktop\Test Runner\IntegrationTests\Report Generator\Reports\report.xslt
why is this "TestResults" extra folder is added?
Just to make things clear this project is 100% working when i run this from visual studio.
If you would like to know how the relative path is being constructed in c# here is the code
var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
var xslt = new XslCompiledTransform();
xslt.Load(Path.Combine(directory, "..\\..\\Report Generator\\Reports\\report.xslt"));
I just want to know how can i get rid of "TestResults" so that my test can run normally. Any helps really appreciated.

TFS Build Machine Test method errors out on build machine

Here is my unit test code:
[TestMethod]
public void GetMyAttachmentTest()
{
var files = Directory.GetFiles(
Directory.GetCurrentDirectory() + "/Common/MyFiles/", "*.*");
.... do some thing with the files...
}
On TFS build machine, when I run my unit test, I am getting the following error:
System.IO.DirectoryNotFoundException: Could not find a part of the path
'C:\Builds\4\30 my folder v1.0\myfolder1\TestResults\SCMTFSService_MyBuildServer 2013-01-16 18_06_52_Any CPU_Release\Out\Common\MySpecialFiles\'.
When I look into the drop folder in TFS, I see that my files are deployed into the following folder:
\\MyBuildServer\Builds\MyFolder\MySolution_20130116.5\Common\MySpecialFiles
Inside my unit test code, I get my files as follows:
var files = Directory.GetFiles(
Directory.GetCurrentDirectory() + "/Common/MySpecialFiles/", "*.*");
Is there a way when my unit test runs on TFS build machine that it can look into the files in the deployed Common\MySpecialFiles?
The question is a bit vague. In the past, I've had issues with unit tests executing in temp locations. This can be problematic with dynamic paths such as GetCurrentDirectory(). When the the temp directory changes/clears, files can be "lost".
Instead of using a dynamic path, setup a network share with appropriate permissions. I recommend storing the path to this network share a config file or the DB so that it can be updated without a code push.
Why not put the location of the files in an appSettings item in the app.config/web.config file? That will make it easy to change it to match your environment whether it's local, a build server or a deployed environment.
Otherwise, you will have to set the current directory to \MyBuildServer\Builds\MyFolder\MySolution_20130116.5 before running your test and that will probably impact your tests in other ways.

Merge DLL into EXE?

I have two DLL files which I'd like to include in my EXE file to make it easier to distribute it. I've read a bit here and there how to do this, even found a good thread here, and here, but it's far too complicated for me and I need real basic instructions on how to do this.
I'm using Microsoft Visual C# Express 2010, and please excuse my "low standard" question, but I feel like I'm one or two level below everyone else's expercise :-/ If someone could point out how to merge these DDL files into my EXE in a step-by-step guide, this would be really awesome!
For .NET Framework 4.5
ILMerge.exe /target:winexe /targetplatform:"v4,C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" /out:finish.exe insert1.exe insert2.dll
ILMerge
Open CMD and cd to your directory. Let's say: cd C:\test
Insert the above code.
/out:finish.exe replace finish.exe with any filename you want.
Behind the /out:finish.exe you have to give the files you want to be
combined.
Use Costura.Fody.
You just have to install the nuget and then do a build. The final executable will be standalone.
Download ilmerge and ilmergre gui . makes joining the files so easy
ive used these and works great
Reference the DLL´s to your Resources and and use the AssemblyResolve-Event to return the Resource-DLL.
public partial class App : Application
{
public App()
{
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
Assembly thisAssembly = Assembly.GetExecutingAssembly();
//Get the Name of the AssemblyFile
var name = args.Name.Substring(0, args.Name.IndexOf(',')) + ".dll";
//Load form Embedded Resources - This Function is not called if the Assembly is in the Application Folder
var resources = thisAssembly.GetManifestResourceNames().Where(s => s.EndsWith(name));
if (resources.Count() > 0)
{
var resourceName = resources.First();
using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName))
{
if (stream == null) return null;
var block = new byte[stream.Length];
stream.Read(block, 0, block.Length);
return Assembly.Load(block);
}
}
return null;
};
}
}
Download
ILMerge
Call
ilmerge /target:winexe /out:c:\output.exe c:\input.exe C:\input.dll
Install ILMerge
as the other threads tell you to
Then go to the installation folder, by default
C:\Program Files (x86)\Microsoft\ILMerge
Drag your Dll's and Exes to that folder
Shift-Rightclick in that folder and choose open command prompt
Write
ilmerge myExe.exe Dll1.dll /out:merged.exe
Note that you should write your exe first.
There you got your merged exe. This might not be the best way if your going to
do this multiple times, but the simplest one for a one time use, I would
recommend putting Ilmerge to your path.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
/* PUT THIS LINE IN YOUR CLASS PROGRAM MAIN() */
AppDomain.CurrentDomain.AssemblyResolve += (sender, arg) => { if (arg.Name.StartsWith("YOURDLL")) return Assembly.Load(Properties.Resources.YOURDLL); return null; };
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
First add the DLL´s to your project-Resources. Add a folder "Resources"
2019 Update (just for reference):
Starting with .NET Core 3.0, this feature is supported out of the box. To take advantage of the single-file executable publishing, just add the following line to the project configuration file:
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
Now, dotnet publish should produce a single .exe file without using any external tool.
More documentation for this feature is available at https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md.
Also you can use ilmergertool at codeplex with GUI interface.
Here is the official documentation. This is also automatically downloaded at step 2.
Below is a really simple way to do it and I've successfully built my app using .NET framework 4.6.1
Install ILMerge nuget package either via gui or commandline:
Install-Package ilmerge
Verify you have downloaded it. Now Install (not sure the command for this, but just go to your nuget packages):
Note: You probably only need to install it for one of your solutions if you have multiple
Navigate to your solution folder and in the packages folder you should see 'ILMerge' with an executable:
\FindMyiPhone-master\FindMyiPhone-master\packages\ILMerge.2.14.1208\tools
Now here is the executable which you could copy over to your \bin\Debug (or whereever your app is built) and then in commandline/powershell do something like below:
ILMerge.exe myExecutable.exe myDll1.dll myDll2.dll myDlln.dll myNEWExecutable.exe
You will now have a new executable with all your libraries in one!
I answered a similar question for VB.NET. It shouldn't however be too hard to convert. You embedd the DLL's into your Ressource folder and on the first usage, the
AppDomain.CurrentDomain.AssemblyResolve event gets fired.
If you want to reference it during development, just add a normal DLL reference to your project.
Embedd a DLL into a project
NOTE: if you're trying to load a non-ILOnly assembly, then
Assembly.Load(block)
won't work, and an exception will be thrown:
more details
I overcame this by creating a temporary file, and using
Assembly.LoadFile(dllFile)
I Found The Solution Below are the Stpes:-
Download ILMerge.msi and Install it on your Machine.
Open Command Prompt
type cd C:\Program Files (x86)\Microsoft\ILMerge Preess Enter
C:\Program Files (x86)\Microsoft\ILMerge>ILMerge.exe /target:winexe /targetplatform:"v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319"
/out:NewExeName.exe SourceExeName.exe DllName.dll
For Multiple Dll :-
C:\Program Files (x86)\Microsoft\ILMerge>ILMerge.exe /target:winexe /targetplatform:"v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319"
/out:NewExeName.exe SourceExeName.exe DllName1.dll DllName2.dll DllName3.dll
The command should be the following script:
ilmerge myExe.exe Dll1.dll /target:winexe /targetplatform:"v4,c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\" /out:merged.exe /out:merged.exe

Categories