I have a console application project with NUnit tests in the same project.
I have been trying to apply this solution.
At run-time the solution worked OK. But when I ran the tests by Resharper test runner or NUnit GUI runner, GetExecutingAssembly().Location returned a path like this: d:\Temp\f4ctjcmr.ofr\nojeuppd.fmf\R2Nbs\assembly\dl3\9766f38e\b9496fb3_43cccf01\.
Disabling shadow-copying fixed the problem in both test runners, but new problems appeared (VS is not able to build the project until NUnit Gui is closed). Is there a better solution than disabling shadow-copying?
Update: Environment.GetCommandLineArgs()[0] returned C:\Program Files (x86)\NUnit 2.6.3\bin\ in the tests running in NUnit Gui with shadow-copying enabled.
Alright, this goes into fun territory.
You should be mocking out this dependency.
Example code:
public interface IApplicationRootService {
Uri GetApplicationRoot();
}
public class ApplicationRootService : IApplicationRootService {
public Uri GetApplicationRoot() {
//etc
}
}
Now, apply liberally to your code where you're calling getexecutingassembly and whatnot. Inject the IApplicationRootService as a constructor dependency.
Ex:
public class DoWork {
private IApplicationRootService _applicationRootService;
public DoWork(IApplicationRootService applicationRootService) {
_applicationRootService = applicationRootService;
}
public void DoSomething() {
var appRoot = _applicationRooService.GetApplicationRoot();
//do your stuff
}
}
Now when you're testing, use a mocking service and mock out the return value of application root to the appropriate folder for nunit to go sniffin'.
Ex code, using nunit and moq:
[Test]
public static void test_do_something() {
var applicationRootService = new Mock<IApplicationRootService>();
applicationRootService.Setup(service => service.GetApplicationRoot()).Returns(new Uri("MyRoot", UriKind.Relative);
var myClass = new DoWork(applicationRootService.Object);
//continue testing!
}
The following solution worked for me. Please vote to its author if it helps you.
As explained in the MSDN forums post, How to convert URI path to normal filepath?, I used the following:
// Get normal filepath of this assembly's permanent directory
var path = new Uri(
System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().CodeBase)
).LocalPath;
Related
I created a fresh .NET Core Class Library project named FooBarBaz. I've then used the package manager console to run:
Install-Package xunit xunit
Install-Package xunit xunit.runners.visualstudio
This is the only code I have added:
using Xunit;
using Xunit.Abstractions;
namespace FooBarBaz
{
public class Class1
{
private readonly ITestOutputHelper output;
public Class1(ITestOutputHelper output)
{
this.output = output;
output.WriteLine("OUTPUT FROM MY CONSTRUCTOR");
}
[Fact]
public void SmokeTest()
{
output.WriteLine("OUTPUT FROM MY TEST");
Assert.True(true);
}
}
}
This is based straight on the xUnit.net documentation example. I know that the documentation goes on to talk about "Message Sinks" and whatnot, but I could've sworn I saw the message in the Output window of visual studio. In my real project this seems to work only erratically.
I know I can click the "Output" hyperlink after selecting a test and see it, but that's just one step extra, and that output doesn't have a monospace font either (which I'd like to have).
See this:
How do I configure xUnit to provide output in the Output window?
After typing the question and fiddling around some more, the completely obscure solution popped up: only tests that fail show ITestOutputHelper output in the Output window.
Try changing the assertion to Assert.True(false); and you'll get this:
Not sure why that's the default, or how you'd change it.
What Jeroen wrote regarding ITestOutputHelper is correct, so you can't use it for "live" messages. But I have a workaround for you:
If you're debugging anyway and activated "Debug" mode, nothing stops you from doing something like
loopCount++;
System.Diagnostics.Debug.WriteLine($"Processing Entries ({loopCount} of {loopMax}) ...");
This will show up in the "Debug" window (i.e. in the Output window there is a dropdown where you need to select "Show output from Debug"). It appears immediately, ideal for long running loops etc.
Don't worry, those messages show up only in "Debug" configuration. To disable them, select "Release", and they won't appear any more - so it is easy to turn them on or off.
You can also write a helper function like:
private void Print(string msg, string test = "")
{
Debug.WriteLine($"{nameof(NameOfTestClass)}{test}: {msg}");
output?.WriteLine(msg);
}
Which will write into debug console in real time, but at the same time write into the test runner's output space.
You can use it in your Facts and Theories like
Print("Something happened");
or
Print("Something happened", "-Test1");
And a complete test class would look like:
using LiveOut = System.Diagnostics.Debug;
// using LiveOut = System.Console;
public class Test_Class
{
ITestOutputHelper Output;
public Test_Class(ITestOutputHelper _output)
{
Output = _output;
}
private void Print(string msg, string test = "")
{
LiveOut.WriteLine($"{nameof(Test_Class)}{test}: {msg}");
Output?.WriteLine(msg);
}
[Fact]
void Test_Xunit()
{
void _print(string msg) => Print(msg, $"-{nameof(Test_Xunit)}");
for (int i = 1; i < 100; i++)
{
_print(i.ToString());
Assert.True(i > 0);
Thread.Sleep(20);
}
}
}
In this case, you can choose between two using commands:
using LiveOut = System.Diagnostics.Debug;
or
using LiveOut = System.Console;
Depending on your needs you will have the output either on the debug window or on the console window.
I am using extent Reports in my specflow unit tests.
I have 2 projects in 1 solution. I have a separate project for creating a hook file which will be common for both the projects.
I need to initialize my extentreports object in BeforeTestRun hook and use it in BeforeScenario.
I am not getting a way to access the same.
Here is my code so far :
public static void BeforeFeature()
{
extentReports = new ExtentReports();
htmlReporter = new ExtentHtmlReporter(FeatureContext.Current.FeatureInfo.Title + ".html");
htmlReporter.Configuration().Theme = Theme.Dark;
extentReports.AttachReporter(htmlReporter);
TestcaseConst._logger = LogManager.GetCurrentClassLogger();
FeatureContext.Current.Set<ExtentReports>(extentReports);
}
[BeforeScenario]
public static void BeforeScenario()
{
extentTest = FeatureContext.Current.Get<ExtentReports>().CreateTest(ScenarioContext.Current.ScenarioInfo.Title, "This test is to check the status of API under test");
ScenarioContext.Current.Set<ExtentTest>(extentTest);
}
Now, I need to shift this code under BeforeFeature to BeforeTestRun, but I am not getting to save something like this "FeatureContext.Current.Set(extentReports);" in BeforeTestRun.
Please help if anyone knows.
Thanks In Advance.
I have noticed that when using a testcase instead of a test, the category of the test is not available through the testcontext. So lets view some code:
[TestFixture]
public class FormTests : BrowserTests
{
[TestCase("/some-url/", FormType.ContactForm), Category("form")]
[TestCase("/some-other-url/", FormType.ContactForm), Category("form")]
public void AssertFormIsSubmittable(string url, FormType formType)
{
Browser.OpenPage($"{BaseUrl}{url}", true);
Browser.Action(FormActions.EnterFormFields(formType));
Browser.Action(FormActions.Submit());
var isSuccesfullySubmitted = Browser.Verify(FormState.IsSubmitted());
Assert.IsTrue(isSuccesfullySubmitted);
}
[Test, Category("form")]
public void FunctionToTestIfCategoryIsWorking()
{
Browser.OpenPage($"{BaseUrl}", true);
Browser.Action(FormActions.EnterFormFields(FormType.ContactForm));
Browser.Action(FormActions.Submit());
var isSuccesfullySubmitted = Browser.Verify(FormState.IsSubmitted());
Assert.IsTrue(isSuccesfullySubmitted);
}
}
When running the AssertFormIsSubmittable (with the testcases), within the BrowserTests base class, when I execute:var category = TestContext.CurrentContext.Test.Properties.Get("Category"); the result is null.
When i execute FunctionToTestIfCategoryIsWorking, the same line of code has "form" as a result. That's the expected result. Somehow, when using a TestCase, it doesn't work anymore.
I tried to change the attributes to:
[TestCase("/some-url/", FormType.ContactForm)]
[TestCase("/some-other-url/", FormType.ContactForm)]
[Category("form")]
And:
[Category("form")]
[TestCase("/some-url/", FormType.ContactForm)]
[TestCase("/some-other-url/", FormType.ContactForm)]
And:
[Test, Category("form")]
[TestCase("/some-url/", FormType.ContactForm)]
[TestCase("/some-other-url/", FormType.ContactForm)]
All with the same result. I looked for people experiencing the same issue, but i found no loads. And i looked for known-issues and bugs on https://github.com/nunit/nunit but found nothing that seemed relevant.
I am using Visual Studio 2015 Community, Update 3 on a Windows 7 Enterprise machine. I have the Nunit 3 Test Adapter Visual Studio extension installed.
Is there anything I am missing? Any help is greatly appreciated of course :)
I would like to be able to run my unit tests across different browsers (FF/IE/Chrome) without having to modify the code to change what webdriver I am using. I am new to selenium testing and would appreciate any recommendations.
I would like to be able to do the following:
run a particular test against a particular browser
run all tests against a particular browser
run all tests against all browsers
Here are some options I have considered but they don't meet my all my needs.
Ask the user (via a Dialog window) which browser to run the test
against
This approach meets condition #1 listed above but not 2 and 3.
This approach would cause the user to be prompted for each test so it does not meet condition #2
Store the default browser in a config file.
The config file can be easily edited with a text editor
This approach meets condition #1 and #2 but requires manually editing
the config file before running the tests.
Here is one easy solution for your problem.
You can use NUnit to execute selenium tests on multiple browsers. All you need to do is download Nunit from NuGet and reference it in your project. Here is a sample code which works just fine.
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Chrome;
namespace MultipleBrowserTesting
{
[TestFixture(typeof(FirefoxDriver))]
[TestFixture(typeof(ChromeDriver))]
[TestFixture(typeof(InternetExplorerDriver))]
public class BlogTest<TWebDriver> where TWebDriver : IWebDriver, new()
{
private IWebDriver _driver;
[Test]
public void Can_Visit_Google()
{
_driver = new TWebDriver();
// Navigate
_driver.Manage().Window.Maximize();
_driver.Navigate().GoToUrl("http://www.google.com/");
}
[TestFixtureTearDown]
public void FixtureTearDown()
{
if (_driver != null)
_driver.Close();
}
}
}
If you are using Visual Studio, you can make use of ordered tests. What I did, I have created three separate test cases namely SetIE, SetChrome and SetFireFox.
[TestMethod]
public void SetIE()
{
Browser.Type = "IE";
}
[TestMethod]
public void SetFireFox()
{
Browser.Type = "FF";
}
[TestMethod]
public void SetChrome()
{
Browser.Type = "CR";
}
These methods just set a string in a class variable and do nothing else.
Create a method to initialize your webDriver
IWebDriver WebDriver = null;
public static void InitializeDriver(TestContext t)
{
if (WebDriver == null)
{
string DRIVER_PATH = #"C:\automation\driversFolder\";
switch (Browser.Type)
{
case "IE":
WebDriver = new InternetExplorerDriver(DRIVER_PATH);
break;
case "FF":
WebDriver = new FirefoxDriver();
break;
case "CR":
WebDriver = new ChromeDriver(DRIVER_PATH);
break;
default:
WebDriver = new FirefoxDriver();
break;
}
}
}
See this blog post which more or less describes this solution.
Now what you have to do is to create an ordered test for IE. Put the first test case SetIE there. and below that put your other test case like login etc. Now you have one suite ready to execute your test cases in IE. Similary create ordered tests for Chrome and FireFox. After that , create a fourth orderedtest named "All Browsers". Inside it ,place all of your 3 ordered tests.
After that , here is what you can do now.
A) If you want to run a single test case against a specific browser, just change the browser name in your class and run that test case.
B) if you want to run all test against a particular browser, just execute the ordered test of that particular broser .
C) If you want to run all tests on all browsers, run your fourth ordered test.
I hope it helps.
I have three projects
1)unmanaged c++ containing full business logic
2)C++/CLI (Project name managed)
3)C# GUI
I have added the library file of unmanaged c++ in C++/CLI and then dll of C++/CLI in C# project.This this all is working fine and execution is trouble-less.
Now i want to do unit testing of C# function that does call the C++/CLI wrapper and then get the results back.I created a unit test using Visual Studio 2010.I added the dll of C++/CLI in my test project.Now when i am trying to execute the test it throws the exception managed.dll not found
Here is the code
[TestMethod()]
public void getstateTest()
{
bool expected=true;
bool actual=false;
try
{
GUI.test target = new test();
expected = true; // TODO: Initialize to an appropriate value
actual = target.getstate();
}
catch (FileNotFoundException exception)
{
MessageBox.Show("Missing file is : " + exception.FileName);
}
Assert.AreEqual(expected, actual);
}
The getstate function is
namespace GUI
{
public class test
{
public bool getstate()
{
bool chk = false;
bool result;
String a = "some path";
String b = "some path"
String c = "some path"
managed objct;
objct = new managed();
objct.Initialize(a, b, c, chk);
objct.Execute();//calls the C++/CLI execute which calls unmanaged C++
result = objct.Executionresult();//gets a bool result
return result;
}
}
}
Same thing works fine when i run the application but on running the test project it says the dll is missing
Sorry if i made it confusing.Please ask if you need more information.Thanks in advance
Have you looked at the test project output folder ? Maybe the managed.dll isn't copied to the output.
Update:
Could you please post fusion log from the exception ? This should give some ideas why the file is not found.
The projects are probably compiling to different directories.
This causes the compiler to compile correctly, but at runtime it can't find the files.
This often happens when you import separate projects into a new solution.
Make the new Unit test compile to the same directory.