JavaScriptte Fonksiyonlar

Kod bloklarını tekrar tekrar yazmak yerine onu bir kere tanımlayarak fonksiyon şeklinde kullanabiliriz.Fonksiyonların genelde parametreleri ver dönüş değerleri bulunur.Eğer fonksiyon bir nesnenin propertysi olarak tanımlanmışsa method adı verilir. Fonksiyon tanımlamaları içiçe olabilir. Ve tanımlandıkları yerdeki değişkenlere erişebilirler.

Fonksiyon Tanımlama

function anahtar kelimesiyle beraber tanımlanır. Ve bu anahtar kelimeden sonra aşağıdaki komponentler olmalıdır:

  • Fonksiyon adını tanımlayan (identifier).Fonksiyonu bu isimle çağıracağız.
  • Fonksiyonun isminden hemen sonra parametrelerin geldiği kısmı belirleyen parantezler “()”.
  • Ve son olarak fonksiyonun gövdesini oluşturan köşeli parantezler “{}”.

Örnek fonksiyonlar:

// 2 Nokta arası uzaklık.

function distance(x1, y1, x2, y2) {
var dx = x2 – x1;
var dy = y2 – y1;
return Math.sqrt(dx*dx + dy*dy);
}

// Rekürsif Faktöriyel Hesabı.

function factorial(x) {
if (x <= 1) return 1;
return x * factorial(x-1);
}

Fonksiyon çağrımları ise metod olup olmadığına göre farklı yapılır. Eğer metod değilse fonksiyonu direk adıyla çağırırız.Ancak method ise nesneadi.fonksiyon() şeklinde çağırırız.

Closures

Çoğu modern programlama dilinde olduğu gibi JavaScript’te lexical scoping kullanır.Bunun anlamı fonksiyonlar tanımlandığı değişken uzayındaki değişkenlere etki eder. Çağrıldığı yerdeki değişkenlere etki edemez. Bilgisayar bilimleri literatüründe , fonksiyona ait değişkenlerin çözümlendiği ,fonksiyon nesnesi ve uzayı (bind edilen değişkenler kümesi) closure olarak adlandırılır.

Teknik olarak tüm JavaScript fonksiyonları closure’dur. Hepsi nesnedir ve kendilerine ait değişken uzayları(scope) vardır.

var scope = “global scope”; // A global variable
function checkscope() {
var scope = “local scope”; // A local variable
function f() { return scope; } // Return the value in scope here
return f();
}
checkscope() // => “local scope”

checkscope() fonksiyonu yerel bir scope değişkeni üretir. Ve fonksiyon kullanıldığında tanımlandığı yerdeki değişkenleri kullanacağından dönüş değeri “localscope” olur.

Kod aşağıdaki şekilde bile olsa yine de “localscope” döndürür.Global değişkeni kullanmaz.

var scope = “global scope”; // A global variable
function checkscope() {
var scope = “local scope”; // A local variable
function f() { return scope; } // Return the value in scope here
return f;
}
checkscope()() //

 

Loading

Facebooktwitterredditpinterestlinkedinmail

JavaScriptte Nesneler

JavaScript’in temel datatiplerinden birisi objecttir. Nesne kompozit bir yapıdır ve içerisinde birden çok değer tutabilir. Bir çok sırasız özellik(property) den oluşur. Her özelliğin bir adı ve değeri vardır.Property isimleri stringdir. Yani biz stringlerin değerleri map ettiğini söyleyebiliriz. String to value mapping  veriyapısında birçok isimde anılmaktadır: “hash”,”hasttable”,”dictionary”,”associative(ilişkisel) array”. JavaScriptte nesneler başka bir nesnenin özeliiklerini miras alabilir.Bu olaya prototip(prototype) denir.Aynı şekilde nesnenin metodları da miras alınmışssa prototopik miras olarak adlandırılır ve JavaScriptin anahtar öğelerinden birisidir.

JavaScriptte string veya sayı olmayan hemen hemen her şey nesnedir; true,false,null,undefined gibi. Ancak stringler sayılar ve boolean değerler nesne değildir bunlar  “immutable objects(değişmez nesneler )” olarak adlandırılır. Normalde oluşturduğumuz nesneler üzerinde oynamaya yapabiliriz,özellik ekleyip çıkarabiliriz ancak string gibi değişmez nesneler için özellik ekleme çıkarma sözkonusu değildir.Sadece JavaScriptin string için bize tanımladığı özellikleri kullanabiliriz.

