title: MsTest datadriven: ignore specific datarows via testattribute?
body: <p>my first question on stackoverflow and I'm hoping it's not a stupid one. :)</p>
  
  <p>Basically all my datadriven tests look like this one:</p>
  
  <pre><code>[TestMethod]
  [DataSource(TestsDataSource)]
  public void Test_With_Some_Fancy_Name()
  {
     if (myIsThisTestIgnored) return;
  ...
  </code></pre>
  
  <p>DataSource attribute + app.config connectionstring + excel odbc driver = excel datadriven tests.</p>
  
  <p><code>myIsThisTestIgnored</code> is set in the <code>[TestInitialize]</code> method (for every datarow there is a separate test with separate <code>[TestInitialize]</code>), via <code>TestContext.DataRow["Ignore"]</code>, so I can "ignore" tests via some true/false in an excel sheet. </p>
  
  <p><strong>Now my problem is</strong>: just returning from a test method lets the test pass. How to not let the ignored tests "pass" in the MSTEST testrunner (and in the CI via msbuild), or even better, do not show them at all?</p>
  
  <p>On our Ci Build, it sums up every ignored (a.k.a passed) test, as the count of test is <code>datarows x number</code> of testmethods, giving a faulty impression of the number of tests that ran. But, until now, I found no way to just set the test result to "ignored" (or any other state than "passes"/"failed") programmatically.</p>
  
  <p>Besides, getting rid of this annoying ignore line in every test and enhancing the assert messages without wrapping every assert in some function would be nice, too.</p>
  
  <p>So the best/only approach to this, I thought, would be AOP style programming and using custom attributes. I found this old post about enhancing your mstest code with custom attributes, good read: <a href="http://callumhibbert.blogspot.com/2008/01/extending-mstest.html" rel="nofollow">http://callumhibbert.blogspot.com/2008/01/extending-mstest.html</a></p>
  
  <p>Specifically the last comment in the linked article got me thinking, as the guy not just made my day by showing how to access all test state data to the attribute (the MarshalObject stuff), but somehow he got it working, quoting him <em>"In this manner, I can determine whether or not to run a test based on a matrix of data driven information from the text context (using the DataSource attribute), and the new custom attributes I created. "</em>. <strong>Yeah.. but how to do that?</strong></p>
  
  <p>I took some of the code and implemeted it, looking something like that:</p>
  
  <pre><code>public class MyCustomAspect : TestAspect&lt;MyCustomAttribute&gt;, IMessageSink, ITestAspect
  { ....
  
      [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure)]
      public IMessage SyncProcessMessage(IMessage msg)
      { 
        ....
        // see last comment in linked article to how to get this MarshalObject
        MyTestsClass testClass = (MyTestsClass)MarshalObject;
  
        if(testClass.myTestInitializeRan &amp;&amp; testClass.myIsThisTestIgnored)
        {
          // what to do here? I would like to get rid of the SyncProcessMessage invocation, but...
          // return msg or null -&gt; Exception "The method was called with a Message of an unexpected type."
          // constructing a IMessage in an easy way (specifically CallMessage) seems not possible, and I have no clue how to construct a valid CallMessage that says "ignore test!"
        }
        else
        {
          IMessage message = _nextSink.SyncProcessMessage(msg);
          return message;
        }
  </code></pre>
  
  <p>Again: I want to suppress the testrun for this datarow, or set the testresult somehow to "ignore"/"unknown".</p>
  
  <p>Doing anything with the returned <code>message</code> or <code>msg</code> seems pointless, as the <code>IMessage</code> Interface just exposes the <code>Properties</code> Dictionary which has only some MethodName and stuff in it, nothing interesting it seems. </p>
  
  <p>Casting <code>IMessage</code> to concrete implementations doesn't work: they are all internal to System.Runtime. Though one can cast to ResultMessage and it returns something != null when an exception was raised (so you can take the exception message and adjust error message via new throw).</p>
  
  <p>Any Ideas? And many thanks for reading so far. ;)</p>