I have some Tests that I run with ReSharpers "Run All Tests from Solution" feature. One of the classes being tested has a dependency on a file in the same folder as the assembly containing it. This file is copied to the output directory via MSBuild (set "Copy To Output Directory" to "Copy always").
Problem: The tests are not being run from the normal assembly output directory, but instead some temporary location in my user profile.
Therefore, I don't really know where to look for the file - the test runner does not copy it there. Can I force it to?
NUnit website recommends in this exact case to use Assembly.CodeBase property, that leads to the bin/debug I needed.
"Note: If you are tempted to disable shadow copy in order to access files in the same directory as your assembly, you should be aware that there are alternatives. Consider using the Assembly.Codebase property rather than Assembly.Location."
The .Location returned Uri style address "file:////D://Projects ... ", so the actual code I used was
string applicationDirectory = new Uri(Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)).LocalPath;
Sounds like you're running your tests with the Shadow Copy option turned on.
Go to Resharper->Options and select the Unit Testing tab (right at the bottom of the list). Uncheck "Shadow-copy assemblies being tested" and try again.
Related
I have an application written in C++, configured with CMake, tested using Catch2, the tests are invoked through CTest.
I have a fairly large list of files that each contain captures of messages that have caused an issue in my application in the past. I currently have a single test that runs through each of these files serially using code that looks approximately like:
TEST_CASE("server type regressions", "[server type]") {
auto const state = do_some_setup();
for (auto const path : files_to_test()) {
INFO(path);
auto parser = state.make_parser(path);
for (auto const message : parser) {
INFO(message);
handle(message);
}
}
}
The message handler has a bunch of internal consistency checks, so when this test fails, it typically does so by throwing an exception.
Is it possible to improve this solution to get / keep the following:
Run the initial do_some_setup once for all of the tests, but then run the test for each file in parallel. do_some_setup is fairly slow, and I have enough files relative to the number of cores that I wouldn't want to have to do setup per file. It would also be acceptable to run do_some_setup more than once, as long as it's better than O(n) in the number of files.
Run the regression test on all the files, even when an earlier file fails. I know I could do this with a try + catch and manually setting a bool has_failed on any failure, but I'd prefer if there were some built-in way to do this?
Be able to specify the file name when invoking tests, so that I can manually run just the test for a single file
Automatically detect the set of files. I would prefer not having to change to a solution where I need to add test files to the test file directory and also update some other location that lists all of the files I'm testing to manually shard them
I'm willing to write some CMake to manage this, pass some special flags to CTest or Catch2, or change to a different unit testing framework.
I have two files in a Unity3d project. One is a test script that runs in edit mode. The other is a single class with static functions that I'd like to call from the test scripts.
here's my test script:
using UnityEngine;
using UnityEngine.TestTools;
using NUnit.Framework;
using System.Collections;
public class NewTestScript
{
[Test]
public void TestAnotherStaticFunction()
{
int a = NewBehaviourScript.FunctionUnderTest(1);
int b = 1;
// Use the Assert class to test conditions.
Assert.IsTrue(a == b);
}
}
here's my function under test:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
/// <summary>
/// the stupidest function in the world,
/// used to verify tests.
/// </summary>
public static int FunctionUnderTest(int a)
{
return a;
}
}
This gives me the error from the Unity compiler (I'm not building outside of Unity):
Assets/TestS/NewTestScript.cs(12,17): error CS0103: The name `NewBehaviourScript' does not exist in the current context
These are running in edit-mode.
I've tried adding and removing the SuperTestNameSpace namespace from the function under test and the calling code.
I've attempted adding/removing files from the .asmdef file that was autogenerated by unity, although this usually leads to other compile errors.
My previous unit test experience is largely in Visual Studio or VSCode, and I'm trying to get my unity3d test experience to match my prior test environment experiences.
Is there a fundamentally limited functionality in the edit-mode tests, or am I missing something stupid?
Further elaboration on the assemblies involved. It looks like there are two assemblies at play here: Assembly-CSharp.dll contains my code under test and TestS.dll contains my testing code. I believe my questions boils down to: how do I add a reference from the TestS.dll assembly to the Assembly-CSharp.dll. I'd know how to do this in Visual Studio (either via the context menu in VS or directly editing the csproj file), however I don't see how to do it in Unity3d. Any edit I make to the csproj file is frequently overwritten by unity, and while there is a 'references' section in the inspector (see picture) I can't add Assembly-CSharp.dll as a reference.
These are the inspector settings for TestS.asmdef. While there's an option to add references, I can't add a reference to Assembly-CSharp.dll, which is where my code-under-test lives.
Ok, I figured this out. There were two things going on:
Editor tests need to be underneath a folder called editor. It's really annoying that the unity editor doesn't do this for you.
You need to have an assembly definition for the code under test and add a reference from the test code to the newly created assembly definition. This must be done in the Unity editor UI.
by default, unity adds your script code to an assembly called Assembly-CSharp.dll, and, for reasons unknown, this assembly isn't referenced by my edit mode test code. I'm not sure if this is a bug in Unity or if it's by design, but explicitly creating and referencing the assembly definition has cleared things up.
The main issue is currently you are trying to call the
NewBehaviourScript(1);
constructor which does not exist...
instead of the method
using SuperTestNameSpace;
//...
NewBehaviourScript.FunctionUnderTest(1);
or alternatively with the namespace in the call directly
SuperTestNameSpace.NewBehaviourScript.FunctionUnderTest(1);
Also make sure the filename matches exactly the class name. So in your case it should be
NewBehaviourScript.cs
Note that the .cs is not printed by Unity in the Project view so there it should say NewBehaviourScript.
Why does it not compile with the using SuperTestNameSpace;? What is the error?
If that exception
Assets/TestS/NewTestScript.cs(14,17): error CS0103: The name `NewBehaviourScript' does not exist in the current context
is only shown in VisualStudio but the script compiling fine in Unity especially after adding a new script it helps to simply close and restart VS.
In some cases it also helps to close Unity and VS, remove all files and folders except Assets and ProjectSettings (and if you are under version control anything that belongs to it like e.g. .git, .gitignore, .gitattributes etc) in particular delete the Library, .vs folder and all .csproj and .sln files.
Than open Unity again and let it recompile everything.
Make sure the file that contains your NewBehaviourScript class IS NOT inside an Editor folder.
Move both the scripts in the Assets (root) folder and try again.
I have done the below steps, it is working fine on my local machine but when I worked with TFS solution explore below error display (newlines added for clarity):
Error: The character encoding for the file D:\Testcase\data.csv has changed.
Your source control provider may have problems managing files with this type of encoding.
For example, if you save an ANSI-encoded file as UTF-8 you may not be able to merge or show differences.
Steps:
Created data.csv file.
Advance save as a unicode (utf-8 without signature Codepage-65001).
Make data.csv file as copy if new
Code:
[DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV", "|DataDirectory|\\data.csv", "data#csv", DataAccessMethod.Sequential), DeploymentItem("data.csv"), TestMethod]
public void CodedUITestMethod1()
{
Console.WriteLine(TestContext.DataRow["firstname"].ToString());
// To generate code for this test, select "Generate Code for Coded UI Test" from the shortcut menu and select one of the menu items.
}
Set the Copy to Output Directory in the properties window for that file to Copy Always or Copy if Newer.
In the application that I am developing (using C++ and Qt), I am using QApplication::applicationDirPath() to access some resources, with respect of the application's path.
As an example, since I want to open a HTML manual from the application, I act this way:
void MainWindow::on_actionHelp_triggered()
{
QString link = QApplication::applicationDirPath() + "/Guide/guide.html";
bool r = QDesktopServices::openUrl(QUrl::fromLocalFile(link));
}
This snippet works if the project's structure presents the path "ProjectName/bin/Release/Guide/guide.html" (since the .exe file is in "ProjectName/bin/Release/AppName.exe").
But what can I do to refer to a higher-directory-level resource? As an example, I wish my HTML file to be in "ProjectName/data/Guide/guide.html". But this way, it seems not possible to compose the path in the way I'm acting.
EDIT: After #olive's comment, I wish to clarify a thing:
"Why am I not using '../'?"
Because it won't work from Visual Studio, where I am massively launch the application to test it. From VS, in fact, I shall use "../data/Guide/guide.html", when "from the outside", I'd have to do "../../data/Guide/guide.html".
That's why (I think) QApplication::applicationDirPath() exists. However, I am not an expert, so don't blame me and correct any eventual mistake of mine, please!
Just use ... QApplication::applicationDirPath() + "/../../data/Guide/guide.html" is perfectly valid path!
Of course there is another problem. When the application is installed, the relative path will probably be different again. You either need to configure the paths in visual studio so that the relative path works both during development and after deployment, or you need to detect the layout.
I can compile the solution with no errors, but when I'll try to run it, I get a crash window:
An unhandled exception of type
'System.Resources.MissingManifestResourceException' occurred in mscorlib.dll
Additional information: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "<myformname>.resources" was corerctly embedded or linked into assembly "<myprojectname>" at compile time, or that all the satellite assemblies required are loaded and fully signed.
And after I press Break it throws me to the line:
this->Icon = (cli::safe_cast<System::Drawing::Icon^ >(resources->GetObject(L"$this.Icon")));
If I comment this line out, everything works just fine, but my program doesn't have icon.
Anyone else had this problem? Found a solution? I couldn't find anything clear enough for me to understand, problem is really annoying me, only solution I found was to declare my form class before any other classes, but I don't even have any other classes in my solution?
I also have only one project in this solution, ms support said something about having multiple projects, which I don't have, so it was no use either.
Take a look here :
http://www.mztools.com/articles/2005/MZ2005007.aspx
The exception is thrown because your icon cannot be located. You will probably need to compiles your resources under one .dll and put this under en-US subfolder on your project output. It did the trick for me at least. There are probably other solutions to your problem too.
Do not panic like I did. The root cause of the problem is that the compiled resource file is different from the one that is asked to load at runtime. This happens because the underlying build-script cannot detect the filename or namespace changes made after the form is created.
For example, At first we started a project named x . And our $(RootNamespace) becomes x. And we created a form named y. So our XML resource file y.resx gets compiled into x.y.resource . At this point the icon change works.
Now somehow we changed the project name or the namespace to z. But our $(RootNamespace) remains the x. While at compile-time it wrongly generates old x.y.resource, but at links-time it links z.y.resource. And at this point the icon change does not work.
It can also happen if the form is under some nested namespace which is not known in the project file.
It can be fixed by changing the compilation output of the y.resx file . It can be done by right-clicking the resource and changing the Resource Logical Name to $(RootNamespace).%(Filename).resources .
I will also make sure that ProjectName,AssemblyName and RootNamespace are the same in the .vcxproj file. Somehow if the form is declared under a nested namespace like RootNamespace.gui , then the output file of the resource should be $(RootNamespace).gui.%(Filename).resources .