Property

Adı ve değeri vardır. Property adı herhangi bir string olabilir.(Boş string de dahil olmak üzere) Ancak bir nesnenin aynı ada sahip iki property’si olamaz. Property değeri JavaScriptte tanımlı herhangi bir değer olabilir.Ek olarak ada ve değere sahip her property, property attributes olarak adlandırılan değerler ile ilişkilidir.

  • writable  attribute, property’nin değerinin setlenip setlenemeyeceğini belirler.
  • enumerable atttribute, property for/in döngüsü içinde kullanılabilir mi onu belirler.
  • configurable attribute, property editlenebilir mi(silme güncelleme ekleme vs) onu belirler.

Nesne Oluşturma

“new” operatörü yeni nesneyi oluşturur ve initialize eder. “new” anahtar kelimesinden sonraki kısım fonksyion çağrımı şeklinde olmalıdır. Örneğin:

  • var o = new Object();
  • var a =new Array();
  • var d = new Date();
  • var r =new RegExp(“js”);

Propertyleri Setleme

Değerin propertysine (.) veya [] içine adını yazarak erişebiliriz.Örneğin:

  • var author = book.author; // Kitabın yazarına setler.
  • var name = author.surname // Yazarın soyadı.
  • var title = book[“main title”] // Kitabın başlığı.

Yeni bir property oluşturmak içinde aynı syntax kullanılır tek fark setleme sol taraftan yapılır.

  • book.edition=6; // book için edition propertysi oluşturduk.
  • book[“main title”]=”JavaScript”; // Main Title Propertysini setledik.

Inheritance[Miras]

JavaScriptte nesneler kendi property kümeleri olarak adlandırılabilir. Aynı şekilde bu nesneler başka prototipleri de kendi üzerlerine miras alabilir. Burada bilinmesi gereken kısım miras alınan prototip miras alan nesnenin yaptığı değişimlerden etkilenmez. Örneğin;

  • var unitcircle = { r:1 }; // Miras alınacak nesne.
  • var c = inherit(unitcircle); // c nesnesi r propertysini miras alıyor.
  • c.x = 1; c.y = 1; // c kendine ait 2 property tanımlıyor.
  • c.r = 2; // c miras aldığı property üzerine yazıyor.
  • unitcircle.r; // => 1:  Prototip nesnesinde değişme olmadı değer hala 1.

 

Propertyleri silmek için delete operatörü kullanılır.

  • delete book.author; // author propertysini sildik.
  • delete book[“main title”]; // Aynı şekilde main title propertysini sildik.

Property Getter ve Setter’ları

Daha önce bahsettiğim gibi nesnenin propertysinin adı değeri ve özellik kümesi bulunur. Property değerleri getter ve setter metodlarıyla setlenebilir. Bu ECMAScript 5 ile tanımlanmıştır. Getter ve setter propertye erişim aracı olarakta tanımlanabilir. Eğer bir propertyde sadece getter metodu var bu onun read-only olduğunu gösterir. Hem getter hem setter tanımlıysa hem okunabilir hem yazılabilirdir.

Nesne Özellikleri (Object Attributes)

Her nesne 3 özellikler ilişkilidir bunlar: Prototip(Protoype), sınıf(class) ve genişletilebilir(extensible).

Prototip(Prototype) Özelliği : Nesnenin prototip özelliği o nesnenin hangi özellikleri miras aldığını belirler. Temel olarak nesnenin iskeletini oluşturur.Bu açıdan önemlidir.Prototip attribute’u nesne create edildiğinde oluşturulur.

Sınıf(Class) Özelliği : Class atttribute’u nesnenin tipi hakkında bilgi sağlar. classof() fonksiyonu ile  nesnenin hangi sınıfa ait olduğuna bakabiliriz.

  • classof(null) // => “Null”
  • classof(1) // => “Number”
  • classof(“”) // => “String”
  • classof(false) // => “Boolean”
  • classof({}) // => “Object”
  • classof([]) // => “Array”
  • classof(/./) // => “Regexp”
  • classof(new Date()) // => “Date”
  • classof(window) // => “Window” (a client-side host object)

