Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to intentionally fail all C# unit tests

QUESTION:

I'm trying to figure out if there's a way to fail all C# unit tests whenever a particular condition is met.

BACKGROUND:

I set up a unit test for an object which encodes and decodes its internal data. Here's a fairly contrived example:

[TestClass]
public class FooTests
{
    private Foo TestFoo { get; set; }

    [TestMethod]
    public void DataEncodingIsWorking()
    {
        // TestFoo.EncodeData() ...
    }

    [TestMethod]
    public void DataDecodingIsWorking()
    {
        // TestFoo.DecodeData() ...
    }

    public FooTests(dynamic[] data) {
        TestFoo = new Foo(data);
    }
}

public class Foo {

    public void EncodeData() {
        // encodes Foo's data
    }

    public void DecodeData() {
        // decodes Foo's encoded data
    }

    public Foo(dynamic[] data) {
        // feeds data to Foo
    }
}

Rather than creating a new instance of TestFoo in every [TestMethod] (somewhat repetitive), I created a global TestFoo object in FooTests. If TestFoo fails to instantiate, I'm looking to fail all FooTests unit tests (as encoding/decoding will not work if the object fails to instantiate).

This isn't really a question of best practices, but I'm also curious as to whether or not this approach is terrible. I suppose another approach would be to set up an additional unit test to see whether or not TestFoo instantiates correctly.

like image 730
alex Avatar asked Dec 18 '22 14:12

alex


1 Answers

How to intentionally fail all C# unit tests


TL;DR: In your ClassInit(), instantiate whatever objects you need for the tests and add appropriate Assert statements. Should any condition fail, all tests will fail.


You can add a method that will be automatically called before any of the test methods are run and decorate it with the ClassInitialize attribute.

MSDN:

Identifies a method that contains code that must be used before any of the tests in the test class have run and to allocate resources to be used by the test class. This class cannot be inherited.

...and:

When run in a load test, the method marked with this attribute will run once, and any initialization operations it performs will apply to the entire test. If you need to do initialization operations once for every virtual user iteration in the test, use the TestInitializeAttribute.

In the example below, we instantiate a new Foo object and Assert it is not null. We can of course test for other situations as desired.

[ClassInitialize]
public void ClassInit(TestContext context)
{
    TestFoo = new Foo(dynamicDataFromContext);
    Assert.IsNotNull(TestFoo);
}

If you are interested in a data-driven test, then you may want to check-out How To: Create a Data-Driven Unit Test

I think CRice makes a fine point on this page about Assert.Inconclusive() so you could optionally incorporate that too.

like image 59
MickyD Avatar answered Dec 24 '22 03:12

MickyD