Tüm yazılar
test-automation

TestFly Part 14: Adım İzleri — Görsel Hata Ayıklama İçin Adım Başına ARIA/DOM Snapshot'ları

TestFly 1.1.0, trace'e adım başına snapshot ekliyor: her adım başladığı andaki erişilebilirlik ağacını (ya da budanmış DOM'u) kaydediyor, başarısız bir test son adımından sonraki sayfayı da bir diff ile yakalıyor ve artık Cucumber senaryoları da trace alıyor.

12 Ekim 20266 dk okuma
TestFly Part 14: Adım İzleri — Görsel Hata Ayıklama İçin Adım Başına ARIA/DOM Snapshot'ları

TestFly Part 14: Adım İzleri — Görsel Hata Ayıklama İçin Adım Başına ARIA/DOM Snapshot'ları

Özet: TestFly 1.1.0, trace'e adım başına snapshot ekliyor: artık her adım, başladığı andaki erişilebilirlik ağacını (ya da dom/both ile sayfanın budanmış HTML'ini) kaydediyor, başarısız bir test ise son adımından sonraki sayfayı da kaydedip öncesiyle bir diff gösteriyor. Yeni config anahtarları tracing.snapshots, tracing.snapshotMaxKb ve tracing.snapshotOnFailureAfter neyin yakalanacağını belirliyor, StepRecord yeni alanları taşıyor, TraceRecorder.saveIfEnabled trace'i yazıyor — artık yalnızca TestNG ve JUnit 5'ten değil, Cucumber'dan da; HTML rapor da her testten trace'e doğrudan bağlantı veriyor.

Adım İzi Nedir, Her Adımı Neden Snapshot'lıyoruz?

Bir trace, bir testin adım zaman çizelgesini yeniden oynatan tek bir bağımsız HTML dosyasıdır — target/traces/{SınıfAdı}/{testMetodu}-trace.html. Adım isimleri, zaman damgaları, ekran görüntüleri, hatanın anındaki son ekran görüntüsü, hata mesajı ve stack trace, kayıt açıksa video — hepsi burada. Tek dosyayı herhangi bir tarayıcıda açarsın; sunucuya ihtiyaç yok.

Ekran görüntüleri sayfanın nasıl göründüğünü gösterir. DOM'da gerçekte ne olduğunu göstermez — bir buton devre dışı mıydı, bir elementte aria-hidden var mıydı, beklediğin markup orada mıydı. Adım başına snapshot'ların kapattığı boşluk tam da bu: her adımın ekran görüntüsünün yanında, trace artık StepSnapshotCapture'ın adım başladığı anda gördüğü sayfanın metin snapshot'ını da gömüyor.

yaml
# testfly.yml
tracing:
  enabled: true

Tracing açıkken, her adım varsayılan olarak bir snapshot alır — teste ek kod gerekmez.

Her Adımın Snapshot'ı Ne İçeriyor?

Yakalama, adım başına bir kez çağrılan StepSnapshotCapture.captureForStep() tarafından yönetiliyor. tracing.enabled'i kontrol ediyor, tracing.snapshots modunu okuyor ve yalnızca gerçekten canlı bir driver oturumu varsa tarayıcıya dokunuyor — API ve veritabanı testleri, ya da tarayıcı oluşmadan önce loglanan adımlar, hiç snapshot almıyor:

java
// StepSnapshotCapture.java (sadeleştirilmiş)
public static Snapshots captureForStep() {
    TestFlyConfig.Tracing tracing = tracing();
    if (tracing == null || !tracing.isEnabled()) {
        return Snapshots.NONE;
    }
    String mode = tracing.getSnapshots();
    boolean aria = mode.equals("aria") || mode.equals("both");
    boolean dom  = mode.equals("dom")  || mode.equals("both");
    WebDriver driver = liveDriver();
    if (driver == null) {
        return Snapshots.NONE;
    }
    int maxKb = tracing.getSnapshotMaxKb();
    return new Snapshots(aria ? captureAria(driver, maxKb) : null,
                          dom  ? captureDom(driver, maxKb)  : null);
}

Zaten bir adımın adını, zaman damgasını, durumunu ve ekran görüntüsünü tutan StepRecord, iki yeni alan artı bir tane daha aldı; o da yalnızca başarısız bir test için sonradan doldurulan son durum:

java
// StepRecord.java
public StepRecord(String name, long offsetMs, String status, String screenshotBase64,
                   String ariaSnapshot, String domSnapshot) { ... }

public String getAriaSnapshot()      { return ariaSnapshot; }
public String getDomSnapshot()       { return domSnapshot; }
public String getAfterAriaSnapshot() { return afterAriaSnapshot; } // yalnızca başarısızlıkta

aria, ariaSnapshot()'ın yazdırdığı aynı YAML metnini yakalıyor — küçük, okunabilir, CSS sınıfı değişikliklerinden etkilenmiyor. dom, DomPruner tarafından script'lerden, stillerden ve dekorasyondan budanmış sayfa HTML'ini yakalıyor; daha büyük ama erişilebilirlik ağacının göstermediği markup'ı gösteriyor — örneğin hata ayıkladığın bir CSS sınıfını.

Neyin Yakalanacağını Nasıl Yapılandırırsın?

