الوحدة:تشغيل تأكيدات متعددة في اختبار واحد

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

  •  03-07-2019
  •  | 
  •  

سؤال

لقد طُلب مني كتابة تطبيق اختبار يحتاج إلى اختبار إجراء مخزن جديد على صفوف متعددة في قاعدة بيانات، وفي الأساس أريد أن أفعل شيئًا مثل هذا:


[Test]
public void TestSelect()
{
    foreach(id in ids)
    {
        DataTable old = Database.call("old_stored_proc",id);
        DataTable new_ = Database.call("new_stored_proc",id);

        Assert.AreEqual(old.Rows[0]["column"],ne_.Rows[0]["column"]);
    }
}

عندما أقوم بإجراء هذا الاختبار، إذا لم يتطابق صف واحد مع الآخر، فسيفشل الاختبار بأكمله؛بدلاً من ذلك، أود حساب عدد مرات تمرير التأكيد وعدد مرات فشله.هل هناك طريقة للقيام بذلك مع NUnit؟

أدرك أن NUnit قد تكون مبالغة وأن هذه مهمة بسيطة بدونها...أردت فقط أن أتعلمها.;)

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

المحلول

1) إذا كان لمعرف ثابتة وليس البحث عنها في وقت التشغيل اختبار، وخلق لاعبا اساسيا وحدة اختبار منفصل لكل معرف. وبهذه الطريقة سوف تعرف أي معرف وفشلها في الواقع. انظر هنا لكتابة حتى على مشاكل مع بيانات اختبارات مدفوعة:
http://googletesting.blogspot.com/2008/09/tott داتا يحركها traps.html

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

و3) أنا لا أعرف مدى صعوبة أن يكون للقيام في NUnit، ولكن في PyUnit، عندما نحتاج إلى إجراء اختبارات على البيانات ديناميكيا، ونحن خلق ديناميكية الاختبارات ومواعيد المباريات وإرفاقها إلى فئة TestCase حتى يتسنى لنا لدينا تجربة فاشلة لكل قطعة من البيانات التي لا يمر. على الرغم من أنني أتصور أن هذا سيكون أكثر صعوبة بكثير دون قدرات ديناميكية بايثون.

نصائح أخرى

ويبدو وكأنك مجرد التأكيد على الشيء الخطأ. إذا كنت تريد أن تحقق من كل القيم وثم تأكيد أنه لا توجد أخطاء (أو إظهار عدد من الأخطاء) ثم حاول هذا:

[Test]
public void TestSelect()
{
    int errors = 0;
    foreach(id in ids)
    {
        DataTable old = Database.call("old_stored_proc",id);
        DataTable new_ = Database.call("new_stored_proc",id);

        if (old.Rows[0]["column"] != new_.Rows[0]["column"])
        {
            errors++;
        }            
    }

    Assert.AreEqual(0, errors, "There were " + errors + " errors.");
}

أعلم أن السؤال يتعلق تحديدًا بـ NUnit، ولكن من المثير للاهتمام، جاليو/MbUnit لديه ميزة تسمح بتشغيل العديد من التأكيدات والتقاطها في وقت واحد.

