Ön Uç Testi için Boru Hattı 101'i Test Etme

Yayınlanan: 2022-03-10
Hızlı özet ↬ Otomatik test, özellikle kapsamlı yeniden düzenleme veya ekip arkadaşlarınızla çalışırken, değişikliklerinizi birleştirme konusunda size çok güven verebilir. Sonuç olarak, testten en fazla değeri elde etmek için derleme rutininizin bir parçası olarak test etmeyi düşünmüş olabilirsiniz. Nereden başlayacağınızı bilmiyor musunuz? Test hattınızı sıfırdan birlikte uygulayalım.

Şu durumu gözünüzde canlandırın: Son teslim tarihine hızla yaklaşıyorsunuz ve CSS dosyalarınızda birçok değişiklikle bu karmaşık yeniden düzenlemeyi bitirme hedefinize ulaşmak için her boş dakikayı kullanıyorsunuz. Otobüs yolculuğunuz sırasında son basamaklarda bile çalışıyorsunuz. Ancak, yerel testleriniz her seferinde başarısız oluyor ve onları çalıştıramıyorsunuz. Stres seviyeniz yükseliyor .

Gerçekten de iyi bilinen bir dizide benzer bir sahne var: Netflix'in “Çevrimiçi Uyuşturucu Nasıl Satılır (Hızlı)” dizisinin üçüncü sezonundan:

En azından testler kullanıyor, düşünebilirsiniz. Neden hala sıkıntıda, merak ediyor olabilirsiniz? Testler yazsanız bile, iyileştirme ve böyle bir durumdan kaçınmak için hala çok yer var. Kod tabanınızı ve tüm değişikliklerinizi en baştan izlemeyi nasıl düşünüyorsunuz? Sonuç olarak böyle tatsız sürprizlerle karşılaşmazsınız değil mi? Bu tür otomatik test rutinlerini dahil etmek çok zor değil: Bu test hattını baştan sona birlikte oluşturalım.

Hadi gidelim!

Önce İlk Şeyler: Temel Terimler

Bir inşaat rutini, küçük yan projelerinizde bile daha karmaşık yeniden düzenleme konusunda kendinize güvenmenize yardımcı olabilir. Ancak bu, bir DevOps mühendisi olmanız gerektiği anlamına gelmez. Birkaç terim ve strateji öğrenmek çok önemli ve bunun için buradasınız, değil mi? Neyse ki, doğru yerdesiniz! Ön uç projeniz için bir test hattıyla uğraşırken yakında karşılaşacağınız temel terimlerle başlayalım.

Genel olarak test dünyasında google'da gezinirseniz, ilk terimlerden biri olarak "CI/CD" terimlerine zaten rastlamış olabilirsiniz. “Sürekli Entegrasyon, Sürekli Teslimat” ve “Sürekli Dağıtım” kelimelerinin kısaltmasıdır ve tam olarak şunu açıklar: Muhtemelen daha önce duymuş olduğunuz gibi, geliştirme ekipleri tarafından kod değişikliklerini daha sık ve güvenilir bir şekilde dağıtmak için kullanılan bir yazılım dağıtım yöntemidir. CI/CD, büyük ölçüde otomasyona dayanan iki tamamlayıcı yaklaşımı içerir.

  • Sürekli Entegrasyon
    Küçük, düzenli kod değişikliklerini uygulamaya ve bunları paylaşılan bir havuzda birleştirmeye yönelik otomasyon önlemleri için kullanılan bir terimdir. Sürekli entegrasyon, kodunuzu oluşturma ve test etme adımlarını içerir.

CD, her ikisi de birbirine benzeyen ancak bazen farklı bağlamlarda kullanılan kavramlar olan "Sürekli Teslimat" ve "Sürekli Dağıtım"ın kısaltmasıdır. Her ikisi arasındaki fark, otomasyon kapsamındadır:

  • Sürekli Teslimat
    Operasyon ekibinin artık bunları canlı bir üretim ortamında dağıtabileceği, daha önce test edilmekte olan kodunuzun sürecini ifade eder. Bu son adım manuel olabilir.
  • Sürekli Dağıtım
    Adından da anlaşılacağı gibi, “dağıtım” yönüne odaklanır. Müşterinin bunları doğrudan kullanabileceği, depo hakkından üretime kadar geliştirici değişikliklerinin tam otomatik serbest bırakma süreci için bir terimdir.

Bu süreçler, geliştiricilerin ve ekiplerin, istedikleri zaman piyasaya sürebileceğiniz bir ürüne sahip olmalarını sağlamayı amaçlar: Sürekli izlenen, test edilen ve devreye alınan bir uygulamanın güvenine sahip olmak.

İyi tasarlanmış bir CI/CD stratejisine ulaşmak için çoğu kişi ve kuruluş “pipelines” adı verilen süreçleri kullanır. “Boru hattı”, bu kılavuzda açıklamadan kullandığımız bir kelimedir. Bu tür boru hatları hakkında düşünürseniz, gaz gibi şeyleri taşımak için uzun mesafeli hatlar olarak hizmet veren boruları düşünmek çok uzak değil. DevOps alanındaki bir işlem hattı oldukça benzer şekilde çalışır: Dağıtım için yazılımı "taşırlar".

