Takip et

Test planınızı seçin ve “Execute in parallel” onay kutusunu devre dışı bırakın.


Yazılım geliştirme süreçlerinde testler, kod kalitesini güvence altına almanın ve olası hataları erken aşamada tespit etmenin vazgeçilmez bir parçasıdır. Swift ve Xcode ekosisteminde, uygulamalarımızın işlevselliğini doğrulamak için genellikle XCTest framework’ünü kullanırız. Günümüzde, test sürelerini kısaltmak ve geri bildirim döngülerini hızlandırmak amacıyla paralel test çalıştırma yaklaşımları oldukça popülerdir. Ancak, her senaryoda paralel testler beklenen faydayı sağlamayabilir; hatta bazı durumlarda testlerinizin kararsız (“flaky”) hale gelmesine neden olabilir. Peki, Swift testlerini seri olarak çalıştırmak neden bazı durumlarda kritik bir öneme sahiptir ve paralel testlerin getirdiği zorluklar nelerdir?

Paralel testler, adından da anlaşılacağı gibi, birden fazla testin aynı anda veya eş zamanlı olarak yürütülmesini ifade eder. Bu, genellikle test süresini önemli ölçüde azaltarak geliştiricilerin daha hızlı geri bildirim almasını sağlar. Özellikle büyük projelerde yüzlerce veya binlerce testin bulunması durumunda, paralel çalıştırma bir zorunluluk haline gelebilir. Ancak bu hızın bir bedeli vardır: kaynak bağımlılıkları. Testleriniz ortak bir veritabanı, paylaşılan dosya sistemi, ağ kaynakları veya hatta kullanıcı arayüzü elementleri gibi dış kaynaklara bağımlıysa, paralel çalıştırma kaosa yol açabilir. Örneğin, bir testin veritabanında yaptığı bir değişiklik, eş zamanlı çalışan başka bir testin beklediği veriyi bozabilir. Bu durum, testlerin bazen geçip bazen kalmasına neden olan “flaky” test sorununu ortaya çıkarır. Flaky testler, geliştirme ekipleri için büyük bir zaman kaybı ve moral bozukluğu kaynağıdır, çünkü başarısız bir testin gerçek bir hata mı yoksa sadece bir test altyapısı sorunu mu olduğunu anlamak zordur.

Ortak kaynak yönetimi, paralel testlerdeki en büyük zorluklardan biridir. Her testin bağımsız ve izole bir ortamda çalışması idealdir, ancak pratik uygulamada bu her zaman mümkün olmaz. Özellikle UI testleri (XCUITest) söz konusu olduğunda, uygulamanın tek bir durumuna odaklanmak ve bu durumu değiştiren diğer testlerden etkilenmemek hayati önem taşır. Bir UI testi, uygulamanın belirli bir ekranında belirli bir butona basma senaryosunu doğrulamak isteyebilir. Eğer aynı anda başka bir UI testi, uygulamanın durumunu farklı bir ekrana yönlendirecek şekilde değiştirirse, ilk test başarısız olacaktır. Bu tür bağımlılıklar, testlerin kararlılığını doğrudan etkiler ve sonuç olarak CI/CD (Sürekli Entegrasyon/Sürekli Teslimat) boru hattınızda gereksiz kırmızı işaretlere yol açar. Bu da geliştiricilerin test sonuçlarına olan güvenini azaltır ve test kültürünü olumsuz etkiler.

Sonuç olarak, paralel testler hız avantajı sunsa da, paylaşılan kaynaklara aşırı bağımlı olan, sıralı işlem gerektiren veya UI durumunu etkileyen testler için seri çalıştırma çok daha güvenli ve stabil bir çözümdür. Swift geliştiricileri olarak, test stratejimizi belirlerken bu dengeyi iyi kurmalıyız. Hangi testlerin paralel çalışabileceğini ve hangilerinin kesinlikle seri çalışması gerektiğini anlamak, sağlıklı bir test süiti oluşturmanın anahtarıdır. Bu makalenin ilerleyen bölümlerinde, Swift testlerinizi nasıl seri çalıştıracağınızı, bunun için hangi araçları ve teknikleri kullanabileceğinizi detaylı bir şekilde inceleyeceğiz.

