Test ortamı

Test nedir? bölümünde açıklandığı gibi, JavaScript'teki testler temelde yalnızca Error işlevi görmeden başarıyla çalıştığını teyit ettiğimiz koddur. Ancak bu tanımın fazla basitleştirilmesinin nedenlerinden biri, kodu nerede çalıştırdığımızı, yani test ortamını dikkate almamasıdır.

Test ortamı genel olarak iki bileşen olarak düşünülebilir: testinizi çalıştırmak için kullandığınız çalışma zamanı ortamı (Düğüm veya tarayıcı gibi) ve kullanabileceğiniz API'ler.

Çalışma zamanı ortamı

Node gibi çalışma zamanlarının veya Deno ya da Bun gibi benzer araçların sunucu tarafında ya da genel amaçlı JS kodlarını desteklemesi amaçlanır. Ortamları, DOM ve HTML öğeleri oluşturup bunlarla çalışma gibi bir tarayıcıda bekleyebileceğiniz API'leri veya görsel bileşen ya da oluşturma hedefi kavramlarını (yani sadece öğeleri değil, bu öğeleri CSS ile görsel olarak bir görüntü alanına oluşturmak) içermez.

Bu nedenle, örneğin document veya window nesnesi olmadığından test edilebilmeleri için React öğelerini oluşturmayı denerseniz bu genel amaçlı çalışma zamanları başarısız olur.

Öte yandan, testlerinizi bir tarayıcıda çalıştırırsanız bu çalışma zamanlarından bekleyebileceğiniz yerleşik API'ler, çoklu doldurma veya bazı ekstra çalışma olmadan kullanılamayabilir. Yaygın bir durum, dosya okuma ve yazma gibi bir şeydir: Bir tarayıcı içinde import { fs } from 'node:'fs'; ve bir test kapsamında dosyayı bu şekilde okumak mümkün değildir.

Bu "web" ve "arka uç" API sorunu, hem sunucu hem de istemci parçaları içeren bir kod tabanına sahip olmak kulağa hoş gelmeyebildiğinden, ama bu kurs boyunca tekrar değineceğimiz test edilebilir kod yazma fikriyle bağlantılı olduğundan, bu durum yalnızca test kapsamının dışında kalıyor.

Algoritmayı veya iş mantığını test edin

Bazı kodlarınızın çalışması, dolayısıyla test için Düğüm veya tarayıcı içe aktarması gerekmez. Bu konuya bu kursun ilerleyen bölümlerinde değineceğiz. Ancak kod tabanınızı sadece "iş mantığı"nı, oluşturma işleminden veya Düğüme özgü koddan ayrı olacak şekilde yapılandırmak test yapmayı kolaylaştırabilir.

Hızlı bir örnek vermek gerekirse diskten bir dosyayı okuyup yazan ve işlem sırasında dosyayı değiştiren bir Düğüm işleviniz olabilir. İşlevinizi, diskten okuma ve yazma işlevini gerçekleştiren işlevleri kabul edecek şekilde yeniden düzenleyerek, her yerde test edilebilir hale getirdiniz.

Bu durumda, bu kodu test etmek için sunucu tarafı çalışma zamanı veya tarayıcıda herhangi bir ortamı kullanabilirsiniz. Testinizde, sanal bir dosyayı bellekte depolayan veya yer tutucu verileri döndüren yardımcılar sağlayabilirsiniz. Bu tür bir yardımcının bir teste dahil edilmesinde bir sakınca yoktur, örneğin, fs.writeFileSync hizmetinin çalışıp çalışmadığını kontrol etmek önemli değildir. Kodunuza ve onu benzersiz veya riskli kılan unsurlara odaklanın.

Tarayıcı API'leri emülasyonu

Vitest gibi birçok test çerçevesi, size tarayıcıyı çalıştırmadan tarayıcının API ortamını emüle etme seçeneği sunar. Vitest, dahili olarak JSDOM adlı bir kitaplık kullanır. Bu, tarayıcı kullanmanın ek yükünün yüksek olduğu basit bileşen testleri için iyi bir seçim olabilir.

Tüm emülasyon kitaplıklarının ortak özelliği, bir tarayıcıyı (örneğin, DOM, öğeler ve çerezler) emüle edebilse de, görsel bileşenlerinin olmamasıdır. Bu, HTML öğeleri ve diğer temel öğelerle çalışmak için zorunlu bir yöntem sağlayacakları anlamına gelir; ancak bir resim veya ekran için çıktıyı oluşturamaz ya da bir öğenin sayfada piksel cinsinden konumunu kontrol edemezsiniz.

