... konulu sunumlar: "Ali Yamuç Ayhan Çakın firstname.lastname@example.org email@example.com Web Uygulamalarında Test Güdümlü Geliştirme Yii üzerinde bir örnek durum çalışması Ali."— Sunum transkripti:
1 Ali Yamuç Ayhan Çakın firstname.lastname@example.org email@example.com Web Uygulamalarında Test Güdümlü Geliştirme Yii üzerinde bir örnek durum çalışmasıAli Yamuç Ayhan Çakın
2 İçerik Giriş Test Öncelikli Geliştirme(TÖG) TÖG -> Test Güdümlü Geliştirme(TGG)TGG : Neden ve Nasıl?Web Uygulamarında TGGÖrnek Bir Durum: Akademik Katalog SistemiYii Çatısında Birim TestlerYii Çatısında Fonksiyonel TestlerSonuçlar
3 GirişBug’ların analizinin ve çözümlerinin şirketlere büyük miktarlarda hem zaman hem para ve en önemlisi de prestij kaybettiriyorTestler yazmak ekstra bir yük değil, bir gerekliliktir.TDD, evrimsel bir yaklaşıma sahiptirTest Öncelikli Geliştirme(TFD)Gözden Geçirme(Refactoring)
4 Test Öncelikli Geliştirme(TÖG) kodu yazmaya başlamadan önce başarısız olmasına yetecek bir test yazmakdaha sonra bu testi karşılayacak kadar yeterli kodu yazmak
5 TÖG -> Test Güdümlü Geliştirme(TGG) Testlerin tamamını geçtiğimiz anda bu döngünün en başına dönüp, yeniden başlamak gerekir.En başa dönmeden, kodu gözden geçirip dizayn ve gereksinimlere uymayan kısımları düzeltilebilirUygulanan süreç Test Öncelikli Geliştirmeden, Test Güdümlü Programlamaya dönüşmüş olur.
6 Test Güdümlü Geliştirme Kent Beck «Test-Driven Development: By Example»Elinizde başarısız bir test senaryosu olmadan asla tek satır kod bile yazmayın,Kod tekrarı yapmayın.Kod tamamlandıktan sonra test yazılması beklenirse, baştaki tüm bu yöndeki niyete rağmen muhtemelen test yazılmayacaktır.Testleri önce yazarak ve kodlama sürecine direkt olarak test yazma sürecini enjekte ederek en kapsamlı testi süreci sağlanmış olur.
7 Test Güdümlü Geliştirme Test güdümlü programlama geleneksel geliştirme yöntemlerini özellikle yazılım kalitesini geliştirmek açısından tamamen değiştirmektedir.Örneğin: Yeni bir modül geliştirmek istediğimizde:Bu sürece başlamadan önceki ilk adımımız, elimizdeki tasarımın bu modülü geliştirmek ve entegre etmek için en iyi tasarım olup olmadığını sorgulamaktır.Eğer öyle ise, hemen test öncelikli geliştirme sürecine başlanabilir.Ancak tasarımın uygun olmadığını ya da yetersiz olduğunu düşünüyorsak, önceliğimiz geliştirme sürecinden çok; varolan tasarımın modülün ekleneceği kısmının gözden geçirilmesi(refactoring) ve bu kısmın yeni eklenecek özelliğe uygun hale getirilmesidir.Aslında bu sayede, adım adım elimizdeki tasarım gelişmekte ve gelecekteki çalışmalarımız için çok daha kaliteli ve uyumlu hale gelmektedir.
8 TGG: Neden?Michael Feathers “Working Effectively With Legacy Code” kitabında:«Test olmadan yazılan kod kötü koddur. Ne kadar iyi yazılmış, ne kadar güzel, ne kadar nesne tabanlı ya da ne kadar iyi kapsüllenmiş(encapsulated) olursa olsun, bunu değiştirmez. Testlerle kodun davranış biçimi çabuk ve denetlenebilir şekilde değişir. Testler olmadan kodumuzun iyiye ya da daha kötüye mi gideceğini gerçekten bilemeyiz. »Somut bir Örnek(Paul Grenyer)
9 TGG: Nasıl? Otomatikleştirilmiş testler aracılığı ile: Birim Testler (Unit Tests) : Sadece bir birimi test eden testlerdir, Örneğin: bir sınıfı ya da metodu. Eğer bir sınıf test ediliyor ise, yapay(mock) nesneler ile ilklendirilerek test gerçekleştirilir.Fonksiyonel Testler (Functional Tests): Fonksiyonel gereksinimlerin sistemde eksiksiz ve dogru biçimde uygulanıp uygulanmadığının ölçen testlerdir. Genel olarak kara kutu testleri (black box test) grubunda anılırlar.
10 Web tabanlı uygulamalarda TDD Web uygulamaları geliştirilmesinde TDD bazı çatılar (framework) tarafından desteklenmektedir.Diğer klasik metotlara göre zahmetli gözüktüğünden dolayı pek de uygulanmamaktadır.Özellikle karmaşık web uygulamalarının geliştirilmesinde TDD’nin kullanımı birçok hatayı çok önceden önlemekte ve servislerin hizmet dışı kalması ya da yanlış sonuçlar üretmesi kod yazımı aşamasında engellenebilmektedir.
11 Örnek Bir Durum: Akademik Katalog Sistemi Test Güdümlü Geliştirme bir örnek durum çalışması olarak göstermek için çevik metodoloji ve TDD kullanarak geliştirmiş olduğumuz web-tabanlı Akademik Katalog Sistemi uygulamasından faydalandık.Sadece küçük bir kesitini inceleyeceğiz.
12 Akademik Katalog Sistemi Akademik Katalog Sistemi yüksek öğretim kurumlarının Bologna Süreci [7] kapsamında online olarak sunulması zorunlu olan bilgilerin belli ara yüzlerle sunulması ve yönetilmesi için web tabanlı bir bilgi sistemidir.Bu sistemin temel amacı yükseköğrenim kurumlarının öğrenim süreçlerinde kalite güvenceyi, şeffaflığı, izlenebilirliği ve ölçülebilirliği sağlamaktır.(ETCS)
13 Akademik Katalog Sistemi Kullanıcı Hikayeleri:2 temel rol: «Guest» ve «Authenticated»Authenticated: Öğretim Elemanı (Instructor), Ders Koordinatörü (Course Coordinator), Program Direktörü (Program Director), Akademik Birim Başkanı (Academic Unit Head), AdminBu kullanıcı hikâyelerinden uygulamamızda ana domain nesneleri olarak 4 temel varlık (enitity): kullanıcı (user), ders (course), program, akademik_birim (academic_unit) elde edilmektedir.
15 AKS Geliştirme Metodolojisi Çevik metodolojiden (agile methodology) esinlenilmiş döngüsel (iterative) ve artımlı (incremental) bir geliştirme metodolojisi benimsedik.Bu özelliğin gerçekleştirilmesi sürecinde döngüsel bir model takip ettik. Öncelikle döngü planlaması yaptık ve her döngüde TDD yaklaşımı ile test ve bu testleri başarıyla geçen kodları yazarak süreci tamamladık.Son adım olarak, herkes mutlu olduğunda, yeni özelliği ile birlikte uygulamayı hizmete soktuk ve bundan sonra diğer döngüde gerçeklenecek diğer özellik veya özelliklerin spesifikasyonlarını toplamaya başladık.
16 Yii Çatısında TGGUygulamamızda TDD sürecini gerçeklemek için yaptığımız unit testler için PHPUnit ve fonksiyonel testler için Selenium Server kullanılmaktadır .Yii PHPUnit ve Selenium Server test çatıları ile oldukça sıkı bir şekilde entegre durumdadır.
17 Yii Çatısında Birim Testler Yii’de (Yii Dokümantasyon) bir birim testi Yii çatısının CTestCase sınıfından türetilerek (extend) elde edilen bir PHP sınıfı ile yapılır.Örnek Kullanıcı Hikayesi:“Ders Koordinatörleri dersleri koordine etmekle sorumludurlar. Bu kapsamda dersleri oluştururlar ve dersin detaylı bilgilerini diğer bir ifadeyle izlencesini (syllabus) ve kimler tarafından verileceği bilgilerini girerler.”
18 Birim Testler BT 1: BT 2: class CourseTest extends CTestCase { //nothing}BT 2:public function testCRUD()$this->assertTrue(true);
19 Birim Testler BT 3: $newCourse=new Course(); $this->assertTrue($newCourse->save());Testimiz başarısız oldu. Model nesnesini save() metodu ile veritabanına kaydetmesinde bir problem oldu; çünkü Course model sınıfında ve bununla eşleşen veritabanındaki course tablosunda boş olarak kayıt yapılamayacak kısıtlar var (Foreign Key Constraints).
21 Birim TestlerBT 4:Bu kod ile ders eklemek için bir ders koordinatörü rolüne sahip bir kullanıcı olmalı ve kullanıcının hangi akademik birimde görev yaptığı bilinmelidir. Bu varsayım ve bu bilgi ile testi sadece ders varlığına odaklıyoruz, basitleştiriyoruz problemi. Şimdi tekrar test yapıyoruz.Aynı kod yazım tekniklerini uygularayarak şimdi de ders varlığının temel CRUD işlemlerinden READ, UPDATE ve DELETE işlemlerini test ediyoruz.
22 Yii Çatısında Fonksiyonel Testler Yii’de fonksiyonel test yapmak için tests/functional dizini altına CourseTest.php adı altında bir dosya açıyoruz ve içerisine CourseTest adından CWebTestCase sınıfından türeyen bir sınıf tanımlıyoruz.“Ders Koordinatörleri dersleri koordine etmekle sorumludurlar. Bu kapsamda dersleri oluştururlar ve dersin detaylı bilgilerini diğer bir ifadeyle izlencesini (syllabus) ve kimler tarafından verileceği bilgilerini girerler.”
23 Fonksiyonel TestlerYaptığımız birim testler daha da çoğaltılabilir de ama biz örnek olsun diye temel CRUD işlemlerini test ettik.Birim testler sadece geliştirici tarafında yapılırken, fonksiyonel testler hem geliştirici hem de paydaşlar tarafında yapılabilir.Seleninum Server herhangi bir tarayıcıyı kullanarak testi görsel olarak da gösterebilir.
24 Fonksiyonel TestlerFonksiyonel testimizde ilk test metodumuz testIndex. Ana sayfamızı açıp 3 sn bekleyip Academic kelimesinin olup olmadığını sorguluyoruz. Şimdi phpunit functional/CourseTest.php yazarak konsol testimizi başlatalım.
25 Fonksiyonel Testler Önceki test başarı ile sonuçlandı. Şimdi testimizi daha da karmaşıklaştıralım. Kullanıcımız sisteme giriş yapsın. Akabinde görev yaptığı bölümün sayfasına girsin ve bir ders oluştursun. Gereken temel bilgileri girsin. Sonra kaydetsin ve bölümün sunduğu derslerden kontrol etsin dersi var olup olmadığını. Ders bilgilerini tekrar görsün. Daha sonra güncelleme linkine tıklasın. Dersi verenler alanına bazı hocalar eklesin ve kaydetsin. Sonra kaydımızı silsin ve silmek için gereken doğrulama mesajının doğru bir şekilde gelip gelmediğini sorgulasın. Son olarak sistemden çıkış yapsın.Bunun için gerekli kodu yazalım.
26 Fonksiyonel Testler http://www.youtube.com/watch?v=7-IBEKIlwFk public function testCourseCreate(){$this->open('');$this->waitForPageToLoad("3000");// ensure the user is logged outif($this->isTextPresent('Logout'))$this->clickAndWait('link=Logout');//test login process, including validation$this->clickAndWait('link=Login');$this->assertElementPresent('name=LoginForm[username]');$this->type('name=LoginForm[username]','ayamuc');$this->assertTextPresent('Password cannot be blank.');$this->type('name=LoginForm[password]','1');$this->open('?r=academicunit/view&id=3');$this->assertTextPresent('Computer Engineering');$this->clickAndWait('link=Create Course');$this->type('name=Course[title]','Test Driven Development');$this->type('name=Course[code]','SE 444');$this->assertTextPresent('Test Driven Development');$this->open('?r=course/courselist&aid=3'); $this->assertTextPresent('SE 444'); $this->assertTextPresent('Test Driven Development'); $this->clickAndWait('link=SE 444'); $this->clickAndWait('link=Update Course'); $this->assertElementPresent('name=Course[title]'); $this->assertElementPresent('name=Course[code]'); $this->type('name=Course[instructor]','Semih Dinç, İsmet YiğitBaşı'); $this->assertTextPresent('Semih Dinç, İsmet YiğitBaşı'); $this->clickAndWait('link=Delete Course'); $this->assertEquals('Are you sure you want to delete this item?',$this->getConfirmation()); $this->assertTextNotPresent('Login'); $this->clickAndWait('link=Logout (ayamuc)'); $this->assertTextPresent('Login'); }
27 SonuçlarBu çalışmada, Yii çatısı kullanarak geliştirmiş olduğumuz web-tabanlı Akademik Katalog Sistemi uygulamasında uyguladığımız metodolojik yaklaşımları ele aldık.Bu kapsamda Test-Güdümlü Geliştirme’yi, artımsal çevik metodoloji ile birlikte kullanarak yaptığımız testler ve sonuçlarını ile gösterdik.Özellikle web-tabanlı uygulamalarda ihmal edilen bu yaklaşım tarzları ile güvenli, daha az hatalı ve daha başarılı uygulamalar geliştirilebileceğini gözlemledik.Bu metot ile özellikle karmaşık web-uygulamalarında, paydaşlarda ve geliştiricilerde sağlanan güven duygusu ile oldukça kaliteli uygulamalar geliştirilebileceğini görmüş olduk.