Uzman İpucu: Testlerinizi yazarken her zaman bağımsızlık prensibini göz önünde bulundurun. Her testin kendi önkoşullarını oluşturmasını ve temizlemesini sağlamak (setup/teardown), hem paralel hem de seri çalıştırmada daha kararlı sonuçlar almanıza yardımcı olur. Ancak bu mümkün olmadığında, seri çalıştırma güvenli limandır.

Swift’te Seri Testleri Nasıl Yapılandırırız? Xcode ve Komut Satırı Yöntemleri

Swift projelerimizde testleri seri olarak çalıştırmanın birden fazla yolu bulunmaktadır. Bu yöntemler genellikle Xcode IDE’si üzerinden veya komut satırı aracılığıyla xcodebuild aracı kullanılarak uygulanır. Her iki yaklaşım da, testlerinizi belirli bir sırayla veya tek tek yürütme kontrolünü size sunar, bu da özellikle bağımlılıkları olan veya dış kaynakları kullanan testler için hayati öneme sahiptir.

# Xcode Üzerinden Seri Test Ayarları Nasıl Yapılır?

Xcode, test çalıştırma davranışını yönetmek için çeşitli ayarlar sunar. En doğrudan yöntemlerden biri, test planları (Test Plans) kullanarak paralel çalıştırmayı devre dışı bırakmaktır. Xcode 11 ile birlikte gelen test planları, farklı test yapılandırmalarını tanımlamanıza olanak tanır ve testlerinizi daha granüler bir şekilde yönetmenizi sağlar.

1. Test Planı Oluşturma veya Düzenleme: Projenizde zaten bir test planı yoksa, Navigatör bölmesindeki “Test Navigator” sekmesine gidin, ardından + düğmesine tıklayarak “New Test Plan” seçeneğini seçin. Eğer mevcut bir test planınız varsa, onu çift tıklayarak düzenleyebilirsiniz.
2. Paralel Çalıştırmayı Devre Dışı Bırakma: Test planı düzenleyicisinde, “Configuration” bölümünün altında “Execute in parallel” seçeneğini göreceksiniz. Bu kutucuğun işaretini kaldırarak, testlerinizin paralel yerine seri olarak çalışmasını sağlayabilirsiniz. Bu ayar, test planındaki tüm testlere uygulanır.


      

Test planınızı seçin ve "Execute in parallel" onay kutusunu devre dışı bırakın.


3. Hedef Bazında Seri Çalıştırma: Bazen belirli bir test hedefini (örneğin, sadece UI testleri) seri çalıştırmak isteyebilirsiniz. Test planında, test hedeflerinizin yanında "Test Runner" kısmında "Parallelize execution" seçeneği bulunabilir. Bunu da devre dışı bırakarak o hedefe ait testlerin seri çalışmasını sağlayabilirsiniz.

Xcode üzerinden bu ayarları yapmak, özellikle görsel arayüzü tercih eden geliştiriciler için oldukça kullanışlıdır. Birden fazla test planı oluşturarak farklı test stratejilerini (örneğin, bir plan paralel CI/CD testleri için, diğeri ise lokalde hata ayıklama için seri testler için) kolayca yönetebilirsiniz.

# xcodebuild ile Komut Satırından Seri Test Nasıl Koşulur?

CI/CD ortamlarında veya otomasyon betiklerinde Xcode IDE'sini doğrudan kullanmak yerine, xcodebuild komut satırı aracını tercih ederiz. xcodebuild, testleri çalıştırmak için zengin seçenekler sunar ve seri çalıştırmayı da destekler.

xcodebuild ile testleri seri çalıştırmanın anahtarı, destination argümanını dikkatli kullanmaktır. Özellikle UI testleri (XCUITest) için simülatörlerde paralel testler genellikle cihaz başına birden fazla test çalıştırma girişiminde bulunur. Seri çalıştırmayı zorlamak için, xcodebuild komutunda belirli bir simülatör UUID'sini belirtmek veya test hedefini paralel çalıştırmadan sorumlu olan -maximum-concurrent-test-device-count ve -maximum-concurrent-test-simulator-loads gibi parametreleri kontrol etmek önemlidir.

En basit haliyle, tek bir test hedefini çalıştırırken:


xcodebuild test \
  -workspace YourApp.xcworkspace \
  -scheme YourApp \
  -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0' \
  -testPlan "MySerialTestPlan"


