سؤال

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

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

قم بإنشاء بعض كائنات الاختبار (TTestCase أو أي شيء آخر) في وقت التشغيل، على سبيل المثال 10 منها، حيث يكون كل منها

  1. تمت تسميته في وقت التشغيل من عدد صحيح تم إنشاؤه عشوائيًا.(أعني بكلمة "الاسم" اسم الاختبار الذي يظهر في شجرة اختبار الاختبار.)
  2. ينجح أو يفشل بناءً على عدد صحيح عشوائي.مرر للتساوي، وافشل للفردي.

من تصميم DUnit، فإنه تبدو كما لو أنه تم تصميمه مع مراعاة المرونة الكافية لجعل مثل هذه الأشياء ممكنة.لست متأكدا من ذلك بالرغم من ذلك.لقد حاولت إنشاء فئة اختبار خاصة بي عن طريق الوراثة من TAbstractTest وITest، ولكن لم يكن من الممكن الوصول إلى بعض الطرق المهمة.لقد حاولت أيضًا الوراثة من TTestCase، لكن هذا الفصل مرتبط ارتباطًا وثيقًا بفكرة تشغيل الأساليب المنشورة (وتتم تسمية الاختبارات على اسم الطرق، لذلك لم أتمكن من الحصول على واحدة تسمى، على سبيل المثال، "go"، لأنه بعد ذلك سيتم تسمية جميع اختباراتي بـ "go"، وأريد تسمية جميع اختباراتي بشكل فردي).

أو بدلاً من ذلك، هل هناك بديل لـ DUnit يمكنه فعل ما أريد؟

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

المحلول

program UnitTest1;

{$IFDEF CONSOLE_TESTRUNNER}
{$APPTYPE CONSOLE}
{$ENDIF}

uses
  Forms, Classes, SysUtils,
  TestFramework,
  GUITestRunner,
  TextTestRunner;

{$R *.RES}

type
  TIntTestCase = class(TTestCase)
  private
    FValue: Integer;
  public
    constructor Create(AValue: Integer); reintroduce;
    function GetName: string; override;
  published
    procedure Run;
  end;

{ TIntTestCase }

constructor TIntTestCase.Create(AValue: Integer);
begin
  inherited Create('Run');
  FValue := AValue;
end;

function TIntTestCase.GetName: string;
begin
  Result := Format('Run_%.3d', [FValue]);
end;

procedure TIntTestCase.Run;
begin
  Check(FValue mod 2 = 0, Format('%d is not an even value', [FValue]));
end;

procedure RegisterTests;
const
  TestCount = 10;
  ValueHigh = 1000;
var
  I: Integer;
begin
  Randomize;
  for I := 0 to TestCount - 1 do
    RegisterTest(TIntTestCase.Create(Random(ValueHigh) + 1));
end;

begin
  Application.Initialize;
  RegisterTests;
  if IsConsole then
    TextTestRunner.RunRegisteredTests
  else
    GUITestRunner.RunRegisteredTests;
end.

نصائح أخرى

أود أن أقول إنك تريد بشكل أساسي الحصول على وظيفة "اختبار فائق" واحدة تقوم بعد ذلك باستدعاء اختبارات أخرى، واحدة لكل ملف بيانات.هذا ما نفعله مع أحد اختبارات DUnit الخاصة بنا.ما عليك سوى تحميل كل ملف متاح بدوره في حلقة، وإجراء الاختبار باستخدام Check's حسب الاقتضاء.

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

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