How to access the NUnit test name programmatically? - nunit

Is there some global state somewhere that I can access the currently-running test name?
I have tests which output files into a directory and read them back in. I'd like each test to create a directory to play in and then clean up after itself, and I don't want to push that name in (I'd have to make it unique, and then make sure each test keeps it unique; ew). I could use a GUID, but I'd like helper methods to be able to assume "this is the place where test files should be stored" without having to push that GUID around to them. Again, this augers for a global state somewhere.
Basically, I want a call like TestRunner.Current.CurrentTest.Name. Does such a thing exist?

(Assuming c#)
NUnit.Framework.TestContext.CurrentContext.Test.Name
or
NUnit.Framework.TestContext.CurrentContext.Test.FullName
or if you are really lazy and aren't driving your tests with TestCaseSource (thanks #aolszowka):
this.GetType().ToString()

I haven't upgraded to 2.5.7 yet myself, but it includes a TestContext class that seems to provide just what you're looking for: http://www.nunit.org/index.php?p=releaseNotes&r=2.5.7

Assuming one method per Test, in your NUnit code, you can use reflection to get the method name from the stacktrace.
If you write a helper method in your NUnit code called by other methods to do this file logging, you can use this syntax to check for the previous method:
string MethodName = new StackFrame(1).GetMethod().Name;
See the answers to question 44153, "Can you use reflection to find the name of the currently executing method?" for more details.

If we are using TestCaseSource tag then above solutions might not give correct answer
Try using TestContext.CurrentContext.Test.MethodName
Follow the below example
namespace NunitTests
{
public class Class1
{
static List<TestData> Data = new List<TestData>()
{
new TestData()
{
...
}
};
[Test]
[TestCaseSource(nameof(TenMBInstance))]
public void TestCase(TestData value)
{
TestContext.CurrentContext.Test.Name; //TestCase(NunitTests..TestData)
TestContext.CurrentContext.Test.MethodName; //TestCase
}
}
}

Related

In Katalon Studio, How to retrieve the values using the javascript executor. document.getElementsByTagName('input')[29].value

enter image description here
I tried below code but not works.
a = WebUI.executeJavaScript('document.getElementsByTagName("input")[29].value', null)
Thread.sleep(5000)
System.out.println(a)
There is so much wrong with this question that I don't even know where to begin...
What are you trying to accomplish by using JavaScript (this is a testing code smell, for 99% of testing cases) to fetch a value ?
Why not do the following:
create a TestObject, preferably in the Object Repository, that points to the object in question.
give that Test Object the locator. This is, by default, some xpath.
In your case, give it xpath
(//input)[29]
. However, I advise you come up with a more meaningful selector for it (for example, select it by some class, data-* attribute, name) that is easier to maintain
use the built-in Keyword for getting attribute, like this:
WebUI.getAttribute(findTestObject('[whateverYourTestObjectNameIs]'), 'value')
this is just good code design, but write this to some Custom Keyword for this util:
// import statements here. Ctrl + Shift + O on your keyboard to bring those in
public final class GeneralWebUIUtils {
public static final String Value = "value";
public static final String GetValue(TestObject to) {
return WebUI.getAttribute(to, this.Value);
}
}
Also, why are you pausing runtime by some hard-coded time amount? That is a testing code smell. Stop it!
What exactly are you waiting on? Use the WebUI keywords for this thing you are waiting on, and if none of those suffice, hmu and I may have the wait method you're looking for ....
Oh, and looking at that image you linked, it looks like you solved your own question.

Is there any alternative to [OneTimeSetup] in Nunit?

In my existing [OneTimeSetup] method, I want to check some preconditions before running any test. But I can't do so as the object which I'll be needing to check preconditions is initialized in Base class [Setup] method. I can't initialize this earlier due to some project limitations.
So, Is there any way where I can execute some code after Base [Setup] method (to check some preconditions) and before any suite execution? I want to execute this once per suite.
[SetUpFixture]
Class GlobalSetup
{
[OneTimeSetUp]
public void OneTimeSetUp(){
setup();
CheckIfDataIsPresent(); // I can't do this here as this code needs Obj O to be initialized. which will be initialized in Base class's [Setup] methed
}
}
Public class Base
{
[Setup]
public void setUp()
{
//some code where we initialize obj O;
}
}
[TestFixture]
public class Test : Base
{
// tests to be executed
}
You already did a nice job of explaining why what you want to do won't work, so I don't have to. :-)
The problem is that each your tests needs a fresh instance of that object, so you properly create it in a [SetUp] method. You would like to ensure that it's possible to create such an object once before you run any tests.
I can only give you a non-specific answer, since you haven't given a lot of info in your example code. If you update your question, I may be able to update my answer. Here goes...
Both your tests and the check you want to perform require an instance of object o. So one approach would be to initialize o one more time in the OneTimeSetup, perform the check and then throw it away. Since you are initializing o in every test, I assume it's not expensive to do so. Say you have 100 tests. You are setting up o 100 times. So make it 101 and be done!
Alternatively, determine what is required for o to be initialized successfully and check that. For example, if it needs a file to be present, check that the file is present. If the file has to have 100 records in some format, check that it's so. Perhaps you might give us more detail about what those prerequisites are.
Finally, you might reconsider whether you really need a new instance per test. Since you suggest you would be willing to make a check once per fixture (I assume that's what you mean by suite) then perhaps you really only need one instance per fixture rather than a new one for each test.

GWT-Jackson-APT fails on $wnd.window JSON web-worker code for encoding strings

Finally having gotten GWT-Jackson-APT processors working and properly generating code for my classes, the one remaining hiccup I have is that for some reason gwt-jackson-apt uses the window JSON stringify (& parse) function.
$wnd.window.JSON.stringify(STRING)
The problem is that due to this being on a web-worker, $wnd.window is not defined. Even though JSON.stringify() is available in web-worker, the result is that the code won't run correctly, even though if I modify it to be just JSON.stringify() before uploading it works pefectly.
Is there a clean way to redefine which of these functions gets used in this instance?
What is the best means of going about fixing this so that my web-worker code doesn't try to call the functions that are not available in their context.
The library right now uses the elemental2 version of JSON Global.JSON.stringify
and if we look at the implementation of the JSON in the Global class we will find that it is assigned to the window instance here :
#JsType(isNative = true, name = "window", namespace = JsPackage.GLOBAL)
public class Global {
public static JSONType JSON;
}
when this is used as Global.JSON.stringify(someJsonObject) from GWT java code when compile it will produce $wnd.window.JSON.stringify(someJsonObject) or something very similar.
in order to fix this we need to access the native JSON in a different way that does not link it the current window instance.
one solution to this is to use JsInterop to interface directly with the JSON, something like this
#JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class JSON {
public native static String stringify(Object jsonObj);
}
with this implementation we can use the JSON without the window prefix and when we use it in java like this JSON.stringify(someJsonObject) and notice how we no longer use the one from Global we end up with a generated Js that looks like this $wnd.JSON.stringify(someJsonObject)
i run a small test and implemented this JSON in the jackson-apt lib and switched to use the new implementation instead of using Global.JSON and all tests passed.
to me this looks like a good issue to be reported on the project repository. and i will apply the fix ASAP.

Migration problems when migrate from NUnit 2.X to NUnit 3.X

I'm using NUnit 2.X library but want to use NUnit 3.X now. I have some problems about migration from 2.X to 3.X. First i have a setup fixture class. Here is the 2.X version;
using System;
using System.IO;
using System.Reflection;
using HalisEnerji.QuantSignal.Logging;
using NUnit.Framework;
namespace HalisEnerji.QuantSignal.Tests
{
[SetUpFixture]
public class Initialize
{
[SetUp]
public void SetLogHandler()
{
Log.LogHandler = new ConsoleLogHandler();
}
}
}
First problem is fixed via change "Setup" attribute with "OneTimeSetUp" attribute. Second problem fixed via add some codes for set test directory. Because i'm using Re-Sharper test engine. Here is final shape of setup fixture;
using System;
using System.IO;
using System.Reflection;
using HalisEnerji.QuantSignal.Logging;
using NUnit.Framework;
namespace HalisEnerji.QuantSignal.Tests
{
[SetUpFixture]
public class Initialize
{
[OneTimeSetUp]
public void SetLogHandler()
{
Log.LogHandler = new ConsoleLogHandler();
var assembly = Assembly.GetExecutingAssembly();
var localPath = new Uri(assembly.CodeBase).LocalPath;
var direcotyName = Path.GetDirectoryName(localPath);
if (direcotyName != null)
{
Environment.CurrentDirectory = direcotyName;
}
}
}
}
Well after solve setup fixture problem, my real problems begins with use TestCaseSource/TestCaseData. Here is sample 2.X version;
[Theory]
[TestCaseSource("CreateSymbolTestCaseData")]
public void CreateSymbol(string ticker, Symbol expected)
{
Assert.AreEqual(Symbol.Create(ticker), expected);
}
private TestCaseData[] CreateSymbolTestCaseData()
{
return new []
{
new TestCaseData("SPY", new Symbol(Security.GenerateEquity("SPY"), "SPY")),
new TestCaseData("EURUSD", new Symbol(Security.GenerateForex("EURUSD"), "EURUSD"))
};
}
2.X version creating exception and my tests are fail. Shortly exception telling that TestCaseData provider method must be static. Well, after mark method with static identifier test working correctly but this time my other test failing (before use static identifier it's not failing). Why my other test failing? Because it's reading a file from test directory and somehow test working before setup up fixture codes run and change test directory!
Before use static identifier first SetUpFixture codes run and then tests code run. After use static identifier order changing my test that read file from test directory (which is Re-Sharper's temporary directory and not contain necessary file) run first after that SetUpFixture codes run. Any idea how all my tests to be successful?
UPDATE:
Explain some units;
I have Initialize.cs (part of my test assembly) which is responsible setup CurrentDirectory.
I have Config.cs (part of my project infrastructure assembly) which is my project configuration file and it has public static readonly Setttings property which is reading configuration file from CurrentDirectory.
I have ConfigTests.cs (part of my test assembly) which is contain some test methods for read/write Settings property.
When i debug tests;
Before use any static TestCaseSource, they are working below order;
A. Initialize.cs => Setup method
B. Config.cs => static Settings property getter method
C. ConfigTests.cs => first test method
So initialize working first others working later all tests successfully passing from test.
After use static TestCaseSource for inside other test file lets say OrdersTests.cs (excluded from project for first scenario after that included again), somehow working order is changing like below;
A. Config.cs => static Settings property getter method
B. OrdersTests.cs => static TestCaseSource method (not test method)
C. Initialize.cs => Setup method
D. ConfigTests.cs => first test method
E. OrdersTests.cs => first test method
So, my ConfigTests.cs tests failing because Initialize.cs working after Config.cs. I hope with this update my problem is more clear.
Is this problem related NUnit or Resharper or V.Studio? I don't know and all i know is my successfully passing tests are failing now!
UPDATE 2:
Chris,
Yes you are right. I explore project in detail and i saw the problem is related that my project's some classes accessing to static Config class and it's static Settings property (before run test setup fixture method and even before static test case source method!). You talk about order of process of test methods; NUnit doing tests like your said, not like i said. But when i try to use your solution (set current directory before test case source) it's not working. Because of that i solve my problem in another way. I'm not happy but at least my test methods working now. Could you please tell me what are the technical reasons that run static test case methods before initialize/setup method? Is this because of NUnit or because of infrastructure of .Net Framework? I'm not fanatic about NUnit and/or TDD. I don't have deep knowledge about these concepts but it does not make sense to me: run any method before setup method.
Thanks for your interest.
Because it's reading a file from test directory and somehow test working before setup up fixture codes run and change test directory!
How are you reading this file? You should use TestContext.CurrentContext.TestDirectory to get the test directory in NUnit 3, rather than relying on the location of the current directory. See the Breaking Changes page for details.
Edit: I also see you've tagged this ReSharper 7.1. You should be aware that this version of resharper does not support NUnit 3 - the first version that did is ReSharper 10. Your tests will appear to run correctly - however you may experience weird side effects, and this may break in any future version of NUnit.
Response to update:
Take a look at NUnit 3's Breaking Changes page. There are two relevant breaking changes between NUnit 2 and 3.
TestCaseSource's must now be static.
The CurrentDirectory is no longer set to Environment.CurrentDirectory by default.
The first you've solved easily enough. The second, is what's now causing you issues.
NUnit 3 runs it's methods in this order:
Evalute TestCaseSource methods (OrdersTests.cs)
Run SetUpFixture (Initialize.cs)
Run Test (ConfigTests/OrdersTests)
I'm not sure what Config.cs is being called before your TestCaseSource method - are you sure of that order? Does anything in CreateSymbolTestCaseData() call anything in Config.cs You could try rewriting your TestCaseSource as such:
private TestCaseData[] CreateSymbolTestCaseData()
{
Environment.CurrentDirectory = "c:\RequiredDirectory";
return new []
{
new TestCaseData("SPY", new Symbol(Security.GenerateEquity("SPY"), "SPY")),
new TestCaseData("EURUSD", new Symbol(Security.GenerateForex("EURUSD"), "EURUSD"))
};
}

How can I fake a Class used insite SUT using FakeItEasy

Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.