Yukarıdaki komutta, -testPlan "MySerialTestPlan" argümanı, Xcode'da oluşturduğunuz ve paralel çalıştırmayı devre dışı bıraktığınız test planınızı kullanmanızı sağlar. Bu, en güvenilir yoldur çünkü tüm ayarlarınız Xcode projenizin içinde saklanır.

Eğer test planı kullanmıyorsanız ve tüm testleri seri çalıştırmak istiyorsanız, xcodebuild komutuna doğrudan paralel çalıştırmayı kısıtlayan parametreler ekleyebilirsiniz:


xcodebuild test \
  -workspace YourApp.xcworkspace \
  -scheme YourApp \
  -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0' \
  -parallel-testing-enabled NO \
  -maximum-concurrent-test-device-count 1 \
  -maximum-concurrent-test-simulator-loads 1


Bu komut, tüm testleri belirtilen iPhone 15 Pro simülatöründe seri olarak çalıştırır. -parallel-testing-enabled NO açıkça paralel testi devre dışı bırakırken, diğer iki parametre eş zamanlı cihaz ve simülatör yükleme sayısını bire indirerek seri çalışmayı zorlar. Bu kombinasyon, özellikle XCUITest'ler için geçerlidir ve test ortamının tek bir simülatör örneği üzerinde izole kalmasını sağlar.

Bu komutları CI/CD sistemlerinize entegre ederek, otomatikleştirilmiş derleme ve test süreçlerinizde de seri test çalıştırmalarını kolayca uygulayabilirsiniz. Örneğin, Jenkins, GitLab CI veya GitHub Actions gibi araçlarda bu komutları bir betik içerisinde çalıştırarak, testlerinizin her zaman stabil ve öngörülebilir bir şekilde yürümesini sağlayabilirsiniz. Özellikle kararsız testlerin (flaky tests) sıkça yaşandığı UI testlerinde bu yaklaşım, hata ayıklama süresini önemli ölçüde azaltır ve geliştirici verimliliğini artırır. Bu sayede, test sonuçlarınıza olan güveniniz artar ve gerçek hatalara odaklanmak için daha fazla zamanınız olur.

Vaka Analizi: Flaky Testlerin Serüveni ve Seri Testlerle Gelen Çözüm

Bir mobil uygulama geliştirme ekibinde, sık karşılaşılan sorunlardan biri "flaky" testlerdir. Bu testler, aynı kod tabanında ve aynı ortamda bazen geçip bazen başarısız olan, tutarsız sonuçlar veren testlerdir. Bu durum, özellikle büyük ve karmaşık Swift uygulamalarında, paralel test çalıştırmaları devreye girdiğinde daha da belirginleşir. Şimdi, hayali bir senaryo üzerinden bu sorunun nasıl ortaya çıktığını ve seri testlerle nasıl çözülebileceğini inceleyelim.

Senaryo: "TaskWise" Uygulaması ve Paylaşılan Görev Yönetimi Sistemi

"TaskWise" adında bir görev yönetimi uygulaması geliştiren bir ekibimiz var. Uygulama, kullanıcıların görevleri oluşturmasını, düzenlemesini ve tamamlamasını sağlıyor. Uygulamanın backend'i, paylaşılan bir REST API ve yerel bir Realm veritabanı ile etkileşim kuruyor. Ekip, hızlı geri bildirim döngüleri için CI/CD hattında testleri paralel olarak çalıştırıyor.

Problem: Ekip, son birkaç sprinttir CI/CD sürecinde rastgele başarısız olan bir dizi UI testinden şikayetçi. Özellikle, şu üç test sıkça "flaky" sonuçlar veriyor:

1. testCreateNewTask(): Yeni bir görev oluşturup başarılı bir şekilde görüntülendiğini doğrulayan test.
2. testEditExistingTask(): Mevcut bir görevi düzenleyip değişikliklerin kaydedildiğini doğrulayan test.
3. testMarkTaskAsComplete(): Bir görevi tamamlandı olarak işaretleyip listeden kaybolduğunu doğrulayan test.

Bu testler, lokalde geliştiricilerin makinelerinde genellikle sorunsuz geçiyor, ancak CI/CD sunucusunda paralel çalıştıklarında %30-40 oranında başarısız oluyor. Başarısızlıkların ortak nedeni: "Element not found" veya "UI state not as expected" (Beklenen UI durumu değil).

