الوحدة:تنفيذ جميع "التأكيدات" في طريقة اختبار واحدة؟

StackOverflow https://stackoverflow.com/questions/1846345

سؤال

هل من الممكن إخبار xUnit.net بتنفيذ كل شيء على سبيل المثال؟ Assert.True() في طريقة اختبار واحدة؟بشكل أساسي في بعض حالات الاستخدام/الاختبار لدينا، تنتمي جميع التأكيدات منطقيًا إلى نفس "نطاق" الاختبارات ولدي على سبيل المثال:شيء من هذا القبيل:

    [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"));       
    }

الآن إذا على سبيل المثال.الأول Assert.True(...) إذا فشل، فلن يتم تنفيذ/التحقق من العناصر الأخرى.أفضل عدم تقسيم هذه التأكيدات السبعة إلى طرق منفصلة، ​​نظرًا لأن هذه التأكيدات تنتمي معًا بشكل منطقي (يتم "تمرير" TC فقط إذا تم تمرير السبعة جميعًا معًا).

هل كانت مفيدة؟

المحلول

الهدف الأساسي من AAA هو تبسيط كل قطعة قدر الإمكان والحفاظ على تركيزها، حتى يتمكن القراء من فهم الاختبارات بسرعة وعزل سبب الفشل بسهولة.

لديك 7 مختلفة Factهنا، والتي تشكل معًا أ Theory.لذلك يجب عليك إنشاء [Theory] مع 7 مجموعات من [InlineData] تمثل التوقعات.يرى http://blog.benhall.me.uk/2008/01/introduction-to-xunitnet-extensions.html على سبيل المثال.

إذا كانت إعادة تنفيذ الترتيب/القانون تمثل مشكلة، فيجب عليك إجراء ذلك "التركيب" (في لغة نماذج اختبار xUnit) عن طريق القيام بذلك في مُنشئ فئة الاختبار الخاصة بك.

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 ) );
    }
}

نصائح أخرى

نعم يمكنك ذلك ولكن عليك إضافة رمز إضافي إلى الاختبار الخاص بك.ستؤدي كل عبارة Assert في xUnit إلى طرح استثناء في حالة فشل التأكيد.لذلك في حالة Assert.True فإنه يطرح TrueException.إذن ما يمكنك فعله هو شيء على غرار ما يلي:

    [Fact]
    public void MultipleAssertTest()
    {
        bool passesValidation = true;

        passesValidation = PassesAssert(true == true);
        passesValidation = PassesAssert(false == true);
        passesValidation = PassesAssert(5 == 1);

        Assert.True(passesValidation);

    }

    private bool PassesAssert(bool expression)
    {
        try
        {
            Assert.True(expression);
            return true;
        }
        catch
        {
            return false;
        }
    }

سيسمح لك هذا بتشغيل جميع التأكيدات الخاصة بك وإجراء الاختبار بالكامل.ومع ذلك، فهو ليس مفيدًا جدًا لأنك لا تعرف ما فشل التأكيد.ما هو الأفضل هو أدناه حتى تتمكن بالفعل من الحصول على نتائج من الاختبار الخاص بك حتى تعرف العناصر التي تفشل.

       private StringBuilder resultMsg;
    [Fact]
    public void MultipleAssertTest()
    {
        bool passesValidation = true;
        resultMsg = new StringBuilder();

        passesValidation = PassesAssert(true == true, "True True test");
        passesValidation = PassesAssert(false == true, "False True test");
        passesValidation = PassesAssert(5 == 1, "5==1 Test");

        Assert.True(passesValidation, resultMsg.ToString());

    }

    private bool PassesAssert(bool expression, string message)
    {
        try
        {
            Assert.True(expression, message);
            return true;
        }
        catch (AssertException ex)
        {
            resultMsg.Append(ex.UserMessage);
            resultMsg.Append(Environment.NewLine);
            return false;
        }
    }

بالطبع يتطلب هذا المزيد من العمل ولكنه يسمح لك بحظر جميع التأكيدات الخاصة بك معًا.يمكنك التفاف أي من أساليب تأكيد الاختبار الخاصة بك بهذه الطريقة.لذلك يمكنك القول أنك تقوم بتوسيع xUnit للحصول على عملية تأكيد غير فاشلة.

أتمنى أن يساعدك هذا.

يحرر:وفقًا للتعليقات، لكي يعمل هذا، ستحتاج إلى استخدام عامل التشغيل & لأن الاستدعاءات اللاحقة ستحل محل القيمة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top