-1

Updated question ::

I want to set up data before any Test in the test suite is run using xUnit.net. I tried IUseFixture but its run before any test class is run (not before the test suite)

Consider your suite has 2 test classes having 2 tests/class, when tried with IUseFixture, SetFixture runs 4 times (once per test).

I need something that run only once when all the four tests run simultaneously (once per test suite)... , here is the example (using WebDriver/C#/xunit)::

Class 1:

 public class Class1 : IUseFixture<BrowserFixture>
{
    private IWebDriver driver;

    public void SetFixture(BrowserFixture data)
    {
        driver = data.InitiateDriver();
        Console.WriteLine("SetFixture Called");
    }

    public Class1()
    {
        Console.WriteLine("Test Constructor is Called");
    }

    [Fact]
    public void Test()
    {
        driver.Navigate().GoToUrl("http://www.google.com");
        driver.FindElement(By.Id("gbqfq")).SendKeys("Testing");
    }

    [Fact]
    public void Test2()
    {
        driver.Navigate().GoToUrl("http://www.google.com");
        driver.FindElement(By.Id("gbqfq")).SendKeys("Testing again");
    }
}

Class 2 :

 public class Class2 : IUseFixture<BrowserFixture>
{
    private IWebDriver driver;

    public void SetFixture(BrowserFixture data)
    {
        driver = data.InitiateDriver();
        Console.WriteLine("SetFixture Called");
    }

    public Class2()
    {
        Console.WriteLine("Test Constructor is Called");
    }

    [Fact]
    public void Test3()
    {
        driver.Navigate().GoToUrl("http://www.google.com");
        driver.FindElement(By.Id("gbqfq")).SendKeys("Testing");
    }

    [Fact]
    public void Test4()
    {
        driver.Navigate().GoToUrl("http://www.google.com");
        driver.FindElement(By.Id("gbqfq")).SendKeys("Testing again");
    }
}

Fixture Class ::

 public  class BrowserFixture
{
    private  IWebDriver driver;
     public BrowserFixture()
     {

         driver = new FirefoxDriver();

     }

    public  IWebDriver InitiateDriver()
    {
        return driver;
    }

}

Now when i run Test,Test2,Test3,Test4 simultaneously , SetFixture is called 4 times , i need something that run only once before any test run (once per test suite) or i can say something that run only once before any of the test class in the TestSuite is intialized , something like BeforeSuite in TestNG ::

http://testng.org/javadoc/org/testng/annotations/BeforeSuite.html http://testng.org/doc/documentation-main.html#annotations

user522170
  • 623
  • 1
  • 6
  • 21
  • `SetFixture` runs once per **test**, not class. The ctor of the test class runs once per test. – Ruben Bartelink Apr 09 '14 at 12:27
  • 1
    If my answer is insufficient, you need to explain more of what you're trying to achieve overall than a low level requirement as you have stated – Ruben Bartelink Apr 09 '14 at 12:31
  • Especially be sure to check JaredKells's answer. I remember that it was true - the appdomains are created on the fly for test assemblies. Although I've been digging in the subject quite a time ago, around the time I've been working on xvsr10 (xUnit runner for VS2010), it's likely that it has not changed since then. – quetzalcoatl Apr 09 '14 at 12:46
  • @quetzalcoatl Good spot. I believe Collection Fixtures in V2 might also be leveragable to achieve similar effects. – Ruben Bartelink Apr 09 '14 at 13:22
  • In your question, `BrowserFixture`'s ctor is run exactly once. I really don't understand your issue (or how this question or my answer improves on [your original Question](http://stackoverflow.com/questions/22804317/xunit-create-new-instance-of-test-class-for-every-new-test-using-webdriver-and/22805115#22805115) or @MarkSeemann's original answer) – Ruben Bartelink Apr 09 '14 at 20:16
  • Have you tried [@Mark Seemann's answer](http://stackoverflow.com/a/22805115/11635) and put breakpoints in it ? If it works, you should delete this question. If it doesn't, you should ask a question and/or unaccept it – Ruben Bartelink Apr 09 '14 at 20:26
  • Hey Ruben , @MarkSeeman's answer works at class level not at Suite level, e.g if i have 3 classes in a suite then IUseFixture ctor is called 3 times , i need something that will be called only once irrespective of number of classes in a suite – user522170 Apr 10 '14 at 07:04
  • @user522170 Then use a static ctor in the `MyFixture` ? – Ruben Bartelink Apr 10 '14 at 08:31
  • i can use static ctor but it doesn't solve my issue because the fixture object (here dummy) is available to me after the test class constructor is called i.e a) First static ctor of fixture is called b) Then test class constructor is called c) Then SetFixture is called , whether its possible to get access to SetFixture in Test class constructor ?? , if yes?? then it will solve my problem – user522170 Apr 10 '14 at 09:03
  • Why can't you defer the relevant bits of work your ctor wants to do with the Fixture into the `SetFixture` impl? BTW if you put @RubenBartelink in the comment then I'll see it - it's only coincidence I saw this – Ruben Bartelink Apr 10 '14 at 12:22
  • @RubenBartelink , issue is that at present our test framework is designed in such a way that Test class passes Driver object to it's base class , and we need to change the implementation so that Driver will be created by Fixture , that's why asked this question, and if i create Driver in SetFixture then i may not able to pass Driver to Test base class and in order to change that we have to do large scale change in our framework. That's why asked if there is something like BeforeSuite (present in TestNG) in Xunit – user522170 Apr 10 '14 at 13:11
  • Think of `SetFixture` as a post-create init step. In your case, I'd have a static Fixture class (possibly using a Singleton a la Jon Skeet's articles) and then pass it it as necessary. You can use the static ctor on that Fixture do the creation - i.e. don't use xUnit's `IUseFixture` stuff as you're doing something far more global. IOW as quetzalcoatl's [cited answer by JaredKell](http://stackoverflow.com/a/14950904/11635). I guess you don't need me to tell you that a deep hierarchy of Test Classes is bad news and that composition of fixtures is a better way to go but I will anyway :P – Ruben Bartelink Apr 10 '14 at 15:35

1 Answers1

3

The ctor of the fixture will run only once:-

public class Facts : IUseFixture<MyFixture>
{
    void IUseFixture<MyFixture>.SetFixture( MyFixture dummy){}
    [Fact] void T(){}
    [Fact] void T2(){}
}

class MyFixture
{
    public MyFixture() 
    {
        // runs once
    }
}
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249