Köken Neden Analizi (Root Cause Analysis):

Ekip, bir süre sonra detaylı bir araştırma yapmaya karar verdi. Şunlar keşfedildi:

* Paylaşılan Veritabanı ve Ağ İsteği Mock'ları: Her üç test de başlamadan önce Realm veritabanını temizliyor ve belirli başlangıç verileriyle dolduruyordu. Ayrıca, ağ istekleri için URLSession'ın URLProtocol'u üzerinden mock veriler sağlıyorlardı. Ancak, bu kurulumlar test sınıfı düzeyinde setUp() ve tearDown() metodlarında yapılıyordu ve paralel çalışan diğer testler bu paylaşılan kaynakları etkileyebiliyordu.
* Aşırı Hızlı UI Geçişleri: Özellikle testCreateNewTask() ve testEditExistingTask() testleri, arayüzde hızlı geçişler ve modal pencerelerin açılıp kapanmasını içeriyordu. Paralel çalışan başka bir UI testi, ana uygulamanın UI hiyerarşisini anlık olarak bozabiliyor veya beklendiği gibi olmayan bir duruma getirebiliyordu. Örneğin, bir test henüz bir modalı kapatmadan diğeri başka bir modal açmaya çalışabiliyordu.
* Senkronizasyon Sorunları: Testlerin birbirini beklemeden eş zamanlı olarak paylaşılan Realm veritabanını manipüle etmesi, veri tutarsızlıklarına yol açıyordu. Bir test, kendi beklediği verinin başka bir test tarafından silindiğini veya değiştirildiğini fark edebiliyordu.

Çözüm: Seri Test Çalıştırma

Bu analizin ardından ekip, özellikle bu "flaky" UI testleri için seri çalıştırmanın daha uygun olacağına karar verdi. Çözüm adımları şu şekilde uygulandı:

1. Xcode Test Planı Oluşturma: Uygulamanın TaskWiseUITests hedefine özel yeni bir Test Planı oluşturdular ve adını "SerialUITests" koydular.
2. Paralel Çalıştırmayı Devre Dışı Bırakma: "SerialUITests" planının ayarlarında, "Execute in parallel" seçeneğini devre dışı bıraktılar.
3. CI/CD Entegrasyonu: CI/CD betiklerini güncelleyerek, xcodebuild komutuna bu yeni Test Planını kullanmasını söylediler.

Önceki paralel çalıştırma komutu (basitleştirilmiş hali):


    # Eski komut: Paralel çalıştırma varsayılan olabilir
    xcodebuild test \
      -workspace TaskWise.xcworkspace \
      -scheme TaskWise \
      -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0'
    

Yeni seri çalıştırma komutu:


    # Yeni komut: Seri test planını kullanarak
    xcodebuild test \
      -workspace TaskWise.xcworkspace \
      -scheme TaskWise \
      -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0' \
      -testPlan "SerialUITests"
    

Sonuçlar:

Bu değişikliğin ardından, "TaskWise" uygulamasının UI testleri CI/CD hattında artık tutarlı bir şekilde geçmeye başladı. Rastgele başarısızlıklar ortadan kalktı ve ekip, test sonuçlarına olan güvenini geri kazandı. Seri çalıştırma nedeniyle test süresi biraz artsa da (yaklaşık %15-20), elde edilen stabilite ve geliştiricilerin flaky testleri ayıklamak için harcadığı zamanın azalması, bu küçük performansa değerdi. Ekip, hızlı ve kritik olmayan birim testlerini hala paralel çalıştırmaya devam ederken, UI testleri ve entegrasyon testleri gibi dış kaynaklara bağımlı olanları seri olarak koşmaya karar verdi. Bu vaka analizi, seri testlerin, özellikle karmaşık ve bağımlı senaryolarda, test süitlerinin güvenilirliğini nasıl artırabileceğini açıkça göstermektedir.

Uzman İpucu: Flaky testlerle karşılaştığınızda, hemen kodu suçlamadan önce test altyapınızdaki paralel çalıştırma ayarlarını kontrol edin. Bazen en basit çözüm, testlerinizi sırayla çalıştırmaktır.

İleri Düzey Kontrol: Test Planları, Test Grupları ve Otomasyon Entegrasyonu

