TESTLERE BAŞLAYALIM - Deneylem Türkçe Projesi (DTP)


XP'de önce test, sonra program yaklaşımı önemli. Bu nedenle biz de önce test yordamımızı oluşturalım.
procedure TfDtpTests.TestDegistir;
begin
  assert(fDtp.Degistir('') = '');
end;

Test projemizi çalıştırdığımızda, yeşil çubuğumuz da kendini gösterecek hemen.



Peki, fonksiyonumuza boş karakter yerine bir dizgi (string) yollarsak ne olacak?

procedure TfDtpTests.TestDegistir;
begin
  assert(fDtp.Degistir('a') = 'a');
end;
Test projemizi tekrar çalıştıralım. Bu kez çubuğun rengi ne? Kırmızı.



Çünkü Degistir fonksiyonu, parametre olarak ne verirsek verelim, boş bir dizgi döndürecek şekilde tasarlandı. Bu nedenle 'a' beklerken, boş bir dizgi geldiği için assert başarısız oldu.
Durumu kolayca düzeltebiliriz. Hemen Degistir fonksiyonunu değistirelim:
function TfDtp.Degistir(s:string):string;
begin
  Result := s;
end;
Bu durumda ister boş, ister dolu bir dizgi göndersek te aynı dizgi geri döneceği için rengimiz de yeşile dönecek demektir.
Yordamımıza yeni testler ekleyelim:
procedure TfDtpTests.TestDegistir;
begin
  assert(fDtp.Degistir('') = '');
  assert(fDtp.Degistir('a') = 'a');
  assert(fDtp.Degistir('Test') = 'Test');
  assert(fDtp.Degistir('işgüzarlık') = 'işgüzarlık');
  assert(fDtp.Degistir('dağıtım') = 'dağıtım');
end;
İlk dört test, doğru sonuç üretecektir. Ancak son test, henüz değişim işlemleri uygulanmadığı için üreteceği sonuç, yanlıştır.
Aşağıdaki şekilde, test sonuçlarını olduğu kadar, yanlış sonuç üreten kod satırını da görmek mümkün. Projemiz ilerledikçe test satırı sayısı onlarla, yüzlerle ifade edilmeye başlayacak, hangisinin hata ürettiğini farketmek te giderek zorlaşacaktır. Ancak, şekilde görüldüğü gibi hangi satırla ilgilenmemiz gerektiği bilgisi, bize hazır olarak veriliyor.



Assertion failure (E:\dtp\uDtpTests.pas, line 57) açıklaması bize hatalı assert satır numarasını 57 olarak gösteriyor.

Şimdi biraz hızlanacağız.
Aslında bu durum XP'nin küçük, basit adımlarla ilerleme önerisine uymuyor. Fakat, daha sonra, geri dönüşlerle bu açığımızı da kapatacağız.
İlk önce Oku fonksiyonunu uDtp.pas dosyasına ekleyelim.
///turkcele.txt dosyasındaki bilgiler kullanılacak
procedure TfDtp.Oku;
var F:TextFile;
  S:string;
  i:integer;
begin
  say:=0;
  if FileExists('TURKCELE.TXT') then
  begin
    i:=0;
    imax:=50;
    SetLength(kod,imax);
    SetLength(kar,imax);
    AssignFile(F,'TURKCELE.TXT');
    Reset(F);
    while True do
    begin
      ReadLn(F,S);
      if Length(S)>2 then
      begin
        if (Copy(S,1,2)=' :') then
          S:=TrimRight(S)
        else
          S:=Trim(S);
      end;
      if (S='') then break;
      if Length(S)>2 then
      begin
        if Copy(S,2,1)=':' then
        begin
          kar[i]:=Copy(S,1,1);
          kod[i]:=Trim(Copy(S,3,Length(S)-2));
          i:=i+1;
          if i>=imax then///Dosya satir sayisi dizi boyutunu asarsa
          begin
            imax:=imax+10;///dizinin yeni boyutunu belirle
            SetLength(kod,imax);
            SetLength(kar,imax);
          end;
        end;
      end;
    end;
    CloseFile(F);
    say:=i;//toplam donusum sayı
    ///Sirala;
  end
  else
  begin
    ShowMessage('TURKCELE.TXT DOSYASI BULUNAMADI');
  end;
  Okundu:=True;
end;
Sonra da Degistir fonksiyonumuzu yeniden düzenleyelim.
function TfDtp.Degistir(s: string): string;
var j:integer;
  s1:string;
