.netassertionsxunit.netarrange-act-assert

Xunit: Perform all 'Assert'ions in one test method?


Is it possible to tell xUnit.net to perform all e.g. Assert.True() in one test method? Basically in some of our use/testcases all assertions belong logically to one and the same 'scope' of tests and I have e.g. something like this:

    [Fact(DisplayName = "Tr-MissImpl")]
    public void MissingImplementationTest()
    {
        // parse export.xml file
        var exportXml = Libraries.Utilities.XML.GenericClassDeserializer.DeserializeXmlFile<Libraries.MedTrace.ExportXml>(
                ExportXmlFile);

        // compare parsed results with expected ones
        Assert.True(exportXml.ContainsRequirementKeyWithError("PERS_154163", "E0032A"));
        Assert.True(exportXml.ContainsRequirementKeyWithError("PERS_155763", "E0032A"));
        Assert.True(exportXml.ContainsRequirementKeyWithError("PERS_155931", "E0032A"));
        Assert.True(exportXml.ContainsRequirementKeyWithError("PERS_157145", "E0032A"));

        Assert.True(exportXml.ContainsRequirementKeyWithError("s_sw_ers_req_A", "E0032A"));
        Assert.True(exportXml.ContainsRequirementKeyWithError("s_sw_ers_req_C", "E0032A"));
        Assert.True(exportXml.ContainsRequirementKeyWithError("s_sw_ers_req_D", "E0032A"));       
    }

Now if e.g. the first Assert.True(...) fails, the other ones are not executed/checked. I'd rather not break these seven Assertions up into separate methods, since these really do belong together logically (the TC only is 'passed' entirely if all seven are passing all together).


Solution

  • The whole point of AAA is to aim to simplify each piece as much as possible and keep it focused, so readers can understand the tests quickly and isolate the cause of failures easily.

    You have 7 different Facts here, which together comprise a Theory. So you should create a [Theory] with 7 sets of [InlineData] representing the expectations. See http://blog.benhall.me.uk/2008/01/introduction-to-xunitnet-extensions.html for an example.

    If the re-executing of the Arrange/Act is an issue, then you should be making that the 'fixture' (in xUnit Test Patterns parlance) by doing that in the constructor of your test class.

    public class WithGenericClassDeserializer
    {
        var exportXml;
    
        public WithGenericClassDeserializer()
        {
            // Or move this into the GivenExportXmlFile_ExpectedValueAtKeyShouldMatch
            exportXml = Libraries.Utilities.XML.GenericClassDeserializer.DeserializeXmlFile<Libraries.MedTrace.ExportXml>( ExportXmlFile );
        }
    
        [Theory( DisplayName = "Tr-MissImpl" )]
        [InlineData( "PERS_154163", "E0032A" )]
        [InlineData( "PERS_155763", "E0032A" )]
        [InlineData( "PERS_155931", "E0032A" )]
        [InlineData( "PERS_157145", "E0032A" )]
        [InlineData( "s_sw_ers_req_A", "E0032A" )]
        [InlineData( "s_sw_ers_req_C", "E0032A" )]
        [InlineData( "s_sw_ers_req_D", "E0032A" )]
        public void GivenExportXmlFile_ExpectedValueAtKeyShouldMatch( string key, string value )
        {
            Assert.True( exportXml.ContainsRequirementKeyWithError( key, value ) );
        }
    }