39

I'm curious as to why the fixture setup must be static? It seems more intuitive to me to have instance variables per fixture that share the lifetime of the fixture.

Yes, these can be initialized in the constructor, but then I assume they are out of reach of the control of the test runner.

What design requirements or philosophies determined that the setup method should be static?

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
ProfK
  • 49,207
  • 121
  • 399
  • 775

1 Answers1

46

The method with the ClassInitialize attribute runs once for all the tests in the class. An instance of the class is created each time a test is run, so it has to be static in order to only run once.

If you want to initialize for every test, then you can use the TestInitialize attribute, which will run whenever a new instance of the class is created (before running a test).

If you need more info, you can check out:

That Pesky MSTest Execution Ordering

riQQ
  • 9,878
  • 7
  • 49
  • 66
Stephen Oberauer
  • 5,237
  • 6
  • 53
  • 75
  • 13
    Thanks, I didn't know an instance was created for each test. – ProfK Aug 26 '12 at 19:45
  • 6
    I don't think the method has to be static to run just once. The testing framework is initializing and executing the test classes we right. It could easily call a non-static method before and after it runs all the test methods. – d512 Aug 10 '14 at 21:05
  • 1
    If it wouldn't be static the initialization couldn't be shared with all test instances. I.e. if you need to initialize a mock service used by all tests. – user3285954 Sep 30 '15 at 09:57
  • 4
    @user3285954 That makes no sense; if you need to initialize a service used by all tests, that can be an instance method which sets instance state in the class shared by all tests. There's no reason it has to be static. – casperOne Oct 08 '15 at 13:34
  • If it's the same for every test it is redundant to have it recreated many times, a class may have 10+ tests. Especially if it's an expensive operation. Instance state will be lost after test completes, will not be available for the next test. If you want to do something before every test run you should use TestInitialize and store in instance members as it was pointed out and as it is clearly described in quite a few places. And if you need initialization before any of the test classes are cretated use AssemblyInitialize. Each has its own place and purpose in test lifecycle. – user3285954 Oct 08 '15 at 18:59
  • Regarding `an instance of the class is created each time a test is run`, if you don't like this try something like NUnit which creates only one instance per class/fixture. Which sounds great if you want to share state and know what you are doing regarding side-effects – KCD Jan 28 '16 at 21:02
  • Great answer! That was really informative and helpful. – Rich Jan 25 '18 at 19:50