Genişletilebilir(The Extensible) Özelliği : Bu özellik nesneye yeni property eklenebilir mi eklenemez mi onu belirler. Genelde kullanıcı tanımlı tüm nesneler genişletilebilir nesnelerdir. Object.isExtensible() metoduyla bu özelliğinvar olup olmadığını sorgulayabiliriz.

Loading

Facebooktwitterredditpinterestlinkedinmail

JUnit ile Basit Bir Test Uygulaması

JUnit testlerini Eclipse ortamında gerçekleştirmek istiyorsanız, Eclipse Juno ve bundan sonraki sürümlerde herhangi bir jar dosyası indirmeden JUniti kullanabilirsiniz.                File -> New -> JUnit Test Case ile test projenizi oluşturabilirsiniz.

Ancak ekli değilse JUnit jar dosyasını JUnit adresinden indirebilirsiniz.
Bu kütüphaneyi projenizde kullanmak için projenize sağ tıklayıp Build Path-> Configure Build Path dedikten sonra Libraries sekmesinden Add External JARs seçeneğine tıklayıp indirmiş olduğunuz Junit4.*.jar arşivini seçiniz.  Artık JUnit kütüphanesi eklenmiş oldu.

Basit bir test ile başlayabiliriz. Toplama ve çarpma işlemleri yapan metotlar yazalım ve bu metotların doğru çalışıp çalışmadığını kontrol edelim;
Projemizi oluşturduktan sonra ilk önce toplama ve çarpma işlemleri için fonksiyonlarımızı aşağıdaki şekilde yazalım.

Metotlarımızı yazdıktan sonra projemize JUnit testimizi ekleyelim. Daha önce anlatıldığı gibi dilerseniz projenize sağ tıklayıp New -> JUnit Test Case ile projenizi oluşturabilirsiniz. Next’e tıklayarak test etmek istediğiniz metodları seçebilirsiniz, Eclipse tüm metodları seçenek halinde size sunacaktır ya da yeni bir class oluşturup kütüphaneleri kendiniz ekleyip test metotlarını kendiniz oluşturabilirsiniz.

 Run-As-> JUnit Test ile projemizi çalıştırdığımızda yeşil bir çubuk göreceksiniz. Bu çubuk yazdığınız testlerin başarılı bir şekilde sonuçlandığını gösterir.

Bir de testin başarısız olduğu durumu görmek için bir test metodu daha yazalım.

testHataliToplama metodunda, toplama fonksiyonundan dönen sonuç aslında 12 fakat biz testte sonucun 11 olmasını bekliyoruz.Buradaki testte beklediğimiz değer yanlış olduğu için çalıştırdığımızda, kırmızı çubuk göreceksiniz.

Örnek pek spesifik olmadı fakat hataları görme açısından basit ve yararlı olacağını düşünüyorum.

Ek olarak kullanabileceğiniz test metodları ise şunlardır;

fail(String): Methodun başarısız olmasına izin verir. Ulaşılamayan kod parçalarını kontrol etmek için kullanılır.

assertTrue(true): Sonucun doğru olduğunu kontrol eder.

assertNull([message], object): Nesne null mu kontrol eder.

assertNotNull([message], object): Nesne Null değil mi kontrol eder.

assertSame([String], expected, actual): İki değişken de aynı nesneye mi referans veriyor kontrol eder.

assertNotSame([String], expected, actual): İki değişken farklı nesnelere mi referans veriyor kontrol eder.

assertTrue([message], boolean condition): Boolean koşulu “true” mu kontrol eder.

assertFalse([message], boolean condition): Boolean koşulu “false” mu kontrol eder.

assertsEquals([String message], expected, actual): Değerler aynı ise test eder.
Array kullanıldığında, dizinin adreslerinin aynı olup olmadığını kontrol eder, içeriğini karşılaştırmaz.

assertsEquals([String message], expected, actual, tolerance):  Float veya Double kullanıldığı zaman, ne kadar tolerans verilmesi gerektiğini gösterir.
Kaç tane ondalık sayısının aynı olup olmadığını kontrol edeceğine karar veririz.

Kullanabileceğiniz diğer metotlar;

@Test public void method(): Test metodu olduğunu gösterir.

@Before public void method(): Testten önce methodu gerçekleştirir.Bu method test için gerekli şeyleri hazırlar, giriş verilerinin okunması gibi.

@After public void method(): Method, test ile birlikte başlamalıdır.