Swift testlerinin seri olarak çalıştırılması, kararlılığı artırmak için kritik bir adımdır, ancak büyük projelerde sadece "seri çalıştır" demek yeterli olmayabilir. Testlerinizi daha verimli yönetmek ve otomasyon süreçlerine sorunsuz bir şekilde entegre etmek için Xcode'un sunduğu ileri düzey kontrol mekanizmalarına hakim olmak gerekir. Bu bölümde, Test Planları ve Test Grupları gibi araçlarla test yürütmesini nasıl daha detaylı kontrol edebileceğimizi ve bu kontrolleri CI/CD boru hatlarına nasıl entegre edebileceğimizi inceleyeceğiz.

# Test Planları ile Granüler Yönetim

Xcode 11 ile tanıtılan Test Planları, testlerinizi organize etme ve çalıştırma şeklinizi devrim niteliğinde değiştirdi. Bir test planı, farklı test yapılandırmalarını (örneğin, dil, lokal, cihaz tipi, paralel/seri çalıştırma) tek bir dosya içinde tanımlamanıza olanak tanır. Bu sayede, farklı senaryolar için farklı test setlerini kolayca çalıştırabilirsiniz.

* Çoklu Konfigürasyonlar: Aynı test hedefine (örneğin, "YourAppUITests") sahipken, farklı test planları oluşturarak farklı senaryoları test edebilirsiniz. Örneğin, bir test planı tüm testleri paralel ve hızlı bir şekilde çalıştırırken, başka bir test planı yalnızca kritik UI testlerini seri ve belirli bir dilde çalıştırabilir. Bu, lokalde geliştirme yaparken veya CI/CD'de farklı aşamalar için esneklik sağlar.
* Test Grupları ve Filtreleme: Test planları içinde, belirli testleri dahil etmek veya hariç tutmak için filtreler kullanabilirsiniz. Bu, özellikle büyük bir test süitiniz olduğunda ve sadece belirli bir değişiklik için ilgili testleri çalıştırmak istediğinizde çok kullanışlıdır. Test planınızı düzenlerken, "Tests" sekmesinin altında testlerinizi gruplayabilir ve her bir grubun paralel veya seri çalışıp çalışmayacağını ayrı ayrı belirleyebilirsiniz. Örneğin:

  • Kritik UI testleri (seri çalıştırılmalı)
  • Performans testleri (belirli bir ortamda tek başına çalıştırılmalı)
  • Hızlı birim testleri (paralel çalıştırılabilir)

Bu grupları test planınızda tanımlayarak, her birinin çalışma stratejisini belirleyebilirsiniz.


* Test Çalıştırma Bağımsızlığı: Test planları, her test çalıştırması için bağımsız bir ortam sağlamaya yardımcı olur. Örneğin, bir test planı uygulamanızın varsayılan dilini İngilizce olarak ayarlarken, başka bir plan Almanca olarak ayarlayabilir. Bu, lokalizasyon testlerini seri ve kontrollü bir şekilde yapmanızı sağlar.

# Otomasyon ve CI/CD Entegrasyonu

Seri test çalıştırmalarını CI/CD boru hattınıza entegre etmek, otomatikleşmiş testlerinizin güvenilirliğini artırmak için hayati öneme sahiptir. xcodebuild komutu, test planlarıyla sorunsuz bir şekilde entegre olur.

Örneğin, xcodebuild komutunuzda birden fazla test planı kullanmak isteyebilirsiniz:


# Birinci adım: Hızlı, paralel birim testlerini çalıştır
xcodebuild test \
  -workspace MyProject.xcworkspace \
  -scheme MyProject \
  -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0' \
  -testPlan "FastUnitTests"

# İkinci adım: Kritik, seri UI testlerini çalıştır
xcodebuild test \
  -workspace MyProject.xcworkspace \
  -scheme MyProject \
  -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.0' \
  -testPlan "CriticalUITests"


Bu yaklaşım, CI/CD boru hattınızı iki aşamaya ayırmanıza olanak tanır: önce hızlı paralel testlerle erken geri bildirim alırsınız, ardından daha yavaş ama kritik olan seri testlerle daha derinlemesine bir doğrulama yaparsınız. Bu, hem hız hem de kararlılık arasında bir denge kurmanızı sağlar.

CI/CD Ortamında Ek Kontroller:

* Ortam Değişkenleri: CI/CD araçları, ortam değişkenleri aracılığıyla testlerin davranışını değiştirmeyi kolaylaştırır. Örneğin, bir CI=true ortam değişkeni ayarlayarak, testlerinizde bu değişkeni kontrol edebilir ve CI ortamına özel setup/teardown mantığı uygulayabilirsiniz (örneğin, gerçek bir veritabanı yerine geçici bir veritabanı kullanmak).
* Test Raporlama: Testler seri çalıştırıldığında, sonuçların daha net ve okunabilir olmasını sağlamak için JUnit veya Cobertura formatında raporlar oluşturmak önemlidir. xcodebuild bu tür raporları destekler:


    xcodebuild test ... \
      -resultBundlePath "Build/TestResults/MyTests.xcresult"
    


Bu xcresult paketini daha sonra xcparse gibi araçlarla işleyerek insan tarafından okunabilir raporlara dönüştürebilirsiniz.
* Duyarlı Rapor Görüntüleme: CI/CD platformlarında test raporları genellikle web arayüzleri üzerinden görüntülenir. Bu raporların mobil cihazlardan da erişilebilir ve okunabilir olması için, rapor sayfalarının responsive (duyarlı) tasarıma sahip olması önemlidir. CSS media query'lerini kullanarak farklı ekran boyutlarına uyum sağlayan rapor görünümleri tasarlayabilirsiniz. Örneğin, küçük ekranlarda test özetini gösterip detayları daraltabilir, büyük ekranlarda ise tüm detayları listeleyebilirsiniz.

Bu ileri düzey teknikler, testlerinizi sadece seri çalıştırmakla kalmayıp, aynı zamanda onları stratejik olarak yönetmenizi ve geliştirme süreçlerinize sorunsuz bir şekilde entegre etmenizi sağlar. Stabil ve güvenilir test süitleri, yazılım kalitesini artırmanın ve geliştirici verimliliğini yükseltmenin temelidir.

Seri Testlerde Performansı Artırma ve En İyi Uygulamalar: Hız ve Stabilite Dengesi

Swift testlerini seri çalıştırmak, kararlılık ve güvenilirlik açısından kritik avantajlar sunsa da, bu yaklaşımın potansiyel bir dezavantajı vardır: artan test süresi. Özellikle büyük projelerde, tüm testleri seriye almak, CI/CD döngüsünü ciddi şekilde yavaşlatabilir. Bu nedenle, seri testleri uygularken performansı optimize etmek ve en iyi uygulamaları takip etmek, hem hız hem de stabilite dengesini korumak için hayati önem taşır.

# Performansı Artırmak İçin İpuçları

1. Gereksiz Testleri Ayıklama ve Temizleme:
* Test Süitini Gözden Geçirin: Gerçekten gerekli olmayan veya artık güncel olmayan testleri belirleyin ve kaldırın. Eski veya tekrarlayan testler sadece zaman kaybına neden olur.
* Verimli setUp() ve tearDown() Metotları: Her testin veya test sınıfının setUp() ve tearDown() metotları, testin çalışması öncesinde ve sonrasında gerekli kaynakları hazırlar ve temizler. Bu metotları mümkün olduğunca hafif tutun. Örneğin, her test için baştan sona bir veritabanı oluşturmak yerine, test sınıfı başına bir kez oluşturup, her testten sonra sadece ilgili verileri temizlemek daha hızlı olacaktır.


    import XCTest

    class MyFeatureUITests: XCTestCase {
        // Class'in tüm testlerinden önce bir kez çalışır
        override class func setUp() {
            super.setUp()
            // Uygulamanın temiz bir başlangıç yapmasını sağlayın (örneğin, tüm verileri silin)
            XCUIApplication().launchArguments = ["--reset-data"]
            XCUIApplication().launch()
        }

        // Her testten sonra çalışır
        override func tearDown() {
            // Test sonrası UI temizliği veya uygulamanın yeniden başlatılması
            XCUIApplication().terminate()
            super.tearDown()
        }

        func testSomeFeatureInteraction() {
            // Test adımları
        }
    }
    


