Modern web uygulamalarını test etmek zor olabilir. Testlerin birçok çeşidi vardır - birim, entegrasyon, kabul, uçtan uca - ve hangilerinin kullanılacağını bilmek zor olabilir. Bu makale, web uygulamalarımı birim ve entegrasyon testlerini kullanarak test etmek için kullandığım kalıpları ele alacaktır. Entegrasyon testleri, gerçek bir kullanıcının uygulama içindeki yolculuğunu yakından simüle edecek, ancak harici sistemlere bağımlılığı olmayacak.
Bu, testlerin hızlı çalışacağı ve uçtan-uca testlere göre daha az kırılgan olacağı, ancak aynı zamanda uygulamanızın doğru çalıştığına dair yüksek düzeyde güven sağlayacağı anlamına gelir. Bu testlerde kullanılan desenler çok esnektir ve testlerinizin kodunuzun uygulama detaylarından ayrılmasına izin verir. Bu, kodunuzu "yanlış negatif" oluşturmadan yeniden düzenleyebileceğiniz anlamına gelir; burada kod doğrudur, ancak test ile kodun nasıl uygulandığı arasındaki sıkı bağlantı nedeniyle test başarısız olur.
Önemli: Bu makale, üst düzey kalıpları ve test stratejilerini ele alacaktır. Test yazma konusunda adım adım bir kılavuz olmayacaktır. Örnekler, Jest , Testing Library , jest-fetch-mock ve daha fazlası gibi kütüphaneleri kullanacak , ancak ben sadece ilgili parçalardan bahsedeceğim ve her bir kütüphanenin ayrıntılarını dokümanlara bırakacağım.
Başlangıç olarak, web uygulamamız için bir kullanıcı kimlik doğrulama akışı oluşturduğumuzu varsayalım. Bu, kullanıcıya kullanıcının e-postası için ilk ekranda bir giriş alanı göstermeyi içerir. Kullanıcının e-postasının sistemimizde var olduğunu tespit edersek, onlara bir şifre giriş alanı gösteririz. Değilse, onlara bir katılma formu gösteriyoruz. Kullanıcı,
/lookupgörünümü başlatacak ve ardından bir hesabı olup olmamasına bağlı olarak
/joinveya
/challengegörünümünde sona erecektir .
Bu bize, hem birim hem de entegrasyon testlerinden hala yararlanabilecek oldukça basit bir kullanıcı deneyimi sağlar. Bazı uygulama ayrıntılarını dışarıda bırakacağız (UI gibi) ve beklendiği gibi çalıştığından emin olmak için bu uygulamayı nasıl etkili bir şekilde test edeceğimize odaklanacağız.
Başlamak için, sistemimizdeki bir kullanıcıyı e-posta adresiyle aramak için bir API çağrısı yapmamız gerekeceğini biliyoruz. Bu API çağrısının bizim için yapılmasını sağlayacak temel bir modül yapalım.
Dosyayı şuraya koyalım
src/app/api/lookup/index.ts. Şunun gibi görünebilir:
Görünüşe göre, gelen
Httpnesne,
@core/httpuygulamamız için ortak HTTP mantığını işleyen bir yardımcı program sınıfıdır. Temel API etki alanını ortam değişkenlerine göre ayarlamak, ortak HTTP başlıklarını ayarlamak, yanıtı ayrıştırmak, analitik olayları tetiklemek vb. Gibi şeyler.
Konu alay konusu olduğunda, genellikle test ettiğiniz şeyin "ucunda" alay etmek en iyisidir. Bir web uygulaması için bu, bir kod modülüyle dalga geçmek yerine gerçek HTTP istekleriyle dalga geçebileceğiniz anlamına gelir. Bunu yapmazsanız, alay modüllerinin ne kadar kırılgan olabileceğini şahsen onaylayabilirim. J est modül alaycılığı gibi bir şey kullanarak büyük, karmaşık testler oluşturdum . Sonra kullanılmış bir işbirliği doğrulama assert temelde için test tarzını “mü
moduleAçağrıyı
moduleB doğru argümanlarla?”.
Kartlardan bir ev inşa etmek gibiydi. Uygulama işlevselliğini doğrulamak yerine, testler kodun nasıl yapılandırıldığını iddia ediyordu. Bu, hayal edebileceğiniz en yararsız, sıkı sıkıya bağlı testlerden bazılarına yol açar. En ufak bir kod değişikliği, testlerin yanlış negatifleri tetiklemeye başlamasına neden olabilir.
Ana fikir, kodun nasıl yapılandırıldığını test etmek istediğimiz şey olmadığıdır. Günün sonunda uygulamanın düzgün çalışmasına özen gösteriyoruz. Bu, bir HTTP isteğinin doğru biçimde gönderilmesini beklediğimiz ve uygulamamızın geri gelebilecek tüm çeşitli yanıtları doğru şekilde işlediği anlamına gelir.
HTTP isteğinin kendisiyle alay ederek, temel alınan kod, başarısız olmaması gereken testlerde başarısız olmadan yeniden düzenlenmekte serbesttir. Alaycı HTTP isteklerine nasıl yaklaştığımıza bakarak bu modülün birim testini nasıl yazacağımıza bakalım.
Testlerde HTTP çağrılarını taklit etmek çok yaygın bir modeldir. Ancak, bunu dağınık ve hatalara yatkın bir şekilde yapmak kolaydır.
Uygulamanız büyüdükçe, aynı API çağrısını kodunuzun farklı yerlerinden yapma şansınız yüksektir. HTTP modelini ayrı test paketlerinde yeniden tanımlarsanız, hata olasılığını artırırsınız.
Örneğin, API yanıtı değiştiğinde ne olur? Bu yanıtı alay eden her testi güncellemelisiniz ve kullanıldığı tüm yerleri yakalamanızı ummalısınız. Taklidin yanlış olduğu bir yeri kaçırırsanız, bu test yanlış verilere dayanıyor demektir.
Bunu ele almak için, API çağrılarımızın her biri için tek bir global model kullanıyoruz . Anlaşmamıza göre, API çağrıları yapan tüm modüllerimiz
apidizinde yer almaktadır . Bu modüllerin her biri
__mocks__için, o ağ araması için "tanım" ile bir modül içeren bir dizin ekleyebiliriz .
Sahte nesne, hem yanıtı hem de istek yüklerini ve ayrıca test için gereken varyasyonları içerir.
userNotFoundNeyin alay edildiğini görmeyi kolaylaştırmak gibi kullanım durumları için kullanıcı dostu anahtarlar kullanabilirsiniz . İşte
lookupdaha önce tanımladığımız modül için bir örnek taklit . Bu taklit, adresinde bulunur
src/app/api/lookup/__mocks__/lookup.ts.
Şimdi, bu global taklidi hem birim hem de entegrasyon testleri için kullanabiliriz.
Birim testleri, tek tek modüllerin beklendiği gibi çalıştığından emin olmanın harika bir yoludur. Bu testler, tüm uygulamanın doğru şekilde çalışmasını sağlamada çok fazla değer sağlamaz, ancak geliştiricilerin bileşenleri etkili bir şekilde oluşturmasına yardımcı olabilir.
Örnek olarak,
lookupAPI modülü için bir birim testi yazalım . Bu örnek birim testi, içinde yer alacaktır
src/app/api/lookup/__tests__/index.spec.ts.
Yukarıdaki örnek
lookupmodül için yalnızca tek bir akışı test eder , ancak size temel yapı hakkında bir fikir vermelidir. Genel
jest-fetch-mockmodel, temeldeki HTTP isteğiyle alay etmek için ile birlikte kullanılır . Artık modülün yanıtı üzerinde iddialar yapabilir ve HTTP isteğinin yapısını doğrulayabilirsiniz.
Birim testleri güzel ama uygulamamızı gerçekten test etmek için entegrasyon testleri yaptırmak istiyoruz.
Entegrasyon testleri neden değerlidir? Bireysel modüllerin birbirleriyle doğru bir şekilde etkileşime girdiğini doğrularlar. Kod hatalarıyla modülleri yanlış bir şekilde birbirine bağlamak çok kolaydır. Geçmişte, birim testlerinin tümü başarılı olmasına rağmen, işe yaramayan kod yazmayı içeren hatalar yaptım.
Sonuçta, tek başına tek bir modül genellikle bir kullanıcı için hiçbir şey yapmaz. Sonunda, kullanıcıya fayda sağlayan birçok modül veya kod parçasının birbiriyle etkileşime girmesi.
Tüm bunları söyledikten sonra, entegrasyon testleri doğası gereği birim testlerinden daha karmaşıktır. Test edilen daha fazla kod parçası var ve bir geliştirici olarak işlevselliği bir entegrasyon testinde nasıl gruplayacağınıza karar vermeniz gerekiyor. Güzel bir pratik kuralın, ona kullanıcının bakış açısından bakmak olduğunu buldum. Örnek uygulamamız durumunda, uygulamamızdaki her görünüm için etkili bir şekilde entegrasyon testleri yazabiliriz.
Yukarıdaki diyagramdan,
lookupgörünüm için ana akışlar için entegrasyon testleri yazabiliriz . Genel olarak şöyle görünecek:
lookupgörüntüsü
/user/credential_available/v1Çağrı için HTTP isteklerinin taklitlerini ayarlayın
Entegrasyon testleri yazılırken, kullanıcı davranışını simüle etmek zordur. Ancak uygulamanızla bir kullanıcının yapacağı gibi etkileşim kurmak, değer sağlayan testlere sahip olmak için önemli bir faktördür.
Bu, Test Kitaplığı için yol gösterici ilkedir . Bu stratejinin en büyük avantajlarından biri, tüm UI parçalarınızın koda doğru şekilde bağlanmasını sağlayabilmenizdir. Kariyerimde , bir düğmeye basıldığında çalıştırılacağını varsaydığım kodu manuel olarak çalıştırarak bir kullanıcı akışını test ettiğim hatalarla karşılaştım , ancak maalesef bir hata yaptım ve kodu çağırmak için düğmeyi hiçbir zaman doğru şekilde bağlamadım .
Kullanıcı etkinliği kitaplığı gibi bir şey kullanmak, kullanıcı davranışını basit bir şekilde simüle etmemize yardımcı olabilir.
Bu harika çalışsa da, küçük bir dezavantaj var. Her olay
element için, eylemi gerçekleştirmemiz gerekiyor. Bunu yapmak basit, ancak test paketiniz büyüdükçe ne olacak? HTTP isteklerinin alay edilmesiyle aynı şey olabilir. Aynı öğeyi birden çok testte (veya hatta test paketlerinde) yakalarsanız, ancak o zaman o öğenin HTML yapısını değiştirmeniz gerekirse, birçok testi bozarsınız.
Bu bir kez daha testlerimiz ve koddaki uygulama ayrıntıları arasında bir bağlantı oluşturur . Bu durumda, HTML'nin yapısıdır. Bakalım bunu ölçeklenebilir bir şekilde ayırabilecek miyiz?
Testlerimizi temel alınan uygulamanın HTML yapısından ayırmak için bir Sayfa Modeli kullanmanızı tavsiye ederim . HTML'niz üzerinden bir arayüz oluşturduğunuzda, test, uygulamanın HTML yapısını bilmek yerine bu arayüze güvenebilir. Bu sayfa modelleri,
__tests__her görünüm için dizinin altındaki görünümle saklanabilir .
Şu adreste
lookupbulunan görünüm için örnek bir sayfa modeline bakalım
src/app/components/views/Lookup/__tests__/LookupPage.ts:
Bu sayfa nispeten basittir, ancak karmaşık bir sayfa için bunun nasıl daha büyük olacağını görebilirsiniz. Her modelin
PageModelyukarıdaki örnekte olduğu gibi bir temel sınıfı genişletmesini sağlayarak bu sayfa modelini bile genişletebilirsiniz . Bu temel
PageModelsınıf, tüm görünümlerde tutarlı olabilecek temel işlevselliği içerebilir. Buna bir örnek, uygulamanızda tutarlı bir şekilde hatalar uyguladıysanız, bir hatanın görünür olup olmadığını belirleme yöntemi olabilir.
Şimdi, ele aldığımız tüm parçaları tek tek alalım ve
lookupgörünüm için bir entegrasyon testi için hepsini bir araya getirelim.
Bu test biraz daha büyük, ancak çoğu şimdiye kadar tanıdık gelecektir. Yeni parçalardan biri,
@reach/routeruygulamamız için yönlendirmeyi işlemek için kullanılmasıdır.
renderWithRouterYöntem, bir yardımcı yöntemdir
@testing-librarydokümanlar . Bu, uygulamanın beklendiği gibi sayfalara doğru şekilde yönlendirildiğini iddia etmemize olanak tanır. Tıpkı birim testlerimizde olduğu gibi, global mock'u kullanıyoruz ve
jest-fetch-mockHTTP isteklerimizle alay ediyoruz.
Artık uygulamamızın sınırını (HTTP istekleri) ve işlevselliği ileri sürmek için ihtiyacımız olan minimum miktarı (yönlendiriciye ulaşma) alay ettiğimize göre, kullanıcı davranışımızı simüle edebilir ve uygulamamızla etkileşim kurabiliriz.
LookupPageHTML ile etkileşimde bulunmak için sayfa modeli sınıfını ve sayfamızla etkileşimde bulunmak üzere
user-eventkullanıcı davranışını simüle etmek için kitaplığı kullanıyoruz.
HTTP isteği, sistemimizde kullanıcıyı "bulmak" için alay edildiğinden, kullanıcı daha sonra
/challengegörünüme yeniden yönlendirilmelidir . Bu testteki ana iddiamız budur. Bu basit görünmekle birlikte, kullanıcının bakış açısından doğru bir şekilde birlikte çalışan birçok modülü test ettik. Bunu minimum alaycılıkla yaptık ve testimiz, olabilecek herhangi bir kod yeniden oluşturucuya inanılmaz derecede dayanıklı olacak.
Bu makalede açıklanan teknikleri kullanarak, uygulamanıza yüksek derecede güven veren esnek testler oluşturabilirsiniz. Ana noktaları özetlemek için:
Okuduğunuz için teşekkürler. Herhangi bir geri bildiriminiz veya düşünceniz varsa lütfen bize bildirin.
Yıllık ortalama 154 bin dolar maaş ve istikrarlı iş büyümesi ile şimdi blok zinciri geliştirmeyi öğrenmek için ideal zaman. Blok zinciri teknolojilerini oluşturmak ve geliştirmek için blok zinciri geliştiricileri, bilgisayar ağı, kriptografi, algoritmalar ve veri yapıları dahil olmak üzere çeşitli beceriler kullanır.
Bu, web siteleri oluşturmaktan onları barındırmaya kadar tüm adımları attığımız Kişisel Web Sitesi serisinin 1. bölümüdür. Kişisel bir web sitesi oluşturmayı öğrenme sürecini aşağıdaki adımlara böldüm: Giriş Herkesin bir web sitesine ihtiyacı olduğuna inanıyorum.
Angular uygulamanızın bazı bölümlerinin neden hala yavaş olduğunu merak ediyor musunuz? Bu makale, uygulama performansınızı nasıl artırabileceğinizi size gösterecek. Angular uygulamalarınızı gecikmeli ve yavaş buluyor ancak bunları nasıl geliştireceğiniz konusunda hiçbir fikriniz yok mu? Uygulamanızın performansını artırmanın yaklaşık 5 yolunu öğrenmek için doğrudan bu makaleye dalalım.
Yaz sonu ve sonbahar nostaljik mevsimlerdir. Sokak lambaları ışıklarını yağmurlu sokaklara saçıyor ve ayakların altındaki yapraklar - alacakaranlığın gölgelerinde soluk kırmızı-turuncu - geçmiş günlerin bir hatırlatıcısı.
Jesenko ve benim 20 yıllık evlilik yolculuğumuza nasıl başladığımıza dair başlangıç hikayemizi pek kimse bilmiyor. Bazılarının, ilk dairemizi birlikte doldurmak için yeterince para kazanmamanın çok erken zamanlarıyla ilgili olabileceğinden eminim.
İnsanlar sanata çekilir. On yıldan fazla bir süredir araştırmacılar, izleme sanatının sağlığımız ve esenliğimiz üzerindeki olumlu etkisini araştırıyorlar.