Üç bölümden oluşan bir tüp şeklinde boru hattının bir çizimi: inşa, test etme, dağıtma
"Gerçek" bir CI/CD ardışık düzeni, yeni bir yazılım sürümünü dağıtmak için yürütülmesi gereken birkaç adımı içerir ve sonuç olarak yazılım teslim sürecini otomatikleştirir. (Büyük önizleme)

Kulağa öğrenilecek ve hatırlanacak bir sürü şey gibi geliyor, değil mi? Test hakkında konuşmadık mı? Bu konuda haklısınız: Bir CI/CD ardışık düzeni konseptinin tamamını kapsamak, birden çok makale için yeterli içerik sağlayacaktır ve küçük ön uç projeleri için bir test hattıyla ilgilenmek istiyoruz. Veya boru hatlarınızın yalnızca test etme yönünü kaçırıyorsunuz, bu nedenle yalnızca sürekli entegrasyon süreçlerine odaklanıyorsunuz. Bu nedenle, özellikle boru hatlarının “Test” kısmına odaklanacağız. Bu nedenle, bu kılavuzda "küçük" bir test hattı oluşturacağız.

Pekala, bu yüzden "test bölümü" ana odak noktamız. Bu bağlamda zaten bildiğiniz ve ilk bakışta aklınıza gelen testler hangileri? Bu şekilde test etmeyi düşünürsem, kendiliğinden aklıma gelen test türleri şunlardır:

  • Birim testi , bir uygulamanın birim adı verilen küçük test edilebilir parçalarının veya birimlerinin, düzgün çalışması için ayrı ayrı ve bağımsız olarak test edildiği bir tür testtir.
  • Entegrasyon Testi , bileşenler veya sistemler arasındaki etkileşime odaklanır. Bu tür testler, birimlerin etkileşimini ve birlikte nasıl çalıştıklarını kontrol ettiğimiz anlamına gelir.
  • Uçtan Uca Test veya E2E testi, gerçek kullanıcı etkileşimlerinin bilgisayar tarafından simüle edildiği anlamına gelir; Bunu yaparken, E2E testi, uygulamada kullanılan teknoloji yığınının mümkün olduğu kadar çok işlevsel alanını ve parçasını içermelidir.
  • Görsel Test , bir uygulamanın görünür çıktısını kontrol etme ve bunu beklenen sonuçlarla karşılaştırma işlemidir. Başka bir deyişle, bir sayfanın veya ekranın görünümünde tamamen işlevsel hatalardan farklı "görsel hataların" bulunmasına yardımcı olur.
  • Statik analiz tam olarak test etmek değildir, ancak burada bahsetmenin önemli olduğunu düşünüyorum. Bir yazım düzeltmesi gibi çalıştığını hayal edebilirsiniz: Programı çalıştırmadan kodunuzda hata ayıklar ve kod stili sorunlarını algılar. Bu basit önlem birçok hatayı önleyebilir.

Eşsiz projemizde büyük bir yeniden düzenlemeyi birleştirme konusunda emin olmak için, test hattımızda tüm bu test türlerini kullanmayı düşünmeliyiz. Ancak avantajlı başlangıç, hızlı bir şekilde hüsrana yol açar: Bu test türlerini değerlendirirken kendinizi kaybolmuş hissedebilirsiniz. Nereden başlamalıyım? Hangi türlerin kaç testi makul?

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Strateji Oluşturma: Piramitler ve Kupalar

Boru hattımızı oluşturmaya başlamadan önce bir test stratejisi üzerinde çalışmamız gerekiyor. Daha önce tüm bu soruların yanıtlarını ararken, bazı metaforlarda olası bir çözüm bulabilirsiniz: Web'de ve özellikle test topluluklarında, insanlar hangi türden kaç test kullanmanız gerektiği konusunda size bir fikir vermek için analojileri kullanma eğilimindedir.

Muhtemelen karşılaşacağınız ilk metafor, test otomasyon piramididir. Mike Cohn, Martin Fowler tarafından “Pratik Test Piramidi” olarak daha da geliştirilen “Succeeding with Agile” adlı kitabında bu kavramla ortaya çıktı. Şuna benziyor:

Bir test piramidi
Martin Fowler'ın "Pratik Test Piramidi" (Geniş önizleme)

Gördüğünüz gibi, sunulan üç test seviyesine karşılık gelen üç seviyeden oluşur. Piramit, bir test stratejisi geliştirirken size rehberlik etmek için farklı testlerin doğru karışımını netleştirmeyi amaçlamaktadır:

  1. Birim
    Bu testleri piramidin temel katmanında bulursunuz çünkü bunlar hızlı yürütülür ve bakımı kolaydır. Bunun nedeni izolasyonları ve en küçük birimleri hedef almalarıdır. Çok küçük bir ürünü test eden tipik bir birim testi örneği için buna bakın.
  2. Entegrasyon
    Bunlar, yürütme hızı söz konusu olduğunda hala kabul edilebilir oldukları için piramidin ortasındadır, ancak yine de kullanıcıya birim testlerin olabileceğinden daha yakın olma güvenini verir. Entegrasyon türü testinin bir örneği bir API testidir, ayrıca bileşen testleri bu tür olarak kabul edilebilir.
  3. E2E testleri ( UI testleri olarak da adlandırılır)
    Gördüğümüz gibi, bu testler gerçek bir kullanıcıyı ve onların etkileşimini simüle eder. Bu testlerin yürütülmesi için daha fazla zamana ihtiyaç vardır ve bu nedenle daha pahalıdırlar - piramidin en üstüne yerleştirilirler. Bir E2E testi için tipik bir örneği incelemek istiyorsanız, buna gidin.