Yine bu seçim, bir bileşenin bir React öğesini, bir Web Bileşeni'ni veya benzeri öğeleri temsil ettiği bileşen testi için çok uygun olabilir. Bu tür bileşenler, genellikle DOM'u nispeten küçük bir şekilde oluşturur ve bununla etkileşim kurar. Öykünülmüş bir tarayıcı, bileşenin istediğiniz gibi çalıştığını onaylamak için yeterli işlevselliği sağlayabilir. Sonraki bölümde Vitest ve JSDOM ile bir React bileşen testi örneği yer almaktadır.

Tarayıcı öykünmesi, köklü bir uygulamadır (JSDOM 2014'te kullanıma sunulmuştur) ancak gerçek bir tarayıcı kullanmaktan her zaman farklı olacaktır. Bu farklılıklar açıkça görülebilir: Örneğin, JSDOM bir düzen motoru içermez. Bu nedenle, bir öğenin boyutunu kontrol etmenin veya kaydırma gibi karmaşık bir hareketi test etmenin bir yolu yoktur. Farklılıklar önemli ve bilinmeyen de olabilir. Bu nedenle, JSDOM tabanlı testlerinizi kısa ve öz tutmak en iyisidir. Böylece, herhangi bir davranışın gerçek testten sapma riskini "zaman sınırı" tutabilirsiniz.

Gerçek bir tarayıcıyı kontrol edin

Kodunuzu kullanıcılarınızın yaşayacağı şekilde test etmek için gerçek bir tarayıcı kullanmak en iyi seçenektir. Pratikte, tarayıcıyı destekleyen çalışma zamanları, Node.js içinde "start" çalıştırılsa bile gerçek bir tarayıcının örneklerini başlatır ve kontrol eder.

Bir testin parçası olarak bir tarayıcıyı kontrol etmek, tarayıcının tıpkı kullanıcı için açılır gibi açılması anlamına gelir. Böylece, URL'ler, özel HTML, JS veya testinizi gerçekleştirmek için gereken her şeyi yükleyerek testinizin tarayıcıyı kontrol etmesine olanak tanır. Ardından, fareyi kontrol ederek veya giriş kutularına giriş yazarak kullanıcı gibi davranmak için kod yazabilirsiniz.

WebdriverIO veya Web Test Runner gibi modern araçlar, yaygın olarak kullanılan tüm tarayıcıları kontrol edebilir, hatta aynı anda birden fazla örneği çalıştırabilir. Bu tarayıcılar, test çalıştırıcının yanında çalışabilir (örneğin, kendi bilgisayarınızda veya bir CI işleminin parçası olarak) veya bunları sizin için çalıştıracak harici ticari hizmetlerden destek alınabilir.

Daha köklü test kitaplıkları (Vitest ve Jest dahil) genellikle tarayıcı moduna sahiptir, ancak kaynakları Node.js'den geldiği için tarayıcı modları genellikle "sürdürülebilir" ve kullanışlı özelliklere sahip değildir. Örneğin Vitest, bir sonraki sayfadaki örnekte kullandığımız güçlü bir temel öğe olan tarayıcıda modül içe aktarma işlemi yapamaz.

Uygulamada

Testlerinizin karmaşıklığı arttıkça, gerçek bir tarayıcı kullanmak giderek daha önemli hale gelir.

  • DOM'de hiçbir özellik kullanmayan veya çok az özellik kullanan testlerde, Node.js'de ve fetch ya da EventTarget gibi benzer çalışma zamanlarında bulunan özelliklerde bile ortam önemli değildir.
  • Küçük bileşen testleri için JSDOM uygun olabilir.
  • Bir kullanıcının giriş yapmasını ve temel bir işlemi gerçekleştirmesini simüle edebilen daha büyük testler (ör. uçtan uca testler) tamamen gerçek bir tarayıcıda çalıştırmak mantıklıdır.

Bu bölüm yoğun bir teorik bilgiler içeriyor ve testlerinizi nerede yapacağınızla ilgili farklı bakış açıları sunuyor. Pratikte kod tabanınız, genellikle ihtiyaçlarınıza ve test araçlarının sağladıklarına bağlı olarak farklı test türleri için birçok farklı yaklaşım kullanır.

Öğrendiklerinizi sınayın

Emülasyon katmanı jsdom'u, tarayıcının hangi özelliklerini *desteklemiyor*?

Düzen motoru.
JSDOM görsel bir araç olmadığından bir öğenin sayfadaki konumunu, çözümlenmiş CSS özelliklerini veya web sitesi düzeninin diğer bölümlerini kontrol etmek için kullanılamaz.
WebSocket
JSDOM, WebSocket çoklu dolgusunu içerdiğinden, bunu kullanan kod çalışır.
requestAnimationFrame
"pretendToBeVisual" işaretiyle, jsdom, gerçekte hiçbir şey çizilmemiş olsa bile 60 fps'de "animasyon" geri çağırmasını çağırır.