Do you use TestInitialize or the test class constructor to prepare each test? and why?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In MSTest, both the test class constructor and TestInitialize run before each test method, so the question is not whether either one works. The real question is what kind of setup you need and which lifecycle behavior makes the test easier to understand and maintain.
The Order of Execution Matters
MSTest creates a new instance of the test class for each test. The constructor runs first, then MSTest sets TestContext, and then any TestInitialize methods run before the test method itself.
That gives you two different setup hooks with different capabilities:
- Constructor for simple synchronous object construction
- '
TestInitializefor framework-aware per-test setup'
A small example makes the distinction clear:
This is a good constructor use case. The test depends on a simple object that can be created synchronously and stored in a readonly field.
Why Constructors Are Often the Better Default
For straightforward setup, constructors are attractive because they are ordinary C# and they encourage immutability.
Benefits of constructor-based setup:
- Easy to read because it is standard object initialization
- Works naturally with
readonlyfields - Keeps simple setup close to the field declarations
- Avoids lifecycle attributes when you do not need them
That last point matters. A lot of test code becomes noisier than necessary because every piece of setup is pushed into framework hooks even when the setup is just "new up a dependency."
When TestInitialize Is the Better Choice
TestInitialize becomes the right tool when the setup is not just construction. The biggest reasons are async work, access to MSTest features, or behavior that depends on framework ordering.
This setup belongs in TestInitialize because:
- The work is asynchronous
- '
TestContextis available' - You may want MSTest attributes such as timeout support on the initialization method
Those are things the constructor cannot do well.
A Useful Rule of Thumb
A practical rule is:
- Use the constructor for simple, synchronous, always-needed setup
- Use
TestInitializewhen setup is async, framework-aware, or more operational than structural
You can also combine them. That is often the cleanest design.
Here the constructor creates durable per-test infrastructure, while TestInitialize prepares mutable state that should be refreshed before each test method.
Exception and Cleanup Behavior
One subtle difference is failure handling. If the constructor throws, the test instance never fully exists, so later cleanup hooks are more limited. If TestInitialize throws, MSTest still has a created test instance and cleanup behavior is more predictable.
That does not mean constructors are risky; it just means setup logic that can fail in more operational ways often fits better in TestInitialize.
Another important point is TestContext. Because MSTest sets TestContext after constructing the test instance, code in the constructor should not rely on it. If you need the current test name, output logging, or similar runtime information, TestInitialize is the correct hook.
Avoid Overengineering Test Setup
The worst pattern is not choosing one hook over the other. The worst pattern is stuffing too much work into either of them:
- Slow I/O in every test when it could be moved to class-level setup
- Hidden global state changes
- Complex branching that makes tests hard to reason about
Per-test setup should be short, explicit, and local to the behavior under test. If many tests need expensive shared fixtures, that is usually a sign to look at ClassInitialize, disposable fixtures, or a different test design.
Common Pitfalls
- Using
TestInitializefor trivial object creation that would be clearer in a constructor. - Using the constructor for async setup, which it does not support cleanly.
- Assuming
TestContextis available inside the constructor. - Mixing mutable test state into
readonlysetup without a clear reason. - Putting too much expensive work into per-test setup instead of moving it to a broader lifecycle hook.
Summary
- Both the constructor and
TestInitializerun before each MSTest test method. - Constructors are usually better for simple synchronous setup and
readonlyfields. - '
TestInitializeis better for async setup,TestContext, and framework-aware initialization.' - Combining both is often the cleanest approach.
- The right choice depends less on preference and more on the kind of setup you actually need.