Ancak, son yıllarda bu metafor zamanının dolduğunu hissetti. Özellikle kusurlarından biri benim için çok önemli: Bu stratejide statik analizler atlanıyor. Bu metaforda kod tarzı sabitleyicilerin veya diğer linting çözümlerinin kullanılması, bence büyük bir kusur olarak kabul edilmiyor. Lint ve diğer statik analiz araçları, kullanımda olan boru hattının ayrılmaz bir parçasıdır ve göz ardı edilmemelidir.

Öyleyse kısa keselim: daha güncel bir strateji kullanmalıyız. Ancak eksik tiftikleme araçları tek kusur değildir - dikkate alınması gereken daha önemli bir nokta daha vardır. Bunun yerine odağımızı biraz değiştirebiliriz: Aşağıdaki alıntı durumu oldukça iyi özetliyor:

“Testler yazın. Çok fazla değil. Çoğunlukla entegrasyon.”

— Guillermo Rauch

Bunu öğrenmek için bu alıntıyı parçalayalım:

  • Testler yaz
    Oldukça açıklayıcı - her zaman testler yazmalısınız. Testler, hem kullanıcılar hem de geliştiriciler için uygulamanıza güven aşılamak için çok önemlidir. Kendin için bile!
  • çok fazla değil
    Rastgele testler yazmak sizi hiçbir yere götürmez; test piramidi, testleri öncelikli tutmak için ifadesinde hala geçerlidir.
  • Çoğunlukla entegrasyon
    Piramidin görmezden geldiği daha “pahalı” testlerin bir kozu, piramidin yukarısına doğru çıktıkça testlere olan güvenin artmasıdır. Bu artış, hem kullanıcının hem de geliştirici olarak sizin bu testlere güvenme olasılığının yüksek olduğu anlamına gelir.

Bu, tasarım gereği kullanıcıya daha yakın olan testlere gitmemiz gerektiği anlamına gelir. Sonuç olarak, daha fazla ödeyebilirsiniz, ancak çok fazla değeri geri alırsınız. Neden E2E testini seçmediğini merak ediyor olabilirsiniz? Kullanıcıları taklit ettikleri için, başlangıçta kullanıcıya en yakın değiller mi? Bu doğrudur, ancak yine de yürütmeleri çok daha yavaştır ve tam uygulama yığınını gerektirir. Dolayısıyla bu yatırım getirisi, entegrasyon testlerinden daha sonra elde edilir: Sonuç olarak, entegrasyon testleri bir yandan güven ile diğer yandan hız ve çaba arasında adil bir denge sunar.

Kent C.Dodds'u takip ederseniz, özellikle bu makaleyi özellikle onun tarafından okuduysanız, bu argümanlar size tanıdık gelebilir. Bu argümanlar tesadüf değil: Çalışmasında yeni bir strateji buldu. Görüşlerine kesinlikle katılıyorum ve en önemlisini burada ve diğerlerini kaynak bölümünde ilişkilendiriyorum. Önerdiği yaklaşım, test piramidinden kaynaklanmaktadır, ancak entegrasyon testlerinde daha yüksek önceliği yansıtacak şekilde şeklini değiştirerek onu başka bir düzeye yükseltmektedir. Buna “Test Kupası” denir.

Bir test kupası
Ölçeklendirmek için doğru olmayabilir, ancak amacını ortaya koyacak hızlı bir eskiz notu aldım. (Büyük önizleme)

Test ödülü, testlerin ayrıntı düzeyini biraz farklı bir şekilde gösteren bir metafordur; testlerinizi aşağıdaki test türlerine dağıtmalısınız:

  • Statik analiz bu metaforda hayati bir rol oynar. Bu şekilde, yalnızca belirtilen hata ayıklama adımlarını çalıştırarak yazım hatalarını, yazım hatalarını ve diğer hataları yakalarsınız.
  • Birim Testleri , en küçük biriminizin uygun şekilde test edilmesini sağlamalıdır, ancak test kupası onları test piramidi kadar vurgulamaz.
  • Entegrasyon , maliyeti ve daha yüksek güveni en iyi şekilde dengelediği için ana odak noktasıdır.
  • E2E ve Görsel testler de dahil olmak üzere UI testleri , test piramidindeki rollerine benzer şekilde test kupasının en üstünde yer alır.

Projelerimin çoğunda bu test ödülü stratejisini seçtim ve bu kılavuzda bunu yapmaya devam edeceğim. Ancak burada küçük bir uyarıda bulunmam gerekiyor: Tabii seçimim günlük hayatımda üzerinde çalıştığım projelere göre oluyor. Bu nedenle, eşleşen bir test stratejisinin faydaları ve seçimi her zaman üzerinde çalıştığınız projeye bağlıdır. Bu yüzden, ihtiyaçlarınıza uymuyorsa kendinizi kötü hissetmeyin, ilgili paragrafta diğer stratejilere kaynak ekleyeceğim.

Küçük spoiler uyarısı: Birazdan göreceğiniz gibi, bir bakıma bu konseptten de biraz uzaklaşmam gerekecek. Ancak, bence bu iyi, ama buna birazdan geleceğiz. Demek istediğim, boru hatlarınızı planlamadan ve uygulamadan önce test türlerinin önceliklendirilmesi ve dağıtılması hakkında düşünmek.

