Takip et

XPathy: Flaky Testleri Bitiren Fluent API

Web otomasyon testleriniz sürekli “flaky” mi oluyor? Dinamik web sayfalarında elementleri bulmak kabusunuz mu? Geleneksel XPath’in bakımı zor, kırılgan yapısına bir alternatif arıyorsanız, XPathy’nin Fluent API’ı ile tanışın. Bu makale, testlerinizi nasıl daha sağlam, okunabilir ve sürdürülebilir hale getireceğinizi adım adım açıklıyor.

Modern web uygulamaları, sürekli değişen ve gelişen yapılarıyla test otomasyon mühendisleri için ciddi zorluklar sunar. Tek sayfa uygulamaları (SPA’lar) ve dinamik olarak yüklenen içerikler, elementlerin DOM’daki konumunu sürekli değiştirebilir veya görünürlüklerini anlık olarak etkileyebilir. Bu durum, otomasyon testlerimizin en büyük düşmanı olan “flaky test” olgusunu ortaya çıkarır. Flaky testler, aynı kod ve aynı ortamda bazen geçerken bazen başarısız olan, güvenilmez testlerdir. Bir testin bir kez başarılı olup, sonraki çalıştırmada rastgele bir nedenden başarısız olması, otomasyon sistemlerine duyulan güveni temelden sarsar.

Geleneksel olarak, web elementlerini hedeflemek için XPath ve CSS Selector’lar kullanılır. XPath, esnekliği sayesinde çoğu senaryoda işimizi görse de, karmaşık ve dinamik web sayfalarında yazımı zorlaşır, okunabilirliği düşer ve en önemlisi son derece kırılgan hale gelir. Küçük bir UI değişikliği, hatta bir div etiketinin araya girmesi bile tüm XPath ifadesini geçersiz kılabilir. Bu durum, test senaryolarının sürekli bakımını gerektirir ve geliştirme süreçlerini yavaşlatır.

Peki, bu kırılganlığı nasıl aşabiliriz? Test otomasyonunun temel amacı, yazılımın kalitesini güvence altına almak ve geliştirme sürecini hızlandırmaktır. Ancak, flaky testler bu hedeflerin tam tersini yapar; geliştiricilerin zamanını hata ayıklama ve sürekli test düzeltmeleriyle boşa harcamalarına neden olur. Güvenilir olmayan test sonuçları, gerçek hataların gözden kaçmasına veya gereksiz yere düzeltmeler yapılmasına yol açabilir. Bu döngü, sonunda otomasyon çabalarına olan inancı azaltır ve manuel testlere geri dönüş eğilimini tetikler. İşte tam da bu noktada, geleneksel XPath yaklaşımlarının yetersiz kaldığı ve daha modern, daha sağlam çözümlere ihtiyaç duyulduğu açıkça ortaya çıkar. Artık sadece elementleri bulmak yeterli değil; onları dinamik ortamlara adapte olabilen, kolayca okunabilen ve bakımı yapılabilir bir şekilde bulmamız gerekiyor. Bu ihtiyaç, XPathy gibi Fluent API’ların yükselişini tetikleyen ana faktörlerden biridir. Bu tür araçlar, testlerin yazılma ve sürdürülme şeklini kökten değiştirerek, geliştiricilere daha sağlam ve güvenilir otomasyon testleri oluşturma gücü verir.

Raw XPath Neden “Öldü”? Geleneksel Yaklaşımın Eksiklikleri Nelerdi?

