سؤال

لقد حصلت على عدة وحدات من هذا النمط:

[TestMethod ()]
[ExpectedException (typeof (ArgumentNullException))]
public void DoStuffTest_Exception ()
{
    var foo = new Foo ();
    Foo.DoStuff (null);
}

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

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

public static void ExpectException<_T> (Action action) where _T: Exception
{
    try { action(); }
    catch (_T) { return; }
    Assert.Fail ("Expected " + _T);
}

سيكون لهذا فائدة جانبية لطيفة حيث يمكنني إضافة جميع اختبارات الاستثناء إلى اختبارات عدم الرمي.

هل هذا تصميم صالح أم أنني فاتني شيء ما؟

يحرر: آج...يبدو أن طريقة AcceptException المذكورة أعلاه تترك لي كتلة واحدة غير مكشوفة أيضًا.

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

المحلول

ما تقترحه صحيح.بصرف النظر عن مشكلة تغطية الكود، أعتقد أنه أفضل من استخدام ExpectedException السمة لأنها توضح بوضوح أي سطر من الاختبار من المتوقع أن يرمي الاستثناء.استخدام ExpectedException يعني أن أي يمكن لسطر التعليمات البرمجية في الاختبار طرح نوع الاستثناء المتوقع وسيظل الاختبار ناجحًا.إذا كان الخطأ ناتجًا عن استدعاء آخر لم يكن من المتوقع تنفيذه، فيمكن أن يخفي ذلك حقيقة أن الاختبار يجب أن يفشل لأن الخط الذي يجب أن يتم طرحه ليس كذلك.

ما قد يكون تعديلًا مفيدًا لما اقترحته هو إرجاع الاستثناء الذي تم اكتشافه:

public static _T ExpectException<_T> (Action action) where _T: Exception
{
    try { action(); }
    catch (_T ex) { return ex; }
    Assert.Fail ("Expected " + typeof(_T));
    return null;
}

سيؤدي ذلك إلى تمكين رمز الاختبار من تأكيد الاستثناء بشكل أكبر إذا رغب في ذلك (على سبيل المثال.للتحقق من استخدام رسالة معينة).

NUnit (على الرغم من أنه لا يبدو أنك تستخدمه لأن لديك TestMethod attribute) يحتوي على بنية مضمنة مشابهة لما اقترحته:

Assert.Throws<ArgumentNullException>(() => Foo.DoStuff(null))

نصائح أخرى

وadrianbanks وExpectException لا يعمل كما هو متوقع إذا المعلمة عمل رميات استثناء آخر الاستثناء المتوقع:

[TestMethod]
public void my_test()
{
    ExpectException<InvalidOperationException>(delegate()
    {
        throw new ArgumentException("hello");
    });
}

وعندما تنفيذ TestMethod "my_test" أنا فقط حصلت على رسالة تقول أن طريقة الاختبار أثار وSystem.ArgumentException: مرحبا. في هذه الحالة يجب أن يقول "InvalidOperationException المتوقع". أقترح إصدار جديد لأسلوب ExpectException:

public static void VerifierException<T>(Action action) where T : Exception
{
    try
    {
        action();
    }
    catch (Exception ex)
    {
        Assert.IsInstanceOfType(ex, typeof(T));
        return;
    }

    Assert.Fail("Aucune exception n'a été déclenchée alors qu'une exception du type " + typeof(T).FullName + " était attendue");
}

وأنا أعلم أن هذا هو موضوع قديم، لكنني واجهت نفس المشكلة.

وأخيرا سألت نفسي: لماذا أحتاج لمعرفة تغطية الاختبارات؟ <القوي> أنا لا - يمكنك! لذلك دعونا يستبعدها، وبالتالي فإن تغطية أنظف

.

في مشروع اختباري واضاف لقد ملف CodeCoverage.runsettings وهذا هو مضمون:

<?xml version="1.0" encoding="utf-8" ?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
        <Configuration>
          <CodeCoverage>
            <ModulePaths>
              <Exclude>
                <ModulePath>.*tests.dll</ModulePath>
                <ModulePath>.*Tests.dll</ModulePath>
                <!-- Add more ModulePath nodes here. -->
              </Exclude>
            </ModulePaths>
          </CodeCoverage>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

وبعد تحديد هذا <م> إعدادات الاختبار ملف كود تغطية بلدي 100٪

وهذه الطريقة ليست هناك حاجة إلى "الإختراق 'وحدة اختبار نظام تغطية رمز، فقط من أجل تحقيق 100٪: -)

نعم هذه هي جميلة الأسعار القياسية - الكثير من تجاربنا أن تفعل الشيء نفسه. في نفس الوقت، عليك أن أتساءل عما إذا كنت لا وضع مرتفعة جدا قيمة على مدونة التغطية إذا تزن تلك نصف فروع في الكثير من أجل أن يكون يستحق كل هذا الجهد.

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