Bu Boru Hatları Çevrimiçi Nasıl İnşa Edilir (Hızlı)

Netflix'in “Çevrimiçi Uyuşturucu Nasıl Satılır (Hızlı)” dizisinin üçüncü sezonunun kahramanı, son teslim tarihine yakınken E2E testi için Cypress kullanılarak gösteriliyor, ancak bu gerçekten yalnızca yerel testti. CI/CD görülmedi, bu da onu gereksiz strese soktu. Öğrendiğimiz teori ile ilgili bölümlerde verilen kahramanın baskısından kaçınmalıyız. Ancak, bu öğrendiklerimizi gerçeğe nasıl uygulayabiliriz?

Her şeyden önce, başlamak için test temeli olarak bir kod tabanına ihtiyacımız var. İdeal olarak, çoğumuzun ön uç geliştiricilerinin karşılaşacağı bir proje olmalıdır. Kullanım durumu, uygulamalı bir yaklaşım için çok uygun ve sıfırdan bir test hattını uygulamamıza olanak tanıyan, sık rastlanan bir durum olmalıdır. Böyle bir proje ne olabilir?

Birincil Boru Hattı Önerim

Aklıma gelen ilk şey aşikardı: Web sitem, yani portföy sayfam, hevesli hattımız tarafından test edilecek örnek bir kod tabanı olarak kabul edilmeye çok uygun. Github'da açık kaynak olarak yayınlandı, böylece onu görüntüleyebilir ve özgürce kullanabilirsiniz. Sitenin teknoloji yığını hakkında birkaç söz: Temel olarak, bu siteyi ek bir web çerçevesi olarak Nuxt.js ile bir JavaScript çerçevesi olarak Vue.js (maalesef bu makaleyi yazdığımda hala sürüm 2'de) üzerine kurdum. Tam uygulama örneğini GitHub deposunda bulabilirsiniz.

Örnek kod tabanımız seçiliyken öğrendiklerimizi uygulamaya başlamalıyız. Test stratejimiz için bir başlangıç ​​noktası olarak test kupasını kullanmak istediğimiz gerçeğini göz önünde bulundurarak, aşağıdaki konsepte ulaştım:

Bir yazarın birincil boru hattı önerisi
Boru hattı tasvirimdeki parantezlerden birinin şeffaf bir renge sahip olduğunu fark ettiniz mi? Amaca göre renklendirme yaptım; benim küçük sorumluluk reddimin daha önce geldiği nokta budur. (Büyük önizleme)

Nispeten küçük bir kod tabanıyla uğraştığımız için, Birim ve Entegrasyon testlerinin parçalarını birleştireceğim. Ancak, bunu yapmak için sadece küçük bir neden. Diğer ve daha önemli nedenler şunlardır:

  • Bir birimin tanımı genellikle "tartışılacak" tır: Bir grup geliştiriciden bir birimi tanımlamalarını isterseniz, çoğunlukla çeşitli, farklı cevaplar alırsınız. Bazıları bir işleve, sınıfa veya hizmete (küçük birimler) atıfta bulunduğundan, başka bir geliştirici tüm bileşende sayılacaktır.
  • Bu tanım güçlüklerine ek olarak, çok bulanık olduğu için birim ve entegrasyon arasına bir çizgi çekmek zor olabilir. Test temelini başarılı bir şekilde doğrulamak için genellikle DOM'a ihtiyacımız olduğundan, bu mücadele özellikle Ön Uç için gerçektir.
  • Her iki entegrasyon testini de yazmak için genellikle aynı araçları ve kitaplıkları kullanmak mümkündür. Yani, kaynakları birleştirerek tasarruf edebiliriz.

Seçim Aracı: GitHub Eylemleri

Bir ardışık düzen içinde neyi hayal etmek istediğimizi bildiğimize göre, sıradaki seçenek sürekli entegrasyon ve dağıtım (CI/CD) platformunun seçimidir. Projemiz için böyle bir platform seçerken, daha önce deneyim kazandığım platformları düşünüyorum:

  • GitLab, iş yerimdeki günlük rutine göre,
  • Yan projelerimin çoğunda GitHub Eylemleri.

Ancak, aralarından seçim yapabileceğiniz birçok başka platform var. Uyumluluk sorunlarının ortaya çıkmaması için, kullanılan teknolojileri ve çerçeveleri göz önünde bulundurarak, seçiminizi her zaman projelerinize ve özel gereksinimlerine dayandırmanızı öneririm. Unutma, GitHub'da zaten yayınlanmış bir Vue 2 projesi kullanıyoruz ve tesadüfen önceki deneyimime uyuyoruz. Ek olarak, bahsedilen GitHub Eylemleri, başlangıç ​​noktası olarak yalnızca projenizin GitHub deposuna ihtiyaç duyar; bunun için özel olarak bir GitHub Eylemleri iş akışı oluşturmak ve çalıştırmak için. Sonuç olarak, bu kılavuz için GitHub Eylemleri ile gideceğim.

Bu nedenle, bu GitHub eylemleri, belirli olaylar oluyorsa size özel olarak tanımlanmış iş akışlarını çalıştırmanız için bir platform sağlar. Bu olaylar, iş akışını tetikleyen, örneğin değişiklikleri bir şubeye göndermek gibi, havuzumuzdaki belirli etkinliklerdir. Bu kılavuzda, bu olaylar CI/CD'ye bağlıdır, ancak bu tür iş akışları, çekme isteklerine etiket eklemek gibi diğer iş akışlarını da otomatikleştirebilir. GitHub bunları Windows, Linux ve macOS sanal makinelerinde çalıştırabilir.

Böyle bir iş akışını görselleştirmek için şöyle görünür:

GitHub Eyleminin iş akışının bir örneği
Bir Github Eyleminin iş akışı, yapılandırılabilir, otomatikleştirilmiş bir süreçtir (dolayısıyla tüm süreç yeşil renkle gösterilir). (Büyük önizleme)

Bu makalede, bir ardışık düzeni resmetmek için bir iş akışını kullanacağım; bu, bir iş akışının Statik Analizden her türlü UI testine kadar tüm test adımlarımızı içereceği anlamına gelir. Aşağıdaki paragraflarda "iş akışı" olarak adlandırılan bu ardışık düzen, aynı koşucu üzerinde yürütülen bir dizi adım olan bir veya daha fazla işten oluşacaktır.

Bu iş akışı tam olarak yukarıdaki çizimde çizmek istediğim yapıdır. İçinde, birden fazla iş içeren böyle bir koşucuya daha yakından bakıyoruz; Bir işin adımlarının kendisi farklı adımlardan oluşur. Bu adımlar iki türden biri olabilir:

  1. Bir adım, basit bir komut dosyası çalıştırabilir.
  2. Bir adım, bir eylemi çalıştırabilir. Bu tür eylem, yeniden kullanılabilir bir uzantıdır ve genellikle eksiksiz, özel bir uygulamadır.

Bunu akılda tutarak, GitHub eyleminin gerçek bir iş akışı şöyle görünür:

Yazar tarafından bazı açıklamalar içeren bir GitHub eyleminin iş akışı
Sözdizimine ilk bakış - hepsi bir arada. (Büyük önizleme)

İlk GitHub Eylemimizi Yazma

Son olarak, kendi Github eylemimizi yazabilir ve biraz kod yazabiliriz! Temel iş akışımız ve tasvir etmek istediğimiz işlerin ilk taslağı ile başlayacağız. Test kupamızı hatırladığımızda, her iş test kupasındaki bir katmana benzeyecek. Adımlar, bu katmanları otomatikleştirmek için yapmamız gereken şeyler olacak.

Bu nedenle, önce iş akışlarımızı depolamak için .github/workflows/ dizinini oluşturuyorum. Test iş akışımızı bu dizinde içerecek şekilde tests.yml adında yeni bir dosya oluşturacağız. Yukarıdaki çizimde görülen standart iş akışı sözdiziminin yanı sıra şu şekilde ilerleyeceğim:

  1. İş akışımıza Tests CI adını vereceğim.
  2. Uzak şubelerime her gönderimde iş akışımı yürütmek ve ardışık düzenimi başlatmak için manuel bir seçenek sunmak istediğim için, iş push ve workflow_dispatch üzerinde çalışacak şekilde yapılandıracağım.
  3. Son olarak, “Temel boru hattı önerim” paragrafında belirtildiği gibi, iş akışım üç iş içerecektir:
    • static-eslint ;
    • unit-integration-jest tek bir işte birleştirildi;
    • UI aşaması olarak ui-cypress , temel E2E testi ve görsel regresyon testi dahil.
  4. Linux tabanlı bir sanal makine tüm işleri yürütmelidir, bu yüzden ubuntu-latest ile gideceğim.

Bir YAML dosyasının doğru sözdizimini girin, iş akışımızın ilk taslağı şuna benzeyebilir:

 name: Tests CI on: [push, workflow_dispatch] # On push and manual jobs: static-eslint: runs-on: ubuntu-latest steps: # 1 steps unit-integration-jest: runs-on: ubuntu-latest steps: # 1 step ui-cypress: runs-on: ubuntu-latest steps: # 2 steps: e2e and visual

GitHub eylemindeki iş akışlarıyla ilgili ayrıntılara dalmak istiyorsanız, istediğiniz zaman belgelerine göz atmaktan çekinmeyin. Her iki durumda da, şüphesiz adımların hala eksik olduğunun farkındasınız. Endişelenme - Ben de farkındayım. Bu iş akışı taslağını hayatla doldurmak için, bu adımları tanımlamamız ve küçük portföy projemiz için hangi test araçlarını ve çerçevelerini kullanacağımıza karar vermemiz gerekiyor. Sonraki tüm paragraflar ilgili işleri tanımlayacak ve söz konusu testlerin otomasyonunu mümkün kılmak için birkaç adım içerecektir.

Statik Analiz

Test ödülünün önerdiği gibi, iş akışımızda linterler ve diğer kod stili düzelticilerle başlayacağız. Bu bağlamda, birçok araç arasından seçim yapabilirsiniz ve bazı örnekler şunları içerir:

  • Eslint, bir Javascript kod stili düzelticisi olarak.
  • CSS kodu sabitleme için Stylelint.
  • Daha da ileri gitmeyi düşünebiliriz, örneğin, kod karmaşıklığını analiz etmek için, scrutinizer gibi araçlara bakabilirsiniz.

Bu araçların ortak yanı, kalıplardaki ve geleneklerdeki hatalara işaret etmeleridir. Ancak, bu kuralların bazılarının bir zevk meselesi olduğunu lütfen unutmayın. Bunları ne kadar katı bir şekilde uygulamak istediğinize karar vermek size kalmış. Bir örnek vermek gerekirse, iki veya dört sekmeden oluşan bir girintiyi tolere edecekseniz. Tutarlı bir kod stili gerektirmeye ve “==” yerine “===” kullanmak gibi daha kritik hata nedenlerini yakalamaya odaklanmak çok daha önemlidir.

Portföy projemiz ve bu kılavuz için çok fazla Javascript kullandığımız için Eslint'i kurmaya başlamak istiyorum. Aşağıdaki komutla kuracağım:

 npm install eslint --save-dev

Tabii ki, NPM kullanmamayı tercih edersem Yarn paket yöneticisi ile alternatif bir komut da kullanabilirim. Kurulumdan sonra .eslintrc.json adında bir konfigürasyon dosyası oluşturmam gerekiyor. Şimdilik temel bir yapılandırma kullanalım, çünkü bu makale size Eslint'i en başta nasıl yapılandıracağınızı öğretmeyecektir:

 { "extends": [ "eslint:recommended", ] }

Eslint yapılandırması hakkında ayrıntılı bilgi edinmek istiyorsanız bu kılavuza gidin. Ardından, Eslint'in yürütülmesini otomatikleştirmek için ilk adımlarımızı atmak istiyoruz. Bununla başlamak için, Eslint'i bir NPM betiği olarak yürütmek için komutu ayarlamak istiyorum. Bunu, script bölümündeki package.json dosyamızda şu komutu kullanarak elde ediyorum:

 "scripts": { "lint": "eslint --ext .js .", },

Daha sonra bu yeni oluşturulan betiği GitHub iş akışımızda çalıştırabilirim. Ancak, bunu yapmadan önce projemizin kullanılabilir olduğundan emin olmamız gerekir. Bu nedenle, tam olarak şunu yapan önceden yapılandırılmış GitHub Eylem actions/checkout@v2 kullanıyoruz: GitHub eyleminizin iş akışının projemize erişebilmesi için projemizi kontrol etmek. Bir sonraki adım, portföy projem için ihtiyacımız olan tüm NPM bağımlılıklarını kurmak olacaktır. Ondan sonra nihayet eslint betiğimizi çalıştırmaya hazırız! Linting kullanmak için son işimiz şu şekilde görünüyor:

 static-eslint: runs-on: ubuntu-latest steps: # Action to check out my codebase - uses: actions/checkout@v2 # install NPM dependencies - run: npm install # Run lint script - run: npm run lint

Şimdi merak edebilirsiniz: npm run lint bu ardışık düzen otomatik olarak "başarısız olur" mu? Evet, bu kutunun dışında çalışır. İş akışımızı yazmayı bitirir bitirmez Github'daki ekran görüntülerine bakacağız.

Birim ve Entegrasyon

Ardından birim ve entegrasyon adımlarını içeren işimizi oluşturmak istiyorum. Bu makalede kullanılan çerçeve ile ilgili olarak, ön uç testi için size Jest çerçevesini tanıtmak istiyorum. Tabii ki, istemiyorsanız Jest kullanmanıza gerek yok - seçim yapabileceğiniz birçok alternatif var:

  • Cypress ayrıca entegrasyon testleri için çok uygun olan bileşen testi sağlar.
  • Yasemin de bir göz atmak için başka bir çerçevedir.
  • Ve daha birçoğu var; Sadece birkaç isim vermek istedim.

Jest, Facebook tarafından açık kaynak olarak sağlanmaktadır. Çerçeve, Vue.js, React veya Angular dahil olmak üzere birçok JavaScript çerçevesi ve projesiyle uyumluyken basitliğe odaklanmasını sağlar. Ayrıca jest'i TypeScript ile birlikte kullanabiliyorum. Bu, uyumlu ve çok uygun olduğu için çerçeveyi özellikle küçük portföy projem için çok ilginç kılıyor.

Portföy projemin bu kök klasöründen aşağıdaki komutu girerek doğrudan Jest kurulumuna başlayabiliriz:

 npm install --save-dev jest

Kurulumdan sonra zaten testler yazmaya başlayabilirim. Ancak bu makale, Github eylemlerini kullanarak bu testleri otomatikleştirmeye odaklanmaktadır. Bu nedenle, bir ünite veya entegrasyon testinin nasıl yazılacağını öğrenmek için lütfen aşağıdaki kılavuza bakın. İş akışımızda işi static-eslint işine benzer şekilde ilerleyebiliriz. Bu nedenle, ilk adım, daha sonra işimizde kullanmak üzere tekrar küçük bir NPM betiği oluşturmaktır:

 "scripts": { "test": "jest", },

Daha sonra, daha önce linterlerimiz için yaptığımıza benzer şekilde unit-integration-jest adlı işi tanımlayacağız. Böylece, iş akışı projemizi kontrol edecek. Buna ek olarak, ilk static-eslint iki küçük farklılık kullanacağız:

  1. Node.js'yi kurmak için adım olarak bir eylem kullanacağız.
  2. Bundan sonra, Jest testimizi çalıştırmak için yeni oluşturulan npm betiğimizi kullanacağız.

Bu şekilde, unit-integration-jest işimiz şöyle görünecek:

 unit-integration-jest: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # Set up node - name: Run jest uses: actions/setup-node@v1 with: node-version: '12' - run: npm install # Run jest script - run: npm test

UI Testleri: E2E ve Görsel Test

Son olarak, hem E2E testi hem de görsel testi içerecek olan ui-cypress yazacağız. Cypress çerçevesini her ikisi için de kullanacağım için bu ikisini tek bir işte birleştirmek akıllıca olur. Elbette aşağıdaki gibi diğer çerçeveleri de düşünebilirsiniz, NightwatchJS ve CodeceptJS.

Yine, GitHub iş akışımızda onu kurmak için yalnızca temel bilgileri ele alacağız. Cypress testlerini ayrıntılı olarak nasıl yazacağınızı öğrenmek istiyorsanız, tam olarak bununla mücadele eden başka bir rehberim ile sizi tanıştırdım. Bu makale, E2E test adımlarımızı tanımlamamız için ihtiyaç duyduğumuz her konuda size rehberlik edecektir. Pekala, önce diğer çerçevelerde yaptığımız gibi Cypress'i kök klasörümüzdeki aşağıdaki komutu kullanarak kuracağız:

 npm install --save-dev cypress

Bu sefer bir NPM betiği tanımlamamız gerekmiyor. Cypress zaten bize kullanmak için kendi GitHub eylemini sağlıyor, cypress-io/github-action@v2 . Orada, onu çalıştırmak için sadece bazı şeyleri yapılandırmamız gerekiyor:

  • Bir E2E testinin mevcut eksiksiz uygulama yığınına ihtiyacı olduğundan, uygulamamızın tamamen kurulduğundan ve çalıştığından emin olmamız gerekir.
  • İçinde E2E testimizi çalıştırdığımız tarayıcıya isim vermemiz gerekiyor.
  • Bilgisayarın gerçek bir kullanıcı gibi davranabilmesi için web sunucusunun tam olarak çalışmasını beklememiz gerekiyor.

Neyse ki, Cypress eylemimiz tüm bu konfigürasyonları with alanıyla depolamamıza yardımcı oluyor. Bu şekilde, mevcut GitHub işimiz şu şekilde görünüyor:

 steps: - name: Checkout uses: actions/checkout@v2 # Install NPM dependencies, cache them correctly # and run all Cypress tests - name: Cypress Run uses: cypress-io/github-action@v2 with: browser: chrome headless: true # Setup: Nuxt-specific things build: npm run generate start: npm run start wait-on: 'http://localhost:3000'

Görsel Testler: Testinize Biraz Göz Atın

Bu kılavuzu yazmaktaki ilk amacımızı hatırlayın: SCSS dosyalarında birçok değişiklikle önemli bir yeniden düzenlemem var - başka hiçbir şeyi bozmadığından emin olmak için derleme rutininin bir parçası olarak test eklemek istiyorum. Statik analiz, birim, entegrasyon ve E2E testlerine sahip olduğumuzdan oldukça emin olmalıyız, değil mi? Doğru, ama hala boru hattımı daha da kurşun geçirmez ve mükemmel hale getirmek için yapabileceğim bir şey var. Krema haline geldiğini söyleyebilirsin. Özellikle CSS yeniden düzenleme ile uğraşırken, bir E2E testi yalnızca sınırlı bir şekilde yardımcı olabilir, çünkü yalnızca söylediğiniz şeyi testinize yazarak yapar.

Neyse ki, yazılı komutlar dışında ve dolayısıyla konsept dışında, hataları yakalamanın başka bir yolu var. Buna görsel test denir: Bu tür testlerin bir fark bulma bulmacası gibi olduğunu hayal edebilirsiniz. Teknik olarak, görsel test, uygulamanızın ekran görüntülerini alacak ve bunu, örneğin projenizin ana dalından mevcut durumla karşılaştıracak bir ekran görüntüsü karşılaştırmasıdır. Bu şekilde, en azından Görsel test kullandığınız alanlarda, yanlışlıkla hiçbir stil sorunu fark edilmeyecektir. Bu, en azından benim deneyimime göre, Görsel testi büyük CSS yeniden düzenlemeleri için bir cankurtaran haline getirebilir.

Aralarından seçim yapabileceğiniz ve göz atmaya değer birçok görsel test aracı vardır:

  • Bu kılavuz için kullandığım Browserstack aracı Percy.io;
  • Bir SaaS çözümü kullanmamayı ve aynı anda tamamen açık kaynağa geçmeyi tercih ediyorsanız Görsel Regresyon İzleyici;
  • AI destekli Applitools. Bu araçla ilgili Smashing dergisinde göz atabileceğiniz heyecan verici bir rehber var;
  • Storybook tarafından Kromatik.

Bu kılavuz ve temel olarak portföy projem için mevcut Cypress testlerimi görsel testler için yeniden kullanmak hayati önem taşıyordu. Daha önce de belirtildiği gibi, entegrasyonun basitliği nedeniyle bu örnek için Percy'yi kullanacağım. Bir SaaS çözümü olmasına rağmen, hala açık kaynaklı birçok parça var ve birçok açık kaynak veya diğer yan projeler için yeterli olması gereken ücretsiz bir plan var. Bununla birlikte, açık kaynaklı bir araç kullanırken de tamamen kendi kendine barındırılmakta daha rahat hissediyorsanız, Görsel Regresyon İzleyici'ye bir şans verebilirsiniz.

Bu kılavuz, aksi takdirde tamamen yeni bir makale için içerik sağlayacak olan Percy'ye yalnızca kısa bir genel bakış sağlayacaktır. Ancak, başlamanız için size bilgi vereceğim. Şimdi ayrıntılara dalmak istiyorsanız, Percy'nin belgelerine bakmanızı tavsiye ederim. Peki, deyim yerindeyse testlerimize nasıl göz verebiliriz? Şimdiye kadar bir veya iki Cypress testi yazdığımızı varsayalım. Onları şöyle göründüğünü hayal edin:

 it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); });

Elbette, görsel test çözümümüz olarak Percy'yi kurmak istiyorsak, bunu bir selvi eklentisi ile yapabiliriz. Bugün birkaç kez yaptığımız gibi, NPM kullanarak kök klasörümüze kuruyoruz:

 npm install --save-dev @percy/cli @percy/cypress

Daha sonra, yalnızca percy/cypress paketini cypress/support/index.js dizin dosyanıza aktarmanız gerekir:

 import '@percy/cypress';

Bu içe aktarma, uygulamanızdan bir anlık görüntü alacak olan Percy'nin anlık görüntü komutunu kullanmanızı sağlayacaktır. Bu bağlamda, anlık görüntü, yapılandırabileceğiniz farklı görünüm alanlarından veya tarayıcılardan alınan bir ekran görüntüsü koleksiyonu anlamına gelir.

 it('should load home page (visual)', () => { cy.get('[data-cy=Polaroid]').should('be.visible'); cy.get('[data-cy=FeaturedPosts]').should('be.visible'); // Take a snapshot cy.percySnapshot('Home page'); });

İş akışı dosyamıza dönersek, işin ikinci adımı olarak Percy testini tanımlamak istiyorum. İçinde, testimizi Percy ile birlikte çalıştırmak için npx percy exec -- cypress run komut dosyasını çalıştıracağız. Testlerimizi ve sonuçlarımızı Percy projemize bağlamak için bir GitHub sırrı tarafından gizlenmiş Percy belirtecimizi geçmemiz gerekecek.

 steps: # Before: Checkout, NPM, and E2E steps - name: Percy Test run: npx percy exec -- cypress run env: PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}

Neden bir Percy belirtecine ihtiyacım var? Bunun nedeni, Percy'nin ekran görüntülerimizi korumak için bir SaaS çözümü olmasıdır. Karşılaştırma için ekran görüntülerini ve statükoyu tutacak ve bize bir ekran görüntüsü onay iş akışı sağlayacaktır. Orada, yaklaşan herhangi bir değişikliği onaylayabilir veya reddedebilirsiniz:

Percy'nin onay iş akışı
(Büyük önizleme)

Çalışmalarımızı Görüntüleme: GitHub Entegrasyonu

Tebrikler! İlk GitHub eylem iş akışımızı başarıyla oluşturuyorduk. Portföy sayfamın deposundaki eksiksiz iş akışı dosyamıza son bir göz atalım. Pratik kullanımda nasıl göründüğünü merak etmiyor musunuz? Çalışan GitHub eylemlerinizi deponuzun “Eylemler” sekmesinde bulabilirsiniz:

GitHub Eylemleri sekmesi
(Büyük önizleme)

Orada, iş akışı dosyalarınıza eşdeğer olan tüm iş akışlarını bulabilirsiniz. Bir iş akışına göz atarsanız, örneğin "Tests CI" iş akışım, bunun tüm işlerini inceleyebilirsiniz:

CI iş akışı görünümünü test eder
(Büyük önizleme)

İşinizden birine göz atmak isterseniz, onu da kenar çubuğundan seçebilirsiniz. Orada, işlerinizin günlüğünü inceleyebilirsiniz:

Hatalarla başarısız iş
(Büyük önizleme)

Görüyorsunuz, boru hattınızın içinde meydana gelirse hataları tespit edebilirsiniz. Bu arada, GitHub eylemlerinizin sonuçlarını kontrol edebileceğiniz tek yer “eylem” sekmesi değil. Bunları çekme isteklerinizde de inceleyebilirsiniz:

GitHUb eylemlerinin çekme istekleri
(Büyük önizleme)

I like to configure those GitHub actions the way they need to be executed successfully: Otherwise, it's not possible to merge any pull requests into my repository.

Çözüm

CI/CD helps us perform even major refactorings — and dramatically minimizes the risk of running into nasty surprises. The testing part of CI/CD is taking care of our codebase being continuously tested and monitored. Consequently, we will notice errors very early, ideally before anyone merges them into your main branch. Plus, we will not get into the predicament of correcting our local tests on the way to work — or even worse — actual errors in our application. I think that's a great perspective, right?

To include this testing build routine, you don't need to be a full DevOps engineer: With the help of some testing frameworks and GitHub actions, you're able to implement these for your side projects as well. I hope I could give you a short kick-off and got you on the right track.

I'm looking forward to seeing more testing pipelines and GitHub action workflows out there! ️

Kaynaklar

  • An excellent guide on CI/CD by GitHub
  • “The practical test pyramid”, Ham Vocke
  • Articles on the testing trophy worth reading, by Kent C.Dodds:
    • “Write tests. Not too many. Mostly integration”
    • “The Testing Trophy and Testing Classifications”
    • “Static vs Unit vs Integration vs E2E Testing for Frontend Apps”
  • I referred to some examples of the Cypress real world app
  • Documentation of used tools and frameworks:
    • GitHub actions
    • Eslint docs
    • jest belgeleri
    • selvi belgeleri
    • Percy documentation