yaml
# testfly.yml
tracing:
  enabled: true
  snapshots: both             # none | aria | dom | both — varsayılan: aria
  snapshotMaxKb: 256           # adım başına tutulan en uzun snapshot, KB — varsayılan: 256
  snapshotOnFailureAfter: true # başarısız testin son adımından sonraki sayfayı da yakala

TestFlyConfig, tracing.snapshots'ı erken doğrular — none, aria, dom veya both dışında bir değer, çalışma sırasında değil config yüklenirken IllegalArgumentException fırlatır. snapshotMaxKb'den uzun bir snapshot kesilir ve … truncated (N more characters) ile biter, böylece tek bir ayrıntılı sayfa tüm trace dosyasını şişirmez.

Trace HTML'i Gerçekte Ne Gösteriyor?

Zaman çizelgesinde bir adıma tıkla, ekran görüntüsü paneli sekmelerle açılır: ARIA (before step), DOM (before step), ve — yalnızca başarısız bir testin son adımında — ARIA (after failure) ve hesaplanmış bir Diff sekmesi. Diff, öncesi ve sonrası YAML'ları arasında satır bazlı bir küme farkı; trace'in kendi gömülü JavaScript'inde (TraceRecorder'daki lineDiff()) istemci tarafında hesaplanır: yalnızca "öncesi"nde olan satırlar - ile, yalnızca "sonrası"nda olanlar + ile işaretlenir. Harici bir diff kütüphanesi yok, ağ çağrısı yok — trace, e-postayla gönderebileceğin ya da Slack'e bırakabileceğin tek bir dosya olarak kalıyor.

Zaman çizelgesindeki adım blokları da snapshot taşıdıklarında küçük bir 🌳 işareti alır, ekran görüntüsü için 📷 işaretinin yanında — hangi adımların tıklanacak bir şeye sahip olduğunu bir bakışta görürsün.

Bu Testlerimi Yavaşlatır ya da Başarısız Olma Riski Taşır Mı?

Bir snapshot almak adım başına bir script çağrısı — tipik bir sayfada birkaç milisaniye — ve yalnızca tracing.enabled açıkken çalışır. StepSnapshotCapture, her yakalamayı başarısızlıkta hata fırlatmak yerine null döndüren bir try/catch'e sarıyor: okunamayan bir sayfa, kapanmış bir driver ya da kararsız bir script çağrısı testi asla başarısız kılmaz, yalnızca o adımı snapshot'sız bırakır. TraceRecorder.saveIfEnabled'ın kendisi de aynı şekilde sarmalanmış:

java
// TraceRecorder.java
@TestFlyApi(since = "1.1.0")
public static void saveIfEnabled(String testId, String testName, boolean isPassing) {
    try {
        TestFlyConfig.Tracing tracing = TestFlyContext.getConfig().getTracing();
        if (tracing == null || !tracing.isEnabled()) return;
        if (isPassing && !tracing.isCaptureOnPass()) return;
        save(testId, testName);
    } catch (Exception ignored) {
    }
}

Bu Cucumber İle Çalışıyor Mu?

Evet — 1.1.0 itibarıyla CucumberHooks, TestNG ve JUnit 5'in kullandığı aynı trace mekanizmasını çağırıyor, bu yüzden Gherkin senaryoları da snapshot'lar dahil bir trace dosyası alıyor; feature dosyalarında ya da step definition'larda hiçbir değişiklik gerekmiyor. HTML test raporu da artık her testin detay panelinden doğrudan kendi trace'ine bağlantı veriyor, yani raporda kırmızı bir satırdan, neyin yanlış gittiğini gösteren tam adıma ve snapshot'a tek tıkla gidiyorsun.

SSS

Adım başına snapshot almak için testlerime kod eklemem gerekiyor mu?

Hayır. tracing.enabled: true ile, her adım tracing.snapshots'a göre (varsayılan aria) otomatik olarak bir snapshot alır. Adım başına çağrılacak bir API yok.

Tarayıcısı olmayan bir testte, örneğin bir API testinde ne olur?

Hiçbir şey yakalanmaz. StepSnapshotCapture, snapshot almadan önce canlı bir WebDriver oturumu olup olmadığını kontrol eder ve yoksa snapshot almadan geçer — yalnızca bir tane yakalamak için asla bir driver oluşturmaz ya da yeniden oluşturmaz.

Bir snapshot yakalama hatası testimi başarısız kılabilir mi?

Hayır. Her yakalama yolu, bir istisnanın yutulup FINE seviyesinde loglandığı, asla yeniden fırlatılmadığı şekilde sarmalanmıştır. Bir snapshot en iyi çaba ilkesiyle alınır; geçti/kaldı sonucunu hiçbir zaman etkilemez.

Diff sekmesi erişilebilirlik ağacının gerçek bir yapısal farkı mı?

Hayır — "öncesi" ve "sonrası" ARIA YAML metni arasında, trace'in kendi gömülü JavaScript'inde hesaplanan satır bazlı bir küme farkıdır. Neyin ortaya çıktığını ya da kaybolduğunu görmek için yeterlidir, anlamsal bir ağaç farkı değildir.

#TestFly#Selenium#Java#SDET#Debugging
Paylaş X LinkedIn

Yorumlar

  • Henüz yorum yok. İlk yorumu sen yaz.