5

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.

2 Answers 2

10

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.

Sign up to request clarification or add additional context in comments.

2 Comments

This is what I expected the behavior to be. At least in my test class initialization method, a Fail or Inconclusive assertion result only affects the first method in the class, and the other tests are executed as if the Assert statements were not there. I just upgrade Visual Studio to 2019, so maybe this is just an issue with the latest version?
@JoeEdwards perhaps, I've not seen this happen before though at the time I was not using VS2019
4

Throwing an exception will fail tests. Or you can call Assert.Fail().

It is better to Assert.Inconclusive() in the case when test pre-conditions fail. That way your tests will stop (orange) but not be fails (red) - the inconclusive state represents the case where the test pre-condition was not met and you never got up to asserting what you are trying to test.

2 Comments

Yeah it helps when you have a ton of tests and if many go orange instead of red you know its not that they really failed but their setup did. Mainly this is for integration tests.
This answer is very helpful - for my purposes, Assert.Inconclusive() is way more appropriate than having all tests fail.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.