@BeforeClass public void method(): Bütün testlere başlamadan önce method()’u çalıştırır, bu genelde zaman alıcı işlerde kullanılır, veritabanı bağlantısı yapmak gibi.

@AfterClass public void method(): Bütün testler bittikten sonra method() çalıştırılır. Bu genel de işlem sonrası temizlik için kullanılır, veritabanı bağlantısını kapatmak vb.

@Ignore: Test methodunu görmezden gelinir.

@Test(expected=IllegalArgumentException.class): Eğer adı verilen exception atılıyorsa testi yapar.

@Test(timeout=1000):  Methodun işlem süresi 1000 milisaniye (1 saniye) tutuyorsa başarısızlıkla sonuçlanır.

 

Loading

Facebooktwitterredditpinterestlinkedinmail

JUnit ile Test Odaklı Yazılım Geliştirme (TDD)

junit

JUnit, Java da test odaklı yazılım geliştirmek için kullanılan bir frameworktur.

Öncelikle, test odaklı yazılım geliştirme (Test Driven Development) kısaca TDD dediğimiz yapıdan bahsetmek istiyorum.

Klasik bir yazılım geliştirme sürecinde önce yazılım tasarlanır, ardından kodlanır ve en son test işlemleri yapılır.Bu süreç sonucunda ise bir çok problem ile karşılaşılır, bu problemleri gidermeye yönelik yapılan çalışmalar ya yetersiz kalır ya da yazılımın maliyetini büyük bir ölçüde artırır. Yazılım sona erdikten sonra yapılan test işlemlerinin kapsamı yetersiz olacağından kodun belli kısımları test edilemez ve oluşabilecek hataların tespiti zorlaşır bu durumda hatalar sistem kullanıcıları tarafından bulunur. Bu da istenilen bir durum değildir.

İşte bunun gibi problemleri çözmek, sistem hatalarının oluşmasını engellemek ve kaliteli yazılımlar yapabilmek için test odaklı yazılım (TDD) konsepti geliştirilmiştir.İlk olarak Extreme Programming (XP) yazılım sürecinin oluşturucusu Kent Beck tarafından ortaya atılmıştır.Extreme programming ve günümüzdeki bir çok Agile(çevik)modern yazılım geliştirme süreçlerinin kodlama bakımından bel kemiğini oluşturmaktadır.

TDD klasik yazılım geliştirme süreçlerinin aksine programı kodlamadan önce modeli test edecek şekilde test sınıflarını oluşturularak yazılım işlemine başlanır.

TDD için temel adımlar 5 tanedir.

1- Herhangi bir kod yazmadan test oluştur.
2- Testleri çalıştır ve eklenen testin çalışmadığını gör.( kırmızı )
3- Testin çalışması için gerekli değişiklikleri yap.
4- Testleri çalıştır ve hepsinin hatasız çalıştığını gör( yeşil )
5- Tekrarları yok et ve başa dön; refactoring.

Burada gerekli sınıfların en basit şekilde oluşturulmaları önem taşır.Test edilen sınıf metotları ilk başta null değeri geri döndürülecek şekilde oluşturulup daha sonra kullanıma göre gereken değişiklikler yapılarak en basit şekilde oluşturulur.Sonuç olarak testler ve gerekli sınıflar oluşturularak tasarım gerçeklenir.
TDD doğru uygulandığında son satırına kadar test edilmiş bir yazılım meydana gelmiş olur ve bu yazılımdaki her bir modülün entegre edilmesi oldukça kolaydır.Refactoring bize çok büyük bir rahatlık sağlar, kodun hata vermeyeceğini garanti eder ve verdiği takdirde nerede verdiğini bize bildirir. Debug ve breakpointler olmadan yazılım daha rahat ve kısa sürede geliştirilir.

Bir yazılım sürecinde Unit testin yanı sıra Integration Tests(Entegrasyon testleri), Acceptance Tests (Kabul Testleri), Continuous Integration(Sürekli birleştirme), Database Tests(Veritabanı testleri) gibi bir çok test bulunmaktadır.Buraya kadar yazılımın en küçük birimlerini test eden,unit testlerden bahsettik.

Sonraki yazıda JUnit ile unit testlerin nasıl geliştirildiği konusuna değineceğiz.

Loading

Facebooktwitterredditpinterestlinkedinmail