Я уже писал о контрольных точках - http://18delphi.blogspot.ru/2013/04/blog-post_6244.html
Я достаточно широко применяю этот подход.
Я внедряю тестовый код в реальные проектные файлы.
Позволю привести себе пример:
Тут в класс TscriptParser "внедрено" две "контрольных точки". f_ReadLnLog и f_GetCharLog.
Я такие "контрольные точки" обычно делаю "не руками", а на уровне модели, но всё равно - надеюсь, что идея понятна.
При этом получившиеся "эталоны" я обычно кладу в CVS/SVN и контролирую их разницу. На разных тестовых наборах. Про это я напишу чуть позже.
Пример доступен тут - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/GUITests/Chapter0/
Я достаточно широко применяю этот подход.
Я внедряю тестовый код в реальные проектные файлы.
Позволю привести себе пример:
unit Script.Parser; interface uses Classes, CoreObject ; {$IfNDef NoTesting} {$Define TestParser} {$EndIf NoTesting} type TscriptParser = class(TCoreObject) private f_Stream : TStream; {$IfDef TestParser} f_GetCharLog : TStream; // - сразу думаем о тестировании, в этот поток будем выводить // результат работы функции GetChar f_ReadLnLog : TStream; // - сразу думаем о тестировании, в этот поток будем выводить // результат работы функции ReadLn {$EndIf TestParser} f_EOF : Boolean; f_CurrentLine : String; protected procedure Cleanup; override; function ReadLn: String; protected function GetChar(out aChar: AnsiChar): Boolean; public constructor Create(const aStream : TStream; const aFileName : String); overload; constructor Create(const aFileName : String); overload; function EOF: Boolean; procedure NextToken; end;//TscriptParser implementation uses System.SysUtils ; constructor TscriptParser.Create(const aStream : TStream; const aFileName : String); begin inherited Create; f_EOF := false; f_Stream := aStream; {$IfDef TestParser} f_GetCharLog := TFileStream.Create(aFileName + '.GetChar.log', fmCreate); f_ReadLnLog := TFileStream.Create(aFileName + '.ReadLn.log', fmCreate); {$EndIf TestParser} end; constructor TscriptParser.Create(const aFileName : String); var l_FileName : String; begin l_FileName := ExtractFilePath(ParamStr(0)) + '\' + aFileName; Create(TFileStream.Create(l_FileName, fmOpenRead), l_FileName); end; procedure TscriptParser.Cleanup; begin FreeAndNil(f_Stream); {$IfDef TestParser} FreeAndNil(f_GetCharLog); FreeAndNil(f_ReadLnLog); {$EndIf TestParser} inherited; end; function TscriptParser.GetChar(out aChar: AnsiChar): Boolean; begin if (f_Stream.Read(aChar, SizeOf(aChar)) = SizeOf(aChar)) then begin Result := true; {$IfDef TestParser} f_GetCharLog.Write(aChar, SizeOf(aChar)); {$EndIf TestParser} end else Result := false; end; function TscriptParser.ReadLn: String; {$IfDef TestParser} const cEOL : AnsiString = #13#10; var l_Result : AnsiString; {$EndIf TestParser} var l_Char : AnsiChar; l_Line : String; begin {$IfDef TestParser} try {$EndIf TestParser} l_Line := ''; while GetChar(l_Char) do begin if (l_Char = #13) then begin if GetChar(l_Char) then begin if (l_Char = #10) then begin Result := l_Line; Exit; end//l_Char = #10 else Assert(false, 'Что-то пошло не так, после символа 13 нет символа 10'); end//GetChar(l_Char) else Assert(false, 'Что-то пошло не так, после символа 13 сразу конец файла'); end;//l_Char = #13 l_Line := l_Line + l_Char; end;//while GetChar(l_Char) f_EOF := true; Result := l_Line; {$IfDef TestParser} finally l_Result := Result; f_ReadLnLog.Write(@l_Result[1], Length(l_Result)); f_ReadLnLog.Write(@cEOL[1], Length(cEOL)); end;//try..finally {$EndIf TestParser} end; procedure TscriptParser.NextToken; begin while(f_CurrentLine = '') do begin f_CurrentLine := ReadLn; if (f_CurrentLine = '') then if f_EOF then Exit; end;//while(f_NextToken = '') f_CurrentLine := ''; end; function TscriptParser.EOF: Boolean; begin Result := f_EOF; end; end.
Тут в класс TscriptParser "внедрено" две "контрольных точки". f_ReadLnLog и f_GetCharLog.
Я такие "контрольные точки" обычно делаю "не руками", а на уровне модели, но всё равно - надеюсь, что идея понятна.
При этом получившиеся "эталоны" я обычно кладу в CVS/SVN и контролирую их разницу. На разных тестовых наборах. Про это я напишу чуть позже.
Пример доступен тут - https://sourceforge.net/p/rumtmarc/code-0/HEAD/tree/trunk/Blogger/GUITests/Chapter0/
Комментариев нет:
Отправить комментарий