TDD: Birim (Unit) Testlere Giriş

Başlarken

Önceki yazılarımda Test Driven Development hakkında bir giriş yapmıştık. Tabiki gerçek hayatta $this->assertTrue(true) yapmıyoruz 🙂 Şimdiki yazımda ise gerçek hayatta birim testler nasıl uygulanıyor onlar hakkında konuşacağım. Daha önceki yazılarıma ulaşmak isterseniz:

Test Driven Development (TDD) Nedir?

PHPUnit Nasıl Kullanılır

Test Edilebilir Kod Üretmek

Birim Nedir?

Birim test yapmadan önce birimin ne olduğunu bilmek şart 🙂

Birim: Bir yazılımın test edilebilir en küçük parçasıdır. Bu OOP’ta genelde bir method olarak nitelendirilir.

Özellikleri

Birim testlerin en önemli özelliği bir test’in dışarı bağımlı olmamasıdır. Eğerki blog uygulamanızdaki Post classını test ediyorsanız bunu veritabanına bağlanmadan test etmelisiniz.

Peki veritabanına düzgün ekliyor mu nasıl anlayacağız?

Merak etme onun da kendi testi var.

Benim uygulamam veritabansız çalışmaz ki???

İşte bu yüzden Test Edilebilir Kod Üretmek konusunda konuşmuştuk. Şimdi ise bu ürettiğimiz test edilebilir kodları nasıl test edeceğiz onlar hakkında konuşacağız.

Mock Objects

İşte burası zurnanın zırt dediği yer. Mock objesi sahte/taklit obje anlamına geliyor. Yani siz Post sınıfınızı veritabansız test edecekseniz o veritabanı sınıfının sahtesini yazacaksınız (taklit edeceksiniz) ki bu sınıfta veritabanı kullanmayacak. Yani veritabanı sınıfını simule edeceğiz. Örnekle şekillendirelim

interface PostInterface {

    public function yarat($user_id, $baslik, $icerik);

}

class Post_MySQL implements PostInterface {

    public function yarat($user_id, $baslik, $icerik) {
        $stmt = DB::getConnection()->prepare('INSERT INTO post VALUES (?,?,?)');
        return $stmt->execute(array($user_id, $baslik, $icerik));
    }

}

Örnekte veritabanı aracılığı ile bloga girilen postu kaydeden bir model sınıfımız var. Şimdi ise bu model’i kullanan bir Controller yazıyorum:

class PostController {

    private $post;

    public function __construct(PostInterface $post) {
        $this->post = $post;
    }

    public function yarat() {
        $sonuc = $this->post->yarat($_POST['user_id'], $_POST['baslik'], $_POST['icerik']);
        if ($sonuc == true) {
            return "Post başarıyla yaratıldı";
        } else {
            return "Beklenmeyen hata oluştu";
        }
    }
}

Asıl yaratma işleminin yapılacağı sayfada ise şu şekilde controller’ımı kullanıyorum:

$controller = new PostController(new Post_MySQL());
echo $controller->yarat();

 Mock Objelerinin yaratılması ve kullanılması

Mock objeleri aslında çok basit bir şekilde yaratılır. Siz zaten kodunuzu test edilebilir bir şekilde hazırladığınız için bu sizin için bir sorun olmayacak 🙂 Şimdi iki tane hazırlıyorum.

class BasariliYaratma implements PostInterface {

    public function yarat($user_id, $baslik, $icerik) {
        return true;
    }

}

class BasarisizYaratma implements PostInterface {

    public function yarat($user_id, $baslik, $icerik) {
        return false;
    }

}

İşte bu kadar basit! Şimdi ise testimi hazırlayabilirim:

class PostTest extends PHPUnit_Framework_TestCase {

    public function testPostBasariylaEklendigindePostBasariylaYaratildiYazisiGeliyor() {
        // dependency injection
        $controller = new PostController(new BasariliYaratma());
        $this->assertEquals("Post başarıyla yaratıldı", $controller->yarat());
    }

    public function testVeritabaniBaglantisiIleIlgiliSikintiOldugundaHataMesajiGoster() {
        // dependency injection
        $controller = new PostController(new BasarisizYaratma());
        $this->assertEquals("Beklenmeyen hata oluştu", $controller->yarat());
    }

}

Daha sonra testlerimizi çalıştırıyoruz ve controller’ımızın beklenen adımları gerçekten sergileyip sergilemediğine bakıyoruz.

Sonuç

Sonuç olarak basit bir şekilde mock objelerinin nasıl yaratılacağını görmüş olduk. Ancak gerçek hayatta 10larca hatta 100lerce sınıfınız olabilir o yüzden 1000lerce mock objesine ihtiyaç duyabilirsiniz. Biz gerçek hayatta, bunları amele gibi tek tek oluşturmuyoruz. Bunun için PHPUnit’in getMock method’u veya Mockery sınıfı kullanılıyor. Bir sonraki yazımda Mockery aracı ile nasıl mock objeleri yaratıldığı hakkında konuşacağım. Hadi kolay gelsin.

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax