Is there any alternative to [OneTimeSetup] in Nunit? - frameworks

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.

Related

Define order of "Parallelizable" in NUnit

Im having 4 test classes inside one project (Lets call them Class A, Class B, Class C, Class D)
Each of these 3 classes have two [TestFixture("string")], which makes it to 8 tests in total.
All classes are having the [Parallelizable] parameter.
When i start the test all at once by clicking inside the Test Explorer on the name of the project and "Run", then it will start all 8 tests at the same time.
The problem here is, that it consumes a lot RAM and the tests fail because it takes too long to load and i get a timeout error (Im doing automation tests with selenium in chrome)
Now i want to define a order.
For example:
Class A and Class B should start parallel
Class C and Class D should start parallel when Class A and Class B is done
Is it possible?
I tried the parameter [Order(1)] for Class A and Class B and Order(2)] for Class C and Class D
But when i run the tests, all 8 tests start to load.
Example from my code:
[TestFixture("normalUser")]
[TestFixture("adminUser")]
[Parallelizable]
public class ImportTest
{
private IWebDriver webDriver;
private const int waitTimer = 60;
public WebDriverWait w;
public string userRole;
// Constructor
public ImportTest(string userRole)
{
this.userRole = userRole;
Console.WriteLine(userRole);
}
////-----------------------------
[SetUp]
{
}
//-------------------------------
[Test]
public void Test1()
{
Do Test
}
[Test]
public void Test2()
{
Do Test
}
//--------------------------
[TearDown]
public void CloseBrowser()
{
webDriver.Quit();
}
}
First, I'll describe what's happening...
The OrderAttribute was created in NUnit V2, before parallel tests existed. It defines the order in which tests are started. Since there was no parallelism at the time, one test had to finish before the next one started.
When parallel execution was introduced in NUnit 3, Order was not exactly broken, because it continued to start tests in the specified order. But many users perceptions were "broken", because they thought that one test would not start until the prior one finished.
Order could, of course, be changed to work like that. However, at this point, that would be a breaking change for some people, so you most likely won't see it happen until there's an NUnit 4.
So... what can you do as a workaround? I can see three options...
The simplest approach would be to make each fixture [NonParallelizable]. Then they would all run separately. You should try that first and see if the performance is acceptable to you. If you want the tests within each fixture to run in parallel, you could use [Parallelizable(ParallelScope.Children)] instead but that might break things if the tests change the state of the fixture or of any common references found in the fixture.
Alternatively, you could pick only some fixtures to mark as [NonParallelizable]. In that case, I'd do it for the ones that consume a lot of memory.
For the most effort required, you could implement ordering yourself for these classes. I'd do that by creating some sort of shared token... e.g. a lock... which each class had to acquire on startup. I'd grab the lock in the OneTimeSetUp for a fixture and release it in the onetime teardown. The locking code should be before any setup code, which acquires resources and should be released after your teardown releases those resources.
I made option 3 rather sketchy because (a) I don't know precisely how your application works and (b) I presume that you won't do it unless it's absolutely necessary.
Final advice: don't make any assumptions about the performance impact of any of these options, even the first. Measure first!

Prevent NUnit from executing test setup method from another class?

