Domanda

Il modo dunit funziona normalmente è che si scrive alcuni metodi pubblicati, e li dunit viene eseguito come test. Quello che voglio fare è un po 'diverso. Voglio creare test in fase di esecuzione in base ai dati. Sto cercando di testare un particolare modulo che elabora i file di input per crea file di output. Ho una serie di file di input prova con corrispondente noti file di output buoni. L'idea è di creare dinamicamente test, uno per ciascun file di input, che elaborano gli ingressi e le uscite controllare contro noti quelli buoni.

La vera fonte dati qui, tuttavia, non è importante. La difficoltà sta facendo dunit si comportano in un modo basato sui dati. Per il bene di questo problema, si supponga che l'origine dei dati erano solo un generatore di numeri casuali. Ecco un problema concreto esempio che arriva al cuore della difficoltà:

Crea alcuni oggetti di prova (TTestCase o altro) in fase di runtime, dire 10 di loro, dove ognuno

  1. è chiamato in fase di esecuzione da un intero generato in modo casuale. (Per 'name' intendo il nome del test che viene visualizzato nella struttura di test-runner.)
  2. passa o fallisce sulla base di un numero intero casuale. Passare per anche, fallire per dispari.

Dalla progettazione di dunit, è Look come è stato progettato con una flessibilità sufficiente in mente per rendere possibile queste cose. Non sono sicuro che sia però. Ho cercato di creare la mia classe di test ereditando da TAbstractTest e ITest, ma alcuni metodi fondamentali non erano accessibili. Ho anche provato che eredita da TTestCase, ma che classe è strettamente legata all'idea di correre metodi pubblicati (e le prove prendono il nome i metodi, quindi non ho potuto semplicemente avere una sola chiamata, per esempio, 'go', perché poi tutti i miei test sarebbero stati chiamati 'go', e voglio che tutti i miei test per essere nominato individualmente).

In alternativa, c'è qualche alternativa al dunit che potrebbe fare quello che voglio?

È stato utile?

Soluzione

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.

Altri suggerimenti

Direi che, fondamentalmente, desidera avere una singola funzione "super-test" che poi chiama gli altri test, uno per ogni file di dati. Questo è ciò che facciamo con uno dei nostri test dunit. Basta caricare ogni file disponibili, a sua volta in un ciclo, ed eseguire il test con del check a seconda dei casi.

L'alternativa, che usiamo anche nello stesso progetto per testare l'applicazione finale e il suo caricamento e l'analisi dei dati, è quello di usare qualcosa come FinalBuilder al ciclo sull'applicazione (presumibilmente si potrebbe ciclo sul app dunit troppo e utilizzare un parametri) con i vari file di dati diversi. L'applicazione esegue quindi, fa un'analisi, poi si chiude dopo il salvataggio. Un'altra applicazione confronta quindi i dati risultanti con i dati ideali, e segnala un errore, se del caso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top