begin
  ///Turkcele.txt'in okunmasini garantile
  if not Okundu then Oku;
  Result:=s;
  for j:=0 to say-1 do begin
    Result:=StringReplace(Result,kod[j],kar[j],[rfReplaceAll]);
  end;
end;
uDtpTests.pas dosyasında herhangi bir değişiklik yapmaya gerek yok.
Yeni düzenlemenin ardından dtpTests projemizi yeniden çalıştıralım.



Dikkat ettiyseniz, bu kez karşımıza çıkan hata Assertion ile ilgili değil.
Access violation hatası, genellikle tanımlanmamış, adresi belli olmayan nesnelere çağrı yapıldığı zaman ortaya çıkar.
Buradaki sorun, uDtpTests.pas'ın eklenti (include) listesinde uDtp.pas dosyasının bulunmasına rağmen, test projesi çalıştırıldığı zaman, fDtp formunun henüz yaratılmamış olmasıdır. Degistir fonksiyonunun tetiklediği Oku fonksiyonu tarafından kullanılan public değişkenler de bu nedenle tanımsız durumdadır.
Bu hatayı gidermenin iki yolu var.
Birinci yolda, Degistir fonksiyonunun kullanacağı genel değişkenleri TfDtp nesnesinin dışında global olarak tanımlarız. Böylece, form oluşmasa da fonksiyonumuz çalışacak, değişkenlerimiz test projesinden de erişilebilir durumda olacaktır. Bunun için global değişkenlerimizi public var alanında tanımlarız.
var
  fDtp: TfDtp;
  ///Aşağıdaki değişkenlere diğer birim dosyalardan da
  ///sorunsuz erişilebilir.
  imax,say:integer;
  Okundu:boolean;
  kod: array of string;
  kar: array of string;

implementation

{$R *.dfm}

Diğer yöntemde ise, değişkenlerimizi TfDtp class public alanında tanımlar, ayrıca test fonksiyonları çalışmadan önce fDtp formunun yaratılmasını da bir fonksiyon aracılığıyla garanti altına alırız.
type
  TfDtp = class(TForm)
    Memo1: TMemo;
    Memo2: TMemo;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    procedure Oku;
    { Private declarations }
  public
    { Public declarations }
    kod: array of string;
    kar: array of string;
    imax,say:integer;
    Okundu:boolean;
    function Degistir(s: string): string;
  end;
uDtpTests.pas biriminde kullanacağımız yeni fonksiyon da şu şekildedir:
///fDtp public değişkenlerini kullanabilmek için
///fDtp'nin önceden tanımlanmış olması gerekiyor
function getfDtp:TfDtp;
begin
  if Assigned(fDtp) then
  begin
    Result := fDtp;
  end else
  begin
    fDtp := TfDtp.Create(Application);
    Result := fDtp;
  end;
end;
Doğru olan, ikinci yöntemdir. Biz de bunu kullanacağız.
uDtpTests biriminden daha önce fDtp.Degistir şeklinde yaptığımız çağrıları, bundan böyle getfDtp.Degistir olarak düzelteceğiz.



Şimdi bir sıçrama daha yapacağız.
Halen, dtp.exe hiçbirşey yapmıyor.
Onu da basitçe fonksiyonel hale getirelim.
fDtp formumuzun üzerine iki tane TMemo ve bir de TButton nesnesi yerleştirelim.



Ayrıca TButton'un OnClick olayını da aşağıdaki gibi tanımlayalım:
procedure TfDtp.Button1Click(Sender: TObject);
var j:integer;
  s:string;
begin
Memo2.Lines.Clear;
for j:=0 to Memo1.Lines.Count do begin
  s:=Degistir(Memo1.Lines.Strings[j]);
  Memo2.Lines.Append(s);
end;
end;
Geldiğimiz son durumda, Memo1'e kopyaladığımız bozuk metin, butona bastığımızda düzeltilmiş olarak Memo2'ye kopyalanıyor.


dtpTests.exe'yi çalıştırdığımızda da testler yeşil!


Gelecek bölümde, görsel nesneleri nasıl test edebileceğimizi araştıracak ve mevcut fonksiyonlarımızı da yeniden elden geçireceğiz.

Önceki Bölüm  -  Sonraki Bölüm
Başa Dön
1. BÖLÜM   Download dtp001.zip
2. BÖLÜM    Download dtpsrc02.zip    Download dtpdoc02.zip
3. BÖLÜM    Download dtpsrc03.zip    Download dtpdoc03.zip