I've got an odd question for which Google has proven barren:
I've got a project in .net with ~20 classes that all have tests in them. One of the classes has common test setup code, although a few of the classes have their own TestFixtureSetup that looks exactly like the common class (not my architecture choice - this predates my employment). I have my own test class for which I have some different code that runs prior to running a few particular tests within the class.
Some more info that's relevant: The custom setup code that I have enables data to be available for a few combinatorial tests I have in my own test class. As the value source for the combinatorial params, the List that is returned first initializes some data.
Alright, here's the question: When I try to run a test in ANOTHER test class, it's "building" the tests from every other class. In my case, it's building the combinatorial test that I have - and thus, triggering the custom setup method that I have.
How do I prevent NUnit from building tests in other classes? As in, I run a test in one class, all I'd like NUnit to do is build tests from that class ONLY.
I tried to remove any NDA-no-no language, but here's the combinatorial I have:
[Test, Combinatorial, Category("Regressive")]
public void Test05_CombiTestExample(
[ValueSource("ListA")] User user,
[ValueSource("ListB")] KeyValuePair<string, string> searchKvp,
[ValueSource("ListC")] string scope)
{
And here's one of the lists that is being reference:
public IEnumerable<KeyValuePair<string, string>> ListB
{
get
{
InitCustomData();
if ([Redacted] != null)
{
return new Dictionary<string, string>()
{
[Redacted]
};
}
return null;
}
}
The line in question is "InitCustomData();" which, because my combinatorial is being built prior to running any setup or anything, is being executed anyway. I want this to stay here - I just don't want NUnit to start building test cases from any other class besides the one it's currently running a test in.

Is there a equivalent of testNG's #BeforeSuite in JUnit 4?

I'm new to the test automation scene so forgive me if this is a stupid question but google has failed me this time. Or at least anything I've read has just confused me further.
I'm using JUnit 4 and Selenium Webdriver within Eclipse. I have several tests that I need to run as a suite and also individually. At the moment these tests run fine when run on their own. At the start of the test an input box is presented to the tester/user asking first what server they wish to test on (this is a string variable which becomes part of a URL) and what browser they wish to test against. At the moment when running the tests in a suite the user is asked this at the beginning of each test, because obviously this is coded into each of their #Before methods.
How do I take in these values once, and pass them to each of the test methods?
So if server = "server1" and browser = "firefox" then firefox is the browser I want selenium to use and the URL I want it to open is http://server1.blah.com/ for all of the following test methods. The reason I've been using seperate #Before methods is because the required URL is slightly different for each test method. i.e each method tests a different page, such as server1.blah.com/something and server1.blah.com/somethingElse
The tests run fine, I just don't want to keep inputting the values because the number of test methods will eventually be quiet large.
I could also convert my tests to testNG if there is an easier way of doing this in testNG. I thought the #BeforeSuite annotation might work but now I'm not sure.
Any suggestions and criticism (the constructive kind) are much appreciated
You can adapt the solution for setting a global variable for a suite in this answer to JUnit 4 Test invocation.
Basically, you extend Suite to create MySuite. This creates a static variable/method which is accessible from your tests. Then, in your tests, you check the value of this variable. If it's set, you use the value. If not, then you get it. This allows you to run a single test and a suite of tests, but you'll only ask the user once.
So, your suite will look like:
public class MySuite extends Suite {
public static String url;
/**
* Called reflectively on classes annotated with <code>#RunWith(Suite.class)</code>
*
* #param klass the root class
* #param builder builds runners for classes in the suite
* #throws InitializationError
*/
public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
this(builder, klass, getAnnotatedClasses(klass));
// put your global setup here
MySuite.url = getUrlFromUser();
}
}
This would be used in your Suite like so:
#RunWith(MySuite.class)
#SuiteClasses({FooTest.class, BarTest.class, BazTest.class});
Then, in your test classes, you can either do something in the #Before/#After, or better look at TestRule, or if you want Before and After behaviour, look at ExternalResource. ExternalResource looks like this:
public static class FooTest {
private String url;
#Rule
public ExternalResource resource= new ExternalResource() {
#Override
protected void before() throws Throwable {
url = (MySuite.url != null) ? MySuite.url : getUrlFromUser();
};
#Override
protected void after() {
// if necessary
};
};
#Test
public void testFoo() {
// something which uses resource.url
}
}
You can of course externalize the ExternalResource class, and use it from multiple Test Cases.
I think the main functionality of TestNG that will be useful here is not just #BeforeSuite but #DataProviders, which make it trivial to run the same test with a different set of values (and won't require you to use statics, which always become a liability down the road).
You might also be interested in TestNG's scripting support, which makes it trivial to ask the user for some input before the tests start, here is an example of what you can do with BeanShell.
It might make sense to group tests so that the test suite will have the same #Before method code, so you have a test suite for each separate.
Another option might be to use the same base url for each test but navigate to the specific page by getting selenium to click through to where you want to carry out the test.
If using #RunWith(Suite.class), you can add static methods with #BeforeClass (and #AfterClass), which will run before (and after) the entire Suite you define. See this question.
This of course won't help if you are referring to the entire set of classes found dynamically, and are not using Suite runner.

How to access the NUnit test name programmatically?

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
}
}
}

StructureMap is not reset between NUnit tests

I'm testing some code that uses StructureMap for Inversion of Control and problems have come up when I use different concrete classes for the same interface.
For example:
[Test]
public void Test1()
{
ObjectFactory.Inject<IFoo>(new TestFoo());
...
}
[Test]
public void Test2()
{
ObjectFactory.Initialize(
x => x.ForRequestedType<IFoo>().TheDefaultIsConcreteType<RealFoo>()
);
// ObjectFactory.Inject<IFoo>(new RealFoo()) doesn't work either.
...
}
Test2 works fine if it runs by itself, using a RealFoo. But if Test1 runs first, Test2 ends up using a TestFoo instead of RealFoo. Aren't NUnit tests supposed to be isolated? How can I reset StructureMap?
Oddly enough, Test2 fails if I don't include the Initialize expression. But if I do include it, it gets ignored...
If you must use ObjectFactory in your tests, in your SetUp or TearDown, make a call to ObjectFactory.ResetAll().
Even better, try to migrate your code away from depending on ObjectFactory. Any class that needs to pull stuff out of the container (other than the startup method) can take in an IContainer, which will automatically be populated by StructureMap (assuming the class itself is retrieved from the container). You can reference the IContainer wrapped by ObjectFactory through its Container property. You can also avoid using ObjectFactory completely and just create an instance of a Container that you manage yourself (it can be configured in the same way as ObjectFactory).
Yes, NUnit tests are supposed to be isolated and it is your responsibility to make sure they are isolated. The solution would be to reset ObjectFactory in the TearDown method of your test fixture. You can use ObjectFactory.EjectAllInstancesOf() for example.
Of course it doesn't reset between tests. ObjectFactory is a static wrapper around an InstanceManager; it is static through an AppDomain and as tests run in the same AppDomain this is why it is not reset. You need to TearDown the ObjectFactory between tests or configure a new Container for each test (i.e., get away from using the static ObjectFactory).
Incidentally, this is the main reason for avoiding global state and singletons: they are not friendly to testing.
From the Google guide to Writing Testable Code:
Global State: Global state is bad from theoretical, maintainability, and understandability point of view, but is tolerable at run-time as long as you have one instance of your application. However, each test is a small instantiation of your application in contrast to one instance of application in production. The global state persists from one test to the next and creates mass confusion. Tests run in isolation but not together. Worse yet, tests fail together but problems can not be reproduced in isolation. Order of the tests matters. The APIs are not clear about the order of initialization and object instantiation, and so on. I hope that by now most developers agree that global state should be treated like GOTO.