2. Test Kapsamını Daraltma:
* Modüler Test Tasarımı: Testlerinizi küçük, bağımsız birimlere ayırın. Büyük, çok adımlı entegrasyon testleri yerine, her bir özelliği ayrı ayrı test eden daha küçük testler yazın. Bu, hem hata ayıklamayı kolaylaştırır hem de test süresini azaltabilir, çünkü her bir küçük test daha az kaynak ve zaman gerektirir.
* Seçici Test Çalıştırma: Tüm testleri her zaman çalıştırmak yerine, değişen kod ile ilgili testleri belirleyip sadece onları çalıştırın. Git commit'lerine veya değişen dosyalara göre ilgili testleri tetikleyen CI/CD stratejileri uygulayabilirsiniz.
3. Optimum Test Ortamı Ayarları:
* Fiziksel Cihaz Yerine Simülatörler: UI testleri için fiziksel cihazlar yerine simülatörler, genellikle daha hızlı kurulum ve daha fazla kontrol imkanı sunar. Ancak, bazı özel durumlarda (örneğin performans testleri) fiziksel cihazlar daha gerçekçi sonuçlar verebilir. Testlerinizi her iki ortamda da deneyin ve en uygun olanı seçin.
* Simülatör Temizliği: Testlerden önce simülatör durumunu sıfırlamak, önceki testlerin kalıntılarını temizler ve testlerin kararlılığını artırır. xcrun simctl erase gibi komutlarla bu işlemi otomasyon betiklerinize ekleyebilirsiniz.

    # Belirli bir simülatörü silme komutu
    xcrun simctl erase all
    # Veya belirli bir simülatör için
    # xcrun simctl erase 'iPhone 15 Pro (17.0)'
    


4. Ağ ve Veritabanı Mock'lama:
* Dış bağımlılıkları (ağ istekleri, veritabanı vb.) gerçek servisler yerine mock veya stub objelerle değiştirin. Bu, testlerin hem hızını artırır hem de dış servislerin kararsızlığından etkilenmesini önler. Örneğin, URLSession'ı URLProtocol ile mock'layarak ağ isteklerini kontrol altına alabilirsiniz.

# En İyi Uygulamalar

* Testlerinizi Sınıflandırın: Testlerinizi hızlarına, bağımlılıklarına ve türlerine göre (ünite, entegrasyon, UI) sınıflandırın. Hızlı birim testlerini paralel çalıştırırken, yavaş ve bağımlı entegrasyon veya UI testlerini seri çalıştırın. Test Planları bu sınıflandırmayı yönetmek için mükemmel bir araçtır.
* İzole Test Ortamları: Her testin mümkün olduğunca kendi izole ortamında çalıştığından emin olun. setUp() ve tearDown() metodlarını kullanarak testler arasında veri sızıntılarını veya durum çakışmalarını önleyin.
* Erken Geri Bildirim İçin Kademe Kademe Test Etme: CI/CD boru hattınızı, en hızlı ve en kritik testleri ilk önce çalıştıracak şekilde tasarlayın. Birim testleri genellikle saniyeler içinde biter ve bir hatanın erken tespit edilmesini sağlar. Daha sonra daha yavaş olan seri entegrasyon ve UI testlerini çalıştırabilirsiniz.
* Sürekli İzleme ve Analiz: Test süresi ve kararlılık metriklerini sürekli olarak izleyin. Test süitinizdeki yavaşlayan veya "flaky" hale gelen testleri düzenli olarak analiz edin ve iyileştirme fırsatlarını belirleyin. Xcode'un test raporlama araçları ve üçüncü taraf CI/CD araçlarının analiz özellikleri bu konuda size yardımcı olabilir.

Seri test çalıştırmaları, test süitlerinizin kararlılığını artırırken, yukarıdaki ipuçları ve en iyi uygulamalarla bu sürenin kabul edilebilir sınırlar içinde kalmasını sağlayabilirsiniz. Nihai hedef, geliştirme ekibinin test sonuçlarına güvenmesini sağlamak ve böylece yüksek kaliteli yazılımları daha hızlı bir şekilde sunabilmektir.

Sonuç ve Sıkça Sorulan Sorular

