سؤال

أنا أعمل على الحوسبة العلمية المدونة (المكتوبة في C++) ، بالإضافة إلى أداء وحدة اختبارات مكونات أصغر ، أود أن تفعل اختبار الانحدار على بعض العددي الناتج بمقارنة إلى "معروفة جيدا" الجواب من التنقيحات السابقة.هناك عدد قليل من السمات أود:

  • تسمح بمقارنة أرقام محددة التسامح (لكل roundoff خطأ و مرونة التوقعات)
  • القدرة على التمييز بين رجات, الزوجي, الخ, و تجاهل النص إذا لزم الأمر
  • وكذلك تنسيق الإخراج إلى معرفة ما حدث من خطأ و فيها:في مجتمع متعدد عمود الجدول من بيانات تظهر فقط في عمود الإدخال الذي يختلف
  • عودة EXIT_SUCCESS أو EXIT_FAILURE اعتمادا على ما إذا كانت الملفات المباراة

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

[التالية ليست حصرا ذات الصلة ، ولكن قد عامل في قرار ما يجب القيام به.يمكنني استخدام CMake و جزءا لا يتجزأ من CTest وظائف محرك الأقراص وحدة الاختبارات أن استخدام جوجل اختبار الإطار.أتصور أنه لا ينبغي أن يكون من الصعب أن أضيف بعض add_custom_command البيانات في بلدي CMakeLists.txt إلى استدعاء كل ما الانحدار البرامج أحتاج.]

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

المحلول 3

لقد انتهى من كتابة سيناريو بيثون القيام به أكثر أو أقل ما أردت.

#!/usr/bin/env python

import sys
import re
from optparse import OptionParser
from math import fabs

splitPattern = re.compile(r',|\s+|;')

class FailObject(object):
    def __init__(self, options):
        self.options = options
        self.failure = False

    def fail(self, brief, full = ""):
        print ">>>> ", brief
        if options.verbose and full != "":
            print "     ", full
        self.failure = True


    def exit(self):
        if (self.failure):
            print "FAILURE"
            sys.exit(1)
        else:
            print "SUCCESS"
            sys.exit(0)

def numSplit(line):
    list = splitPattern.split(line)
    if list[-1] == "":
        del list[-1]

    numList = [float(a) for a in list]
    return numList

def softEquiv(ref, target, tolerance):
    if (fabs(target - ref) <= fabs(ref) * tolerance):
        return True

    #if the reference number is zero, allow tolerance
    if (ref == 0.0):
        return (fabs(target) <= tolerance)

    #if reference is non-zero and it failed the first test
    return False

def compareStrings(f, options, expLine, actLine, lineNum):
    ### check that they're a bunch of numbers
    try:
        exp = numSplit(expLine)
        act = numSplit(actLine)
    except ValueError, e:
#        print "It looks like line %d is made of strings (exp=%s, act=%s)." \
#                % (lineNum, expLine, actLine)
        if (expLine != actLine and options.checkText):
            f.fail( "Text did not match in line %d" % lineNum )
        return

    ### check the ranges
    if len(exp) != len(act):
        f.fail( "Wrong number of columns in line %d" % lineNum )
        return

    ### soft equiv on each value
    for col in range(0, len(exp)):
        expVal = exp[col]
        actVal = act[col]
        if not softEquiv(expVal, actVal, options.tol):
            f.fail( "Non-equivalence in line %d, column %d" 
                    % (lineNum, col) )
    return

def run(expectedFileName, actualFileName, options):
    # message reporter
    f = FailObject(options)

    expected  = open(expectedFileName)
    actual    = open(actualFileName)
    lineNum   = 0

    while True:
        lineNum += 1
        expLine = expected.readline().rstrip()
        actLine = actual.readline().rstrip()

        ## check that the files haven't ended,
        #  or that they ended at the same time
        if expLine == "":
            if actLine != "":
                f.fail("Tested file ended too late.")
            break
        if actLine == "":
            f.fail("Tested file ended too early.")
            break

        compareStrings(f, options, expLine, actLine, lineNum)

        #print "%3d: %s|%s" % (lineNum, expLine[0:10], actLine[0:10])

    f.exit()

################################################################################
if __name__ == '__main__':
    parser = OptionParser(usage = "%prog [options] ExpectedFile NewFile")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose", default=True,
                      help="Don't print status messages to stdout")

    parser.add_option("--check-text",
                      action="store_true", dest="checkText", default=False,
                      help="Verify that lines of text match exactly")

    parser.add_option("-t", "--tolerance",
                      action="store", type="float", dest="tol", default=1.e-15,
                      help="Relative error when comparing doubles")

    (options, args) = parser.parse_args()

    if len(args) != 2:
        print "Usage: numdiff.py EXPECTED ACTUAL"
        sys.exit(1)

    run(args[0], args[1], options)

نصائح أخرى

يجب أن تذهب PyUnit, التي هي الآن جزء من معيار lib تحت اسم unittest.وهو يدعم كل ما طلب.التسامح التحقق ، على سبيل المثال ، يتم مع assertAlmostEqual().

على ndiff فائدة قد تكون قريبة من ما كنت تبحث عن:انها مثل مهرجان دبي السينمائي الدولي ، لكنه لن مقارنة الملفات النصية من أرقام المطلوب التسامح.

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

هنا لمحة سريعة.كل اختبار هو يحددها ملفات الإدخال و الإخراج المتوقع الملفات.بعد التنفيذ, إخراج ملفات يتم تخزينها في جهاز محمول المعيار الدليل.الخطوة الثانية ثم يقارن هذا المؤشر إلى إشارة مرجعية.التحديث الأخير مكن المستخدم امتداد لذا يمكنك تحديد المقارنة الوظائف المخصصة الخاصة بك البيانات.

وآمل أن يساعد.

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