Geleneksel XPath, web elementlerini DOM (Belge Nesne Modeli) ağacındaki konumlarına göre hedeflemek için güçlü bir araçtır. Ancak bu gücün beraberinde getirdiği bazı ciddi zayıflıklar vardır. Bir elementin tam yolunu belirten mutlak XPath’ler (/html/body/div[1]/section/ul/li[2]/a gibi) son derece kırılgan olmalarıyla bilinirler. Sayfaya küçük bir element eklenmesi veya çıkarılması bile bu yolu geçersiz kılabilir. Göreceli XPath’ler (//div[@id='sidebar']/a[contains(text(),'Hizmetlerimiz')] gibi) biraz daha esnek olsa da, yine de büyük bir bakım yükü oluştururlar.

Düşünün ki, bir e-ticaret sitesindeki bir ürün kartını hedeflemek istiyorsunuz. Geleneksel bir XPath şöyle görünebilir:


    //div[@class='product-list']/div[3]/div[@class='product-card']/a[@data-product-id='12345']/h3
  

Bu ifade, üçüncü ürünü seçen, belirli bir ID'ye sahip ürün kartının içindeki başlığı hedefliyor. Eğer üçüncü sıradaki ürünün yeri değişirse veya araya yeni bir element girerse, bu XPath anında bozulur. Ayrıca, bu ifadeyi okumak ve neyi hedeflediğini anlamak için HTML yapısını iyi bilmek gerekir. Özellikle karmaşık XPath'ler, okunabilirlik açısından bir labirente dönüşebilir.

Geleneksel XPath'in bu karmaşık yapısı, test otomasyonu ekipleri için zamanla ciddi bir maliyet oluşturur. Testler başarısız olduğunda, öncelikle XPath ifadelerinin kontrol edilmesi gerekir ki bu da ciddi bir zaman kaybıdır.

Bir diğer önemli sorun, dinamik web siteleridir. JavaScript ile sürekli güncellenen veya tamamen yeniden çizilen sayfalar, elementlerin ID'lerini, class'larını veya diğer niteliklerini değiştirebilir. Örneğin, bir form gönderimi sonrası dinamik olarak oluşturulan bir başarı mesajını hedeflemek, bazen imkansız hale gelebilir çünkü mesajın tam XPath'i her zaman farklı olabilir veya sadece belirli bir zaman diliminde var olabilir. Geleneksel XPath, bu tür dinamik değişimlere karşı çok dirençli değildir. starts-with() veya contains() gibi fonksiyonlarla bir nebze esneklik sağlansa da, genel çözüm sunmaktan uzaktır.

Ayrıca, geleneksel XPath'in en büyük handikaplarından biri de "insan odaklı" olmamasıdır. Bir geliştirici veya test mühendisi, bir UI elementini düşünürken "Sayfadaki 'Kaydet' düğmesini bul" veya "Ürün listesindeki 'Sepete Ekle' yazan butonu bul" gibi ifadelerle düşünür. Ancak, geleneksel XPath yazarken bu doğal düşünce tarzından uzaklaşarak, elementin DOM içindeki hiyerarşik ve teknik konumuna odaklanmak zorunda kalırız. Bu da düşünce yapısıyla kodlama arasındaki mesafeyi açar ve hataya açık bir ortam yaratır. Bu nedenlerle, test otomasyonunun giderek daha önemli hale geldiği modern geliştirme döngülerinde, "Raw XPath" yaklaşımı artık yetersiz kalmakta ve "ölü" olarak nitelendirilmektedir. Daha sezgisel, daha sağlam ve daha bakımı kolay bir yaklaşıma ihtiyaç duyulmaktadır.

XPathy Nedir ve Fluent API Ne Anlama Gelir?

XPathy, web otomasyon testlerinizdeki element bulma sürecini devrim niteliğinde değiştirmeyi hedefleyen, XPath ifadeleri oluşturmak için tasarlanmış bir Fluent API yaklaşımıdır. "Fluent API", bir API tasarım desenidir ve zincirleme metot çağrıları kullanarak kodun daha okunabilir ve doğal bir dil gibi akmasını sağlar. Amaç, karmaşık işlemleri bile adım adım, anlaşılır bir sırayla ifade etmektir. XPathy'nin temel felsefesi, karmaşık ve kırılgan XPath ifadelerini, insan diline yakın, anlaşılır ve sürdürülebilir bir yapıya dönüştürmektir.

Geleneksel XPath yazarken karşılaşılan zorluklar göz önüne alındığında, XPathy'nin Fluent API'ı, element hedefleme sürecini basit, anlaşılır adımlara böler. Örneğin, bir "Kaydet" butonunu bulmak için artık //button[text()='Kaydet'] gibi bir ifade yazmak yerine, XPathy ile XPathy().button().with_text("Kaydet") şeklinde ifade edersiniz. Bu, sadece bir söz dizimi değişikliği değil, aynı zamanda elementin ne olduğunu ve neden seçildiğini anlatan bir ifade biçimidir. Kodun okuyucusu, elementin hangi özelliklere sahip olduğunu ve ne anlama geldiğini kolayca kavrayabilir, bu da bakım maliyetlerini önemli ölçüde düşürür.

Uzman İpucu: Fluent API, kodunuzu doğal dil gibi okumanızı sağlayarak karmaşıklığı azaltır ve hataları daha kolay tespit etmenize olanak tanır.

XPathy'nin Fluent API'ı, bir dizi metodu birbirine zincirleyerek karmaşık XPath'leri oluşturur. Bu metotlar, HTML elementinin etiket adı (div(), button(), input() gibi), içerdiği metin (with_text(), contains_text() gibi), sahip olduğu nitelikler (with_id(), with_class(), has_attribute() gibi) veya DOM içindeki ilişkileri (parent(), has_child() gibi) baz alabilir. Bu yaklaşım, XPath ifadelerini daha modüler hale getirir. Her bir metot, belirli bir koşulu veya özelliği temsil eder ve bir araya geldiklerinde güçlü ve spesifik bir element seçici oluştururlar.

Sürdürülebilirlik açısından da XPathy önemli avantajlar sunar. Bir UI değişikliği olduğunda, geleneksel XPath'i baştan sona yeniden yazmak yerine, XPathy ifadesindeki ilgili metot çağrısını güncellemek genellikle yeterlidir. Örneğin, bir elementin metni değişirse sadece with_text() metodundaki değeri güncellemek yeterli olurken, DOM yapısındaki bir değişiklik sadece div() yerine span() gibi etiket adını değiştirmeyi gerektirebilir. Bu modüler yapı, testlerin bakımını hızlandırır ve hatalı XPath'lerin neden olduğu "flaky test" sayısını azaltır. Sonuç olarak, XPathy, test otomasyonunu sadece daha kolay değil, aynı zamanda daha güvenilir ve verimli hale getiren bir yaklaşımdır.

XPathy'nin Temel Prensipleri ve Felsefesi Nelerdir?

XPathy'nin arkasında yatan temel prensipler, modern test otomasyonunun ihtiyaçlarına cevap vermek ve geleneksel XPath'in zayıflıklarını gidermek üzerine kuruludur. Bu prensipler, geliştiricilere daha iyi, daha sağlam ve daha keyifli bir test yazma deneyimi sunmayı hedefler:

  • Okunabilirlik (Readability): En önemli prensiplerden biridir. XPathy, kodun doğal bir dil gibi okunmasını sağlar. XPathy().div().with_text("Kullanıcı Adı") ifadesi, "İçerisinde 'Kullanıcı Adı' metni olan bir div bul" anlamına gelir ve bir test mühendisi veya geliştiricinin anadilinde düşündüğü şekle çok yakındır. Bu sayede, kodun ne yaptığını anlamak için DOM yapısını detaylıca incelemeye gerek kalmaz.
  • Sürdürülebilirlik (Maintainability): Web uygulamaları sürekli değişir. XPathy, bu değişikliklere karşı daha dirençli ifadeler oluşturmaya odaklanır. Bir UI değişikliği olduğunda, tüm XPath'i yeniden yazmak yerine, ilgili metot çağrısını güncellemek yeterli olur. Bu, testlerin bakım süresini ve maliyetini önemli ölçüde azaltır.
  • Sağlamlık (Robustness): Dinamik element ID'leri, değişen class'lar veya DOM'daki hiyerarşik değişiklikler flaky testlere neden olabilir. XPathy, starts_with(), contains_text(), has_attribute() gibi metotlarla bu dinamik değişimlere karşı daha dayanıklı element seçicileri oluşturmayı teşvik eder. Bu sayede testler, küçük UI değişikliklerinden daha az etkilenir.
  • Dinamik İçeriğe Adaptasyon (Adaptability to Dynamic Content): AJAX çağrıları veya JavaScript manipülasyonları ile yüklenen içerik, elementlerin anlık olarak var olup olmadığını etkileyebilir. XPathy, bu tür dinamik içerikleri hedeflemek için daha esnek yöntemler sunar ve testlerin daha güvenilir olmasını sağlar. Örneğin, bir elementin sadece belirli bir metin içerdiğini bilmek yeterliyken, tam metnini bilme zorunluluğunu ortadan kaldırır.
  • Modülerlik (Modularity): Her bir XPathy metodu, XPath ifadesinin belirli bir parçasını temsil eder. Bu modüler yapı, karmaşık seçicilerin daha küçük, yönetilebilir parçalar halinde inşa edilmesini sağlar. Aynı zamanda, belirli element seçici desenlerinin yeniden kullanılabilirliğini artırır.

Bu prensipler, XPathy'nin sadece bir araç olmaktan öte, test otomasyonuna daha stratejik ve verimli bir yaklaşım sunan bir felsefe olduğunu gösterir. Geliştiricilerin "flaky test" sendromundan kurtulmalarına ve gerçekten güvenilir test otomasyonu oluşturmalarına yardımcı olur.

XPathy ile Element Bulma Nasıl Yapılır? Adım Adım Uygulama

XPathy'nin Fluent API'ını kullanarak element bulma süreci oldukça sezgisel ve basittir. Geleneksel XPath'in karmaşıklığından uzaklaşarak, kodunuzu daha okunabilir ve yönetilebilir hale getirebilirsiniz. Şimdi, adım adım XPathy ile nasıl element bulacağımıza dair örnekler üzerinde duracağız. Bu örneklerde, Python için hipotetik bir xpathy kütüphanesi kullanıldığını varsayacağız, ancak buradaki prensipler çoğu dilde benzer Fluent API yaklaşımlarına uyarlanabilir.

İlk olarak, en basit senaryo ile başlayalım: bir etiket adına ve içerdiği metne göre element bulma. Diyelim ki, sayfanızda "Giriş Yap" metnine sahip bir düğme () arıyorsunuz. Geleneksel XPath ile bu //button[contains(text(), 'Giriş Yap')] şeklinde yazılırken, XPathy ile bu işlemi çok daha anlaşılır bir şekilde yapabiliriz:


    from xpathy import XPathy

    # Örnek 1: Sadece metin içeren bir buton bulma
    login_button_xpath = XPathy().button().with_text("Giriş Yap").to_xpath()
    print(f"Giriş Yap butonu XPath'i: {login_button_xpath}")
    # Çıktı: Giriş Yap butonu XPath'i: //button[contains(text(), "Giriş Yap")]
  

Gördüğünüz gibi, kod sanki İngilizce cümle gibi okunuyor: "bir buton bul ve metni 'Giriş Yap' olsun". Bu, hem daha hızlı yazmanızı hem de kodu daha kolay anlamanızı sağlar. Peki ya birden fazla koşulu bir araya getirmek istersek? Örneğin, hem belirli bir class'a sahip hem de belirli bir id'ye sahip bir alanı bulmak isteyebiliriz:


    # Örnek 2: Birden fazla nitelikle input alanı bulma
    username_input_xpath = XPathy()\
        .input()\
        .with_id("username-field")\
        .with_class("form-control")\
        .to_xpath()
    print(f"Kullanıcı adı alanı XPath'i: {username_input_xpath}")
    # Çıktı: Kullanıcı adı alanı XPath'i: //input[@id="username-field" and contains(@class, "form-control")]
  

Burada \ karakteri, uzun bir kod satırını daha okunabilir hale getirmek için kullanılmıştır. XPathy, metotları otomatik olarak and operatörü ile birleştirir, bu da daha spesifik element seçicileri oluşturmanıza olanak tanır. Diyelim ki dinamik bir id'ye sahip bir element var ve id'si "product-" ile başlıyor ve "Detail" metnini içeren bir elementi. Bu durumda starts_with() ve contains_text() metotlarını kullanabiliriz:


    # Örnek 3: Dinamik ID ve kısmi metin ile span bulma
    dynamic_span_xpath = XPathy()\
        .span()\
        .with_id_starts_with("product-")\
        .contains_text("Detail")\
        .to_xpath()
    print(f"Dinamik span XPath'i: {dynamic_span_xpath}")
    # Çıktı: Dinamik span XPath'i: //span[starts-with(@id, "product-") and contains(text(), "Detail")]
  

Bu örnekler, XPathy'nin ne kadar esnek ve güçlü olduğunu göstermektedir. Geleneksel XPath'in karmaşıklığı olmadan, ihtiyaç duyduğunuz her türlü element seçicisini kolayca oluşturabilirsiniz. Özellikle dinamik ve karmaşık UI'lara sahip modern web uygulamalarında, bu tür bir Fluent API yaklaşımı, testlerinizin bakımını kolaylaştıracak ve "flaky test" oranını önemli ölçüde azaltacaktır. Kod bloklarının okunabilirliği, XPath ifadesinin kendisinden çok daha yüksek olduğundan, bir sorun yaşandığında hatayı tespit etmek ve düzeltmek de çok daha kolay hale gelir.

Bu örnekte, XPathy'nin zincirleme metotları ile nasıl anlaşılır bir XPath ifadesi oluşturduğumuzu görüyorsunuz. Geleneksel XPath'e göre ne kadar daha okunaklı ve yönetilebilir olduğu ortada.

Vaka Analizi: Dinamik Bir Tabloda Element Seçimi Nasıl Kolaylaşır?

Dinamik tablolar, web otomasyon testlerinde karşılaşılan en büyük zorluklardan biridir. Sıralama, filtreleme, sayfalama veya AJAX ile güncellenen içerik, elementlerin konumunu sürekli değiştirebilir. Geleneksel XPath ile bu tür tabloları hedeflemek, testlerin sürekli kırılmasına yol açar. Ancak XPathy'nin Fluent API'ı ile bu süreç çok daha sağlam ve yönetilebilir hale gelir. Şimdi bir senaryoyu inceleyelim: Bir ürün yönetim panelindeki dinamik bir tabloda belirli bir ürünün "Düzenle" butonunu bulmak istiyoruz.

Tablo yapısı kabaca şöyle olabilir:


    
Laptop Pro Elektronik 1200 TL
Akıllı Telefon X Elektronik 800 TL

Amacımız, "Akıllı Telefon X" adlı ürünün satırındaki "Düzenle" butonunu bulmak. Geleneksel XPath ile bu biraz zahmetli ve kırılgan olabilir. Örneğin, //tr[./td[contains(text(), 'Akıllı Telefon X')]]/td/button[contains(text(), 'Düzenle')] gibi bir ifade yazmak zorunda kalırız ki bu da okunabilirliği düşürür.

XPathy ile bu işlemi nasıl daha zarif ve sağlam bir şekilde yapabiliriz, inceleyelim:


    from xpathy import XPathy

    # 1. Adım: Belirli bir ürün adına sahip satırı bulma
    product_name_to_find = "Akıllı Telefon X"
    row_containing_product = XPathy().tr().has_child(
        XPathy().td().with_text(product_name_to_find)
    )

    # 2. Adım: Bulunan satırın içindeki "Düzenle" butonunu hedefleme
    edit_button_xpath = row_containing_product.find_child(
        XPathy().button().with_text("Düzenle").with_class("edit-btn")
    ).to_xpath()

    print(f"'{product_name_to_find}' ürününün Düzenle butonu XPath'i: {edit_button_xpath}")
    # Çıktı: //tr[./td[contains(text(), "Akıllı Telefon X")]]//button[contains(text(), "Düzenle") and contains(@class, "edit-btn")]

    # Farklı bir senaryo: Sonraki sayfaya geçiş butonu
    # Sayfalama butonları genellikle 'pagination-next-btn' gibi dinamik ID'lere sahip olabilir.
    next_page_button_xpath = XPathy().button()\
        .with_text("Sonraki")\
        .with_id_starts_with("pagination-")\
        .to_xpath()
    print(f"Sonraki sayfa butonu XPath'i: {next_page_button_xpath}")
    # Çıktı: //button[contains(text(), "Sonraki") and starts-with(@id, "pagination-")]
  

Bu vaka analizinde, XPathy'nin iki önemli özelliğini kullandık:

  1. has_child(): Bir elementin, belirli bir iç elemente sahip olup olmadığını kontrol etmemizi sağlar. Bu, dinamik satırları hedeflemek için çok güçlü bir yöntemdir. Satırın kendisi değişse bile, içerdiği "Akıllı Telefon X" metni sabit kaldığı sürece, doğru satırı bulabiliriz.
  2. find_child(): Belirli bir ebeveyn elementin içinde, istediğimiz child elementi bulmamızı sağlar. Bu, hiyerarşik seçimi çok daha okunabilir kılar.

Bu yaklaşımla, tablonun genel yapısı değişse bile (örneğin, "Elektronik" kolonu başka bir yere taşınsa veya yeni kolonlar eklense bile), testlerimiz "Akıllı Telefon X" metnine ve "Düzenle" butonuna odaklandığı için çok daha sağlam kalır. Geleneksel XPath'in aksine, XPathy ile yazılan bu ifadeler, testlerin kırılganlığını büyük ölçüde azaltır ve test otomasyon projelerinizin sürdürülebilirliğini artırır. Elementlerin görsel veya konumsal değişikliklerinden minimum düzeyde etkilenirken, işlevsel olarak doğru elementi hedeflemeye devam ederiz. Bu, dinamik web sayfalarında güvenilir test otomasyonu için kritik bir adımdır.

XPathy'nin İleri Düzey Özellikleri ve Püf Noktaları Nelerdir?

XPathy'nin Fluent API'ı, temel element seçicilerin ötesinde, daha karmaşık ve özel senaryolar için güçlü özellikler sunar. Bu ileri düzey özellikler, test otomasyon uzmanlarının en zorlu element bulma problemlerini bile çözmelerine yardımcı olurken, kodun okunabilirliğini ve bakımını yine de yüksek tutar. Şimdi bu özelliklerden ve bazı püf noktalarından bahsedelim.

Mantıksal Operatörler: AND ve OR Kullanımı

Geleneksel XPath'te and ve or operatörleri yaygın olarak kullanılır. XPathy de bu mantığı kendi Fluent API'ına entegre eder. Varsayılan olarak, zincirlenmiş metotlar and operatörü ile birleştirilir. Ancak, birden fazla alternatif koşulu denemek istediğinizde or_() metodu devreye girer:


    from xpathy import XPathy

    # Örnek 1: AND operatörü (varsayılan)
    xpath_and = XPathy().div().with_class("product-card").has_attribute("data-id", "123").to_xpath()
    print(f"AND ile XPath: {xpath_and}")
    # Çıktı: //div[contains(@class, "product-card") and @data-id="123"]

    # Örnek 2: OR operatörü
    xpath_or = XPathy().button().with_text("Kaydet").or_().input().with_type("submit").to_xpath()
    print(f"OR ile XPath: {xpath_or}")
    # Çıktı: //button[contains(text(), "Kaydet")] | //input[@type="submit"]
  

Bu, özellikle bir elementin farklı sayfa durumlarında farklı niteliklere sahip olabileceği durumlarda, tek bir sağlam seçici ile birden fazla olasılığı kapsamanıza olanak tanır.

Ebeveyn ve Kardeş Elementlerle İlişkisel Seçim

Elementler arasındaki hiyerarşik ilişkiler, web sayfalarında çok önemlidir. XPathy, parent() ve following_sibling() gibi metotlarla bu ilişkileri kolayca hedeflemenizi sağlar:


    # Örnek 3: Ebeveyn elemente ulaşma
    child_element_selector = XPathy().span().with_text("Ürün Adı")
    parent_element_xpath = child_element_selector.parent().div().with_class("product-detail").to_xpath()
    print(f"Ebeveyn element XPath'i: {parent_element_xpath}")
    # Çıktı: //div[contains(@class, "product-detail") and .//span[contains(text(), "Ürün Adı")]]

    # Örnek 4: Kardeş elemente ulaşma (Örn: bir label'dan sonraki input)
    label_element = XPathy().label().with_text("Şifre:")
    password_input_xpath = label_element.following_sibling().input().with_type("password").to_xpath()
    print(f"Şifre input alanı XPath'i: {password_input_xpath}")
    # Çıktı: //label[contains(text(), "Şifre:")]/following-sibling::input[@type="password"]
  

Bu ilişkisel seçiciler, DOM yapısı kısmen değişse bile elementleri güvenilir bir şekilde bulmanıza yardımcı olur, çünkü göreceli konumlar genellikle mutlak konumlardan daha stabildir.

Custom XPath Ekleme

Bazı durumlarda, XPathy'nin sunduğu metotlar mevcut ihtiyacınızı tam olarak karşılamayabilir veya çok özel bir XPath ifadesi yazmanız gerekebilir. XPathy, bu gibi durumlar için esneklik sunar:


    # Örnek 5: Custom XPath ekleme
    custom_xpath_part = "[position()=last()]" # Son elementi seç
    last_item_xpath = XPathy().li().with_class("item").append_xpath(custom_xpath_part).to_xpath()
    print(f"Son öğe XPath'i: {last_item_xpath}")
    # Çıktı: //li[contains(@class, "item")][position()=last()]
  

Bu özellik, XPathy'nin Fluent API'ının gücünden faydalanırken, gerektiğinde tam kontrolü elinizde tutmanızı sağlar.

Performans İpuçları

  • Mümkünse ID Kullanın: ID'ler genellikle en hızlı ve en sağlam element seçicilerdir. Eğer bir elementin benzersiz bir ID'si varsa, XPathy'nin with_id() metodunu tercih edin.
  • Gereksiz Derinlikten Kaçının: XPath ifadeleri ne kadar kısa ve hedefe yönelik olursa, o kadar hızlı çalışır. // (herhangi bir alt düğüm) yerine / (doğrudan alt düğüm) kullanmak performansı artırabilir. XPathy, mümkün olduğunca optimize XPath'ler üretmeye çalışır.
  • Sınırlayıcı Kullanın: Büyük tablolarda veya listelerde arama yaparken, aramayı belirli bir ebeveyn elementle sınırlamak (örneğin, XPathy().div().with_id("main-content").find_child(XPathy().button()...) gibi) tarayıcının arama alanını daraltır ve performansı artırır.

Bu ileri düzey özellikler ve püf noktaları, XPathy'nin sadece yeni başlayanlar için değil, deneyimli otomasyon mühendisleri için de güçlü bir araç olduğunu göstermektedir. Kodun okunabilirliğini ve sürdürülebilirliğini artırırken, karmaşık senaryolarda bile sağlam ve güvenilir element seçiciler oluşturmanıza olanak tanır.

Mobil Uyumlu Testler İçin XPathy Nasıl Kullanılır?

Mobil uyumlu (responsive) web tasarımları, farklı ekran boyutlarında ve cihazlarda elementlerin konumunu, boyutunu ve hatta görünürlüğünü değiştirebilir. Bu durum, mobil test otomasyonunda geleneksel XPath'in kırılganlığını daha da artırır. Ancak XPathy'nin sağladığı esneklik ve dinamik element hedefleme yetenekleri, mobil uyumlu testler için de güçlü bir çözüm sunar.

Mobil uyumlu testlerde karşılaşabileceğiniz senaryolar şunlardır:

  1. Farklı Cihazlarda Değişen Konumlar: Bir buton masaüstünde sağ üst köşede iken, mobilde sayfanın altına taşınabilir. Mutlak XPath'ler bu durumda anında kırılır.
  2. Elementlerin Gizlenmesi/Gösterilmesi: Masaüstünde görünen bir menü, mobil görünümde gizlenip bir hamburger menü ikonu ile tetiklenebilir.
  3. Sınıfların veya Niteliklerin Değişmesi: CSS media query'leri, elementlere farklı ekran boyutlarında farklı class'lar uygulayabilir.

XPathy, bu tür durumlarda daha semantik ve nitelik tabanlı seçiciler oluşturarak testlerinizi daha sağlam hale getirir. Örneğin:

  • Metin veya Niteliklere Odaklanın: Konum yerine, elementin içerdiği metin veya benzersiz nitelikleri (data-test-id, aria-label gibi) hedefleyin. Örneğin, XPathy().button().with_text("Menü"), menü butonunun ekran üzerindeki konumundan bağımsız olarak çalışacaktır.
  • Görünürlük Kontrolü: Testlerinizde, bir elementin gerçekten görünür olup olmadığını kontrol etmek için otomasyon kütüphanenizin (Selenium, Playwright vb.) sağladığı metotları kullanın. XPathy, elementi bulur; görünürlük kontrolü otomasyon aracınızın işidir.
  • Dinamik Sınıfları Yönetme: Eğer bir element mobil görünümde farklı bir sınıfa sahip oluyorsa, contains_class() veya or_() operatörü ile birden fazla olasılığı hedefleyebilirsiniz:

    # Mobil veya masaüstü menü butonu
    menu_button = XPathy().button()\
        .with_class("mobile-menu-icon")\
        .or_()\
        .button().with_id("desktop-menu-toggle")\
        .to_xpath()
    print(f"Mobil/Masaüstü Menü Butonu XPath'i: {menu_button}")
    # Çıktı: //button[contains(@class, "mobile-menu-icon")] | //button[@id="desktop-menu-toggle"]
    

Responsive tasarım, CSS Media Query'leri ile yönetilir. İşte tipik bir örnek:


    /* Masaüstü menüsü varsayılan olarak görünür */
    .desktop-menu {
      display: flex;
    }
    .mobile-menu-icon {
      display: none; /* Masaüstünde gizli */
    }

    @media (max-width: 768px) { /* Tablet ve altı ekranlar için */
      .desktop-menu {
        display: none; /* Masaüstü menüsü gizlenir */
      }
      .mobile-menu-icon {
        display: block; /* Mobil menü ikonu görünür */
      }
      .product-grid {
        grid-template-columns: 1fr; /* Ürünler tek sütuna düşer */
      }
    }
  

Bu tür durumlarda, XPathy'yi kullanarak elementin o anki görünümdeki mevcut niteliklerine göre seçim yapabiliriz. Örneğin, mobil görünümde tek sütun haline gelen bir ürün listesindeki her bir

elementini yine XPathy().div().with_class("product-item") ile hedefleyebiliriz, çünkü class adı değişmiyor. Elementlerin hiyerarşisi değişse bile, XPathy'nin has_child() veya find_child() gibi ilişkisel metotları, bu değişikliklere daha dayanıklı seçiciler oluşturmamızı sağlar. Mobil uyumlu testlerde başarılı olmak için, elementlerin sadece konumuna değil, aynı zamanda işlevsel rolüne ve benzersiz niteliklerine odaklanmak hayati önem taşır. XPathy tam da bu esnekliği ve gücü sağlayarak mobil testlerinizin güvenilirliğini artırır.

Sonuç: Flaky Testlere Veda Edin ve Testlerinizi Güçlendirin

Web otomasyon testleri, modern yazılım geliştirme süreçlerinin vazgeçilmez bir parçasıdır. Ancak, geleneksel XPath'in inherent kırılganlığı ve dinamik web sayfalarının getirdiği zorluklar, "flaky test" sorununu beraberinde getirerek otomasyon yatırımlarının verimini düşürmüştür. Bu makalede ele aldığımız XPathy'nin Fluent API yaklaşımı, bu kronik soruna etkili ve sürdürülebilir bir çözüm sunmaktadır. Geleneksel XPath'in okunabilirlik, bakım zorluğu ve dinamik içerik karşısındaki zayıflıkları, test otomasyon mühendislerini yıllardır yoran başlıca problemler olmuştur.

XPathy, bu sorunlara karşı adeta bir kalkan görevi görerek, XPath ifadelerini daha sezgisel, doğal dil benzeri bir yapıya dönüştürür. Fluent API sayesinde, "içinde 'Kaydet' yazan bir buton bul" gibi düşündüğümüz şekilde kod yazabiliriz. Bu sadece kodun daha kolay okunmasını sağlamakla kalmaz, aynı zamanda bakım maliyetlerini de önemli ölçüde azaltır. Bir UI değişikliği olduğunda, tüm XPath ifadesini baştan yazmak yerine, XPathy'nin modüler yapısı sayesinde sadece ilgili metodu güncellemek genellikle yeterli olur. Bu hız ve esneklik, geliştirme döngülerinizin daha akıcı olmasına ve testlerinizi güncel tutma çabalarınızın azalmasına olanak tanır.

Vaka analizlerimiz ve ileri düzey örneklerimizle gösterdiğimiz gibi, XPathy dinamik tablolardan mobil uyumlu testlere kadar geniş bir yelpazedeki zorlu senaryolarda güvenilir element seçiciler oluşturmanıza yardımcı olur. has_child(), parent(), or_() gibi metotlar, karmaşık ilişkileri ve birden fazla olasılığı tek bir sağlam ifadeyle ele almanızı sağlar. Bu, testlerinizin küçük UI değişikliklerinden etkilenmesini minimuma indirir ve böylece "flaky test" oranını dramatik bir şekilde düşürür. Güvenilir testler, geliştirme ekiplerinin yazılıma olan güvenini artırır, hızlı geri bildirim sağlar ve gerçek hatalara odaklanmalarına olanak tanır.

Sonuç olarak, "Raw XPath is Dead" ifadesi, geleneksel yaklaşımların artık günümüzün dinamik web ortamında yetersiz kaldığını vurgulayan bir gerçeği işaret ediyor. XPathy gibi Fluent API'lar ise bu yeni dönemin gerektirdiği sağlamlığı, okunabilirliği ve sürdürülebilirliği sunarak test otomasyonunun geleceğini şekillendiriyor. Testlerinizi güçlendirmek, geliştirme süreçlerinizi hızlandırmak ve "flaky test" çilesine son vermek istiyorsanız, XPathy'nin Fluent API yaklaşımını benimsemek, atabileceğiniz en akıllıca adımlardan biridir. Bu sayede, test otomasyonu yatırımlarınızın karşılığını fazlasıyla alacak ve daha kaliteli yazılımlar ortaya koyacaksınız.

Sıkça Sorulan Sorular

XPathy sadece Python için mi geçerli?
Hayır, Fluent API konsepti birçok dilde (Java, C#, JavaScript, Ruby vb.) uygulanabilir. XPathy adında spesifik bir kütüphane Python için bu makalede örnek olarak kullanılmış olsa da, bu yaklaşım farklı dillerde de benzer kütüphanelerle veya kendi implementasyonlarınızla kullanılabilir. Önemli olan, Fluent API tasarım desenini benimseyen bir araç veya yaklaşımdır.
XPathy kullanmak performans düşüşüne neden olur mu?
Doğru kullanıldığında performans düşüşüne neden olmaz. XPathy, okunabilirliği artırırken, arka planda standart ve optimize edilmiş XPath ifadeleri üretir. Asıl performans, üretilen XPath'in tarayıcı tarafından nasıl işlendiğine ve elementin DOM'daki karmaşıklığına bağlıdır. Genellikle iyi yazılmış XPath'ler yeterince hızlıdır. XPathy'nin amacı, iyi XPath'ler yazma sürecini kolaylaştırmaktır.
Hangi web otomasyon araçlarıyla entegre edilebilir?
XPathy, Selenium WebDriver, Playwright, Puppeteer gibi XPath destekleyen tüm popüler web otomasyon araçlarıyla kolayca entegre edilebilir. Ürettiği XPath ifadesini doğrudan bu araçların find_element_by_xpath() veya benzeri metotlarına (örneğin, Selenium'da driver.find_element(By.XPATH, xpathy_expression) şeklinde) geçirebilirsiniz. Bu, XPathy'nin otomasyon ekosistemindeki esnekliğini artırır.
Dinamik id'ler veya class'lar için nasıl bir çözüm sunuyor?
XPathy, dinamik ID'ler ve Class'lar gibi değişken element niteliklerini yönetmek için güçlü metotlar sunar. starts_with(), contains() gibi XPath fonksiyonlarını temel alan with_id_starts_with(), contains_text(), with_class_contains() gibi metotlarla, elementin değişen kısımlarını göz ardı ederek sabit kısımlarını hedefleyebilirsiniz. Bu sayede, elementler dinamik olarak güncellense bile testleriniz sağlamlığını korur.
Karmaşık XPath'lerden XPathy ifadelerine geçiş zor mu?
Başlangıçta bazı mevcut karmaşık XPath'leri dönüştürmek biraz çaba gerektirse de, XPathy'nin Fluent API'ının sezgisel yapısı sayesinde bu süreç oldukça kolaylaşır. Birkaç örnek üzerinde pratik yaptıktan sonra, eski XPath'leri yeni, daha okunabilir ve sağlam XPathy ifadelerine çevirmek doğal bir alışkanlık haline gelecektir. Ayrıca, yeni testler yazarken XPathy ile başlamak, projenizin baştan itibaren daha sürdürülebilir olmasını sağlar.

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Gönder

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.