VS Team Test: several test initialization methods in a test class

I have a unit test project called "MyClassTest" in TeamTest. This project has three TestMethods methods. Each method needs its own steps to initialize the test. But when I apply TestInitializeAttribute to the three initialization methods, it says that the attribute should not be used more than once. Then what should be the attribute that will be used to initialize each test method in Visual Studio Team Test?

Link:

  • VS Team Test: testing .Net using Excel as a data source: adapter failure

  • How to create a run and cleanup script for a Visual Studio testing project?

  • VS 2010 Download Tests Using Custom Counters

  • How to register a unit test record and exit to MSTest

  • Can the unit test project load the app.config file of the target application?

+8
c # unit-testing visual-studio-2010
source share
5 answers

According to MSDN TestInitializeAttribute :

  • cannot be used more than once (AllowMultiple = false) and
  • cannot be inherited to create your own TestInitializeAttribute .

So my suggestion is to create test initialization methods without the TestInitialize attribute. Then, in a unique test of the TestInitialize method TestInitialize check the current current TestMethod and call the appropriate initialization method:

 [TestClass] public class UnitTest { public TestContext TestContext { get; set; } [TestInitialize] public void Initialize() { switch (TestContext.TestName) { case "TestMethod1": this.IntializeTestMethod1(); break; case "TestMethod2": this.IntializeTestMethod2(); break; default: break; } } [TestMethod] public void TestMethod1() { } [TestMethod] public void TestMethod2() { } public void IntializeTestMethod1() { //Initialize Test Method 1 } public void IntializeTestMethod2() { //Initialize Test Method 2 } } 
+18
source share

If you have three test methods, and each method has its own initialization steps , then why do you move the initialization to the method that will be executed before each test? The only advantage I see is a nice blocking block that adds some lines to the source file. But this gives you a drawback - looking at any of these testing methods, you cannot tell in what context the context method will be executed. Thus, I use the initialization method to set only the basic context, which is really used by all tests in the device.

Just move the context creation to the arrange part of each method.

If you have several methods that use a common context, then simply extract the method that will set the context for them and call it in the arrange part. You can also divide each context setting into several steps and reuse these steps (for example, in given-when-then tools such as Specflow ).

And, of course, the creation of various devices is also possible.

+11
source share

This is a bit old post, but I came up with the following, which seems to work fine: First define the attribute class:

 [AttributeUsage(AttributeTargets.Method, Inherited = true)] public class InitialiseWithAttribute : Attribute { public string Id { get; private set; } public InitialiseWithAttribute(string id) { Id = id; } } 

then define an extension method in some convenient utility class:

  public static bool IsInitialisedWith(this string testName, string value) { bool result = false; Type testClassType = new StackFrame(1).GetMethod().DeclaringType; MethodInfo methodInfo = testClassType.GetMethod(testName); if (methodInfo != null) { InitialiseWithAttribute initialiseWithAttribute = methodInfo.GetCustomAttribute<InitialiseWithAttribute>(true); if (initialiseWithAttribute != null) { result = initialiseWithAttribute.Id == value; } } return result; } 

Now write your tests like this:

  public TestContext TestContext {get; set;} [TestInitialize] public void TestInitialise() { if (TestContext.TestName.IsInitalisedWith("DoSomethingSpecial") { // ... Do something special } else { // ... Do something normal } } [TestMethod] [InitialiseWith("DoSomethingSpecial")] public void MySpecialTest() { // The test } 
+4
source share

If they need three separate entrances; then they should probably be in three separate lights, each with its own init!

+3
source share

In my work, we pass an argument to the TestInitialize method to determine how we want the initialization work to work.

 public partial class CommonActions { public void TestInitialize(bool adminTest) { try { if (adminTest) { //do stuff } 

Then we have standard initialization in the class definition, which defaults to false.

 [TestClass] public class ProjectTestBase : FrameworkTestBase { public CommonActions common { get; set; } = new CommonActions(); [TestInitialize] public void TestInitialize() => common.TestInitialize(false); 

Then in the tests themselves you can override TestInitialize for any test you want.

 [TestClass] public class SetReportsInAdmin : ProjectTestBase { [TestInitialize] public new void TestInitialize() => common.TestInitialize(true); 

We use a boolean to determine if there is an administrator test that needs to have extra overhead to configure. Take this and apply whatever variables you want, in such a way as to give you multiple initializations using a single method.

+2
source share

All Articles