[Test]
public void MultipleTest()
{
    Assert.Multiple(() =>
    {
       Assert.IsTrue(blabla);
       Assert.AreEqual(pik, pok);
       // etc.
    }
}

ال Assert.Multiple يصطاد الجميع التأكيدات الفاشلة وسيتم الإبلاغ عنها في نهاية الاختبار.

وأود أن نحصي عدد الصفوف التي لا تطابق وبعد ذلك كتابة التأكيد الذي سوف مقارنة هذا الرقم مع 0، وسيعود عدد من السلاسل غير مطابقة في الرسالة.

ويمكن أيضا استخدام Assert.Greater لذلك.

وP.S. من حيث المبدأ يجب أن تحاول أن تفعل تأكيد واحد لكل اختبار وحدة. هذا هو جوهر ذلك.

وحسنا هل يمكن أن يعلن عداد ثم تأكيد قيمة العداد لتحديد نجاح / فشل

وأيضا، هل يمكن أن تفعل الجزء الأكبر من العمل في إعداد الاختبار، وبعد ذلك فقط إنشاء اختبارات متعددة.

وأنا لست واضحة لماذا أنت في حاجة إلى كل stmts تأكيد في نفس الاختبار.

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

وكان لي مؤخرا نفس القضية. I الجمع بين فكرة عد أخطاء مع ذكر يان تريفين من Assert.Multiple إلى أسلوب التمديد لIEnumberable التي تسمح لي أن تفعل أشياء مثل:

[Test]
public void TestEvenNumbers()
{
    int[] numbers = new int[] { 2, 4, 12, 22, 13, 42 };
    numbers.AssertAll((num) => Assert.That((num % 2) == 0, "{0} is an odd number", num));
}

والذي ينتج في إخراج NUnit:

TestEvenNumbers:
  5 of 6 tests passed; 0 inconclusive
FAILED: 13:   13 is an odd number
  Expected: True
  But was:  False

  Expected: 6
  But was:  5

وسيكون الحل لمشكلة OP سيكون:

[Test]
public void TestSelect()
{
    ids.AssertAll(CheckStoredProcedures);
}

private void CheckStoredProcedures(Id id)
{
    DataTable old = Database.call("old_stored_proc",id);
    DataTable new_ = Database.call("new_stored_proc",id);

    Assert.AreEqual(old.Rows[0]["column"], new_.Rows[0]["column"]);
}

وهنا هو الأسلوب تمديد (لاحظ أنني استخدمت "الكل" بدلا من "متعددة" من أجل التناسق مع المصطلحات ينق):

using System;
using System.Text;
using System.Collections.Generic;
using NUnit.Framework;

public static class NUnitExtensions
{
    public static void AssertAll<T>(this IEnumerable<T> objects, Action<T> test)
    {
        int total = 0;
        int passed = 0;
        int failed = 0;
        int inconclusive = 0;
        var sb = new StringBuilder();
        foreach (var obj in objects)
        {
            total++;
            try
            {
                test(obj);
                passed++;
            }
            catch (InconclusiveException assertion)
            {
                inconclusive++;
                string message = string.Format("INCONCLUSIVE: {0}: {1}", obj.ToString(), assertion.Message);
                Console.WriteLine(message);
                sb.AppendLine(message);
            }
            catch (AssertionException assertion)
            {
                failed++;
                string message = string.Format("FAILED: {0}: {1}", obj.ToString(), assertion.Message);
                Console.WriteLine(message);
                sb.AppendLine(message);
            }
        }

        if (passed != total)
        {
            string details = sb.ToString();
            string message = string.Format("{0} of {1} tests passed; {2} inconclusive\n{3}", passed, total, inconclusive, details);
            if (failed == 0)
            {
                Assert.Inconclusive(message);
            }
            else
            {
                Assert.AreEqual(total, passed, message);
            }
        }
    }
}

ويمكنك استخدام [TestCase()] السمة إذا قائمة بسيطة الثابت ترميز من معرفات .

[Test]
[TestCase(1234)]
[TestCase(5678)]
[TestCase(7654)]
public void TestSelect(int id)
{
    DataTable old = Database.call("old_stored_proc", id);
    DataTable new_ = Database.call("new_stored_proc", id);

    Assert.AreEqual(old.Rows[0]["column"], new_.Rows[0]["column"]);
}

وهذا سيولد ثلاثة اختبارات منفصلة لكل ID ومهما عداء اختبار nunit استخدام سيعرض نجاح / فشل التهم الموجهة إليه.

وإذا كان في حاجة إلى إنشاء قائمة حيوية من معرفات ثم نوصي باستخدام [TestCaseSource()] السمة .

scroll top