17 Eylül 2018

Test Kodlarında Anti-Pattern’ler (Test Code Smells)

Yazılım testi hem manuel hem de otomasyon olarak yapılabilmekte ve manuel testte test mühendisi son kullanıcı rolünü üstlenerek testleri gerçekleştirirken otomasyon testinde test araçları kullanılarak test betikleri/kodları yazarak gerçekleştirmektedir.

Yazılım testi hem manuel hem de otomasyon olarak yapılabilmekte ve manuel testte test mühendisi son kullanıcı rolünü üstlenerek testleri gerçekleştirirken otomasyon testinde test araçları kullanılarak test betikleri/kodları yazarak gerçekleştirmektedir. Eğer planlı ve düzgün bir şekilde yapılırsa otomasyon testi, örneğin tekrar edilebilirlik sağlama, testin maliyetini ve iş yükünü azaltmak gibi manuel teste göre ciddi faydalar sağlamaktadır. Fakat, eğer betikler/kodlar düzgün bir şekilde geliştirilmezse manuel teste göre daha az etkili olmakta, ekstra maliyet ve iş yükü getirebilmektedir.

Yazılım endüstrisinde otomasyon testi ve test scriptleri geliştirilmesi ana akım haline gelmektedir. Örneğin Microsoft test mühendisleri Office 2007 için bir milyondan fazla otomatize edilmiş test durumu yazmıştır. Ülkemizde de son yıllarda test otomasyonuna önem verilmeye başlanmıştır.

Test kodunun kalitesi de en az kaynak kodun kalitesi kadar önemlidir. Kimse düşük kalitede ve hatta içinde açık bulunan test kodlarıyla yapılan testten faydalanamaz.

Kaliteli test kodları geliştirmek için farklı pratikler ve metodlar önerilmişse de, uygulamaya düzgün bir şekilde geçirilemediği için Test Smell (Anti-Pattern)’ler oluşmaktadır. Tasarımı zayıf , kötü tasarımlanmış test kodları test smell olarak adlandırılmakta ve bunların test süitinin ve ürün kodunun bakımına, korunabilirliğine (maintainability) ve hatta fonksiyonelliğine olumsuz etkileri olmaktadır.

Test smell’ler birçok firma için büyük maliyetlere sebep olmuştur. Örneğin Google’da geliştirilmiş bir test süitinde 15 ay süresince her gün ortalama 1.6 milyon test başarısız olarak sonuçlanıyormuş ve bunların yaklaşık 73 bini (%4.5) flaky testlerden yani aynı ürün kodunu test edip bazen geçen bazen kalan test kodlarından kaynaklanıyormuş. Yine Google’a ait resmi test bloğunda (googletesting.blogspot.com/2016/05/flaky-tests-at-google-and-how-we.html) paylaşılan bilgiye göre Google’da yazılan testlerin %16’sının yani 7de 1’inin flaky test olduğundan ve bunun ciddi bir rakam olduğundan bahsediliyor.

Test smell’leri 2001’den itibaren akademik ve endüstride tartışılmaya başlanmış ve bu konu ile ilgili yapılan çalışmalar gittikçe artmıştır. Yapılan çalışmaların ve tartışmaların yıllara göre değişimi aşağıdaki grafikte görülebilir.

BİR TEST KOD SMELL ÖRNEĞİ

Aşağıda bir eager test smell örneği ve bu smell’in düzeltilmiş hali verilmiştir. Örnek, popüler bir açık kaynak kodlu uygulama olan JfreeChart (www.jfree.org/jfreechart) projesinden alınmıştır. Aynı test objesinin birçok davranışını aynı test methodunun içinde test etmeye çalışan metoda Eager Test denir. Sol bölümde yazılan test metodunun orjinalinde 25 tane assert metodu bulunmakta ve bu görüldüğü gibi bir çok durumu test etmeye çalışan bir eager test.

Bu durumda, bir tane assert metodunun başarısız olması, bütün test metodunun durmasına, testin geri kalanının çalıştırılmamasına ve potansiyel olabilecek diğer hataların yakalanmasının engellenmesine ve ayrıca geliştiricinin test sırasında nasıl bir sorun oluştuğunu anlamasını zorlaştırmaya sebep olacaktır. Bu smell’i ortadan kaldırmak için sağda görüldüğü gibi test metodu her biri test objesinin özel durumlarını ayrı ayrı test edecek şekilde küçük metodlara bölünmelidir.

public class XYTextAnnotationTest {

 

    /**

     * Confirm that the equals method can distinguish all the required

       fields.

     */

    @Test

    public void testEquals() {

        XYTextAnnotation a1 = new XYTextAnnotation("Text", 10.0, 20.0);

        XYTextAnnotation a2 = new XYTextAnnotation("Text", 10.0, 20.0);

        assertTrue(a1.equals(a2));

 

        // text

        a1 = new XYTextAnnotation("ABC", 10.0, 20.0);

        assertFalse(a1.equals(a2));

        a2 = new XYTextAnnotation("ABC", 10.0, 20.0);

        assertTrue(a1.equals(a2));

 

        // x

        a1 = new XYTextAnnotation("ABC", 11.0, 20.0);

        assertFalse(a1.equals(a2));

        a2 = new XYTextAnnotation("ABC", 11.0, 20.0);

        assertTrue(a1.equals(a2));

 

        // y

        a1 = new XYTextAnnotation("ABC", 11.0, 22.0);

        assertFalse(a1.equals(a2));

        a2 = new XYTextAnnotation("ABC", 11.0, 22.0);

        assertTrue(a1.equals(a2));

 

        // font

        a1.setFont(new Font("Serif", Font.PLAIN, 23));

        assertFalse(a1.equals(a2));

        a2.setFont(new Font("Serif", Font.PLAIN, 23));

        assertTrue(a1.equals(a2));

 

        ...

 

    }

    ...

}

/**

     * Confirm that cloning works.

     */

    @Test

    public void testCloning() throws CloneNotSupportedException {

        XYTextAnnotation a1 = new XYTextAnnotation("Text", 10.0, 20.0);

        XYTextAnnotation a2 = (XYTextAnnotation) a1.clone();

        assertTrue(a1 != a2);

        assertTrue(a1.getClass() == a2.getClass());

        assertTrue(a1.equals(a2));

    }

 


Proven Test Hizmetleri ekipleri , Entegre Test Yönetimi Yaklaşımı, Bağımsız Test ve Dış Kaynak Hizmetleri ile müşterilerinin yazılım ve bilişim alanındaki ürün ve hizmetlerinin kalitesini arttırmak için alternatif çözümler sağlamaktadır. Proven Blog sayfalarında, test smell türleri ve bunların nasıl engellenebileceği, nasıl tespit edilip düzeltilebileceği ile ilgili bilgiler vermeye devam edeceğiz.

Konuyla ilgili daha detaylı bilgiye www.proven.com.tr üzerinden veya bkucuk@proven.com.tr adresine e-posta atarak ulaşabilirsiniz.

Barış KÜÇÜK


Kaynaklar

[1]   V. Garousi B. Küçük "Smells in software test code: A survey of knowledge in industry and academia" Journal of Systems and Software vol. 138 2018.