Swift ve Xcode ekosisteminde testler, yazılım kalitesini sağlamanın temel taşlarından biridir. Paralel test çalıştırmalarının sunduğu hız avantajı cazip olsa da, paylaşılan kaynaklara bağımlılık, UI durum çakışmaları ve "flaky" test sorunları gibi zorluklar, seri test çalıştırmalarını bazı senaryolarda kaçınılmaz hale getirmektedir. Bu makalede, Swift testlerinizi neden seri çalıştırmanız gerekebileceğini, Xcode ve xcodebuild aracılığıyla nasıl yapılandıracağınızı, flaky testlerle ilgili bir vaka analiziyle pratik çözümleri ve son olarak da performans ve en iyi uygulamalarla ilgili ipuçlarını detaylıca inceledik.

Unutmayın ki, test stratejisi tek bir doğru cevaba sahip değildir. Projenizin büyüklüğü, testlerinizin türü ve bağımlılıkları gibi faktörlere bağlı olarak en uygun yaklaşımı belirlemeniz gerekir. Hızlı, bağımsız birim testleri için paralel çalıştırma hala ideal olabilirken, dış kaynaklara aşırı bağımlı veya kullanıcı arayüzü ile etkileşimde bulunan testler için seri çalıştırma, güvenilir ve tekrarlanabilir sonuçlar elde etmenin altın anahtarıdır. Test planları ve komut satırı araçları sayesinde, test çalıştırma süreçlerinizi daha granüler bir şekilde kontrol edebilir ve CI/CD boru hattınıza sorunsuz bir şekilde entegre edebilirsiniz. Bu sayede, geliştirme ekibiniz test sonuçlarına tam olarak güvenebilir, gerçek hatalara odaklanabilir ve nihayetinde daha yüksek kaliteli yazılımları daha verimli bir şekilde sunabilir.

# Sıkça Sorulan Sorular

S: Seri testler paralel testlerden neden daha yavaştır?

C: Seri testler, adından da anlaşılacağı gibi, testleri birbiri ardına, tek tek çalıştırır. Paralel testler ise aynı anda birden fazla testi yürüterek toplam test süresini kısaltmaya çalışır. Bu nedenle, aynı sayıda test için seri çalıştırma, genellikle daha uzun sürer.

S: Hangi tür testler genellikle seri çalıştırılmalıdır?

C: Genellikle aşağıdaki test türleri seri çalıştırılmalıdır:

  • UI Testleri (XCUITest): Uygulamanın kullanıcı arayüzü tek bir durum üzerinde çalıştığı için, paralel çalışan UI testleri genellikle UI durumunu bozar.
  • Entegrasyon Testleri: Paylaşılan bir veritabanı, dosya sistemi veya ağ kaynağı gibi dış bağımlılıkları olan testler.
  • Durum Bağımlı Testler: Bir testin çıktısının başka bir testin girdisi olduğu veya testlerin belirli bir sıraya göre çalışması gereken senaryolar.

S: xcodebuild komutunda seri çalıştırmayı nasıl kesin olarak sağlarım?

C: xcodebuild komutunda en kesin yol, Xcode'da "Execute in parallel" seçeneği devre dışı bırakılmış bir test planı oluşturmak ve bu planı -testPlan "MySerialTestPlan" argümanıyla kullanmaktır. Alternatif olarak, -parallel-testing-enabled NO -maximum-concurrent-test-device-count 1 -maximum-concurrent-test-simulator-loads 1 gibi argümanları kullanarak paralel çalıştırmayı açıkça kısıtlayabilirsiniz.

S: Seri testler için test ortamını nasıl izole edebilirim?

C: Her testin veya test sınıfının setUp() ve tearDown() metodlarını kullanarak, testten önce gerekli önkoşulları oluşturup (örneğin, geçici bir veritabanı veya mock ağ katmanı) testten sonra bu kaynakları temizleyin. Ayrıca, UI testleri için her test öncesi uygulamanın temiz bir durumda başlatıldığından veya simülatörün sıfırlandığından emin olun.

S: Seri testler performansı çok düşürürse ne yapmalıyım?

C: Test süitinizdeki gereksiz testleri temizleyin, setUp/tearDown metotlarını optimize edin ve ağ/veritabanı bağımlılıklarını mock'layın. Ayrıca, testlerinizi türlerine göre sınıflandırarak (hızlı birim testleri paralel, yavaş UI testleri seri) bir hibrid strateji uygulayabilirsiniz. CI/CD boru hattınızı kademeli test çalıştırmaları için optimize edin, böylece en kritik ve hızlı testler ilk önce çalışır.

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.
Mobil sürümden çık