paint-brush
Godot'ta Test Yapmak: Kişisel Olarak Buna Nasıl Yaklaşıyorum?ile@dlowl
725 okumalar
725 okumalar

Godot'ta Test Yapmak: Kişisel Olarak Buna Nasıl Yaklaşıyorum?

ile D. Lowl4m2024/03/07
Read on Terminal Reader

Çok uzun; Okumak

Godot Birim Testi (GUT), AssetLib'den tek tıklamayla kurulabilir. Test komut dosyalarımız için genişletebileceğimiz bir sınıf sağlar. Godot'nun hata ayıklayıcısını kullanma ve bireysel testler yürütme yeteneğine sahip güzel bir kullanıcı arayüzü var. CLI'den ve CI'den çalıştırılabilir (ancak bununla daha sonra ilgileneceğim)
featured image - Godot'ta Test Yapmak: Kişisel Olarak Buna Nasıl Yaklaşıyorum?
D. Lowl HackerNoon profile picture

Biraz değişiklik olsun diye, biraz geliştirici günlüğü tutmak istiyorum. Bir süre önce bir oyun yarışmasına katıldım ve bu oyunu - Fareler ve Kötü Seçimler - fareleri dışarı çekmek için labirentin etrafına peynir yerleştirdiğiniz kısa bir bulmaca oyunu yaptım. Eğlenceliydi ama bazı eksiklikler olduğu belliydi.


Bunlardan en önemlilerinden biri farelerin davranışlarının sezgisel olmamasıdır. Oyuncular, farelerin sadece dondurulmasını değil, sevilmeyen bir peynirin de itilmesini beklediklerini belirttiler. Ayrıca, bu mekaniğin uygulanması çok daha zengin bir bulmaca tasarımına olanak tanıyacaktır.


Dolayısıyla bunun Godot'ta otomatik testlerin yapılabilmesi için iyi bir fırsat olduğunu düşünüyorum.

Beklenen davranışın bir örneği: Fare mavi peynirden uzaklaşmalıdır

Test Araçları

Godot 4 için kullanılabilen birkaç test çerçevesi var, ancak I'imi yakalayan Godot Unit Test (GUT) oldu. GUT oldukça basittir:


  • Tek tıklamayla AssetLib'den kurulabilir.


  • Test komut dosyalarımız için genişletebileceğimiz bir sınıf sağlar: sadece test_ ile başlayan işlevler ekleyin ve bazı iddialar yazın; tipik birim test yapısı.


  • Godot'nun hata ayıklayıcısını kullanma ve bireysel testler yürütme yeteneğine sahip hoş bir kullanıcı arayüzüne sahiptir.


  • CLI'den ve CI'dan çalıştırılabilir (ancak bununla daha sonra ilgileneceğim).

Test Çerçevem

Bu özel durum için, karmaşık senaryoları, oyunun seviyelerini tanımladığım gibi, kod yerine motor editöründe tanımlamanın bir yoluna sahip olmak istedim (bu şekilde testler gerçeğe daha yakın olurdu). Bu nedenle şunları yapmak istiyorum:


  • Haritayı alan ve testleri çalıştıran tek bir koşucu işlevine sahip olun.


  • Her biri yürütülecek bir dizi senaryoya (test senaryolarına) sahip bir harita koleksiyonuna sahip olun.


  • Test senaryolarını sürükle-bırak yöntemiyle tanımlamanın bir yolunu bulun: bir fare yerleştirin ve N dönüşte olması gereken yeri ayarlayın.


O halde bunu açalım.

Test Senaryosu Tanımları

Yeni bir `MouseTestCase` sınıfı tanımlayalım. Onun Node2D miras almasını istiyoruz (onu bir sahneye yerleştirmek istediğimiz gibi. Ve onun alt öğelerinden birini (sahneye kendimiz yerleştireceğimiz) bulmasını istiyoruz: bir fare ve beklenen son konumu (İşaretçi olarak)

 extends Node2D class_name MouseTestCase @export var steps_left = 0 # How many steps to simulate @export var done = false @onready var mouse: Mouse = $Mouse @onready var expected_position = SnapUtils.get_tile_map_position($TestMarker.position)


Artık bunu sahneye koyabiliriz ve iyiyiz! Farenin nerede başladığını, nerede bitmesi gerektiğini ve kaç adımda biteceğini biliyoruz.

Test senaryosunu tanımlamak için bir düğüm ağacı

Haritada şu şekilde görünüyor: test edilecek fare yeşil, hedef işaretçisi kırmızı

Haritaları Test Et

Şimdi bunlardan bir grup daha oluşturalım ve itici davranışımızı test etmek için bir harita hazırlayalım.

'Püskürtme' mekanik testi için ortaya çıkan test haritası

Bu davranış biraz karmaşık olduğundan, birbirinden biraz farklı birçok durumu ele almak istiyoruz:

  • Fare beğenmediği peynirden uzaklaşmak istiyor/


  • Fare hareket yönünü korumak istiyor (yani dönüşlerden kaçınıyor)


  • Fare sola sağa dönüşleri ve U dönüşlerini tercih eder


Bu davranışı kapsayacak 12 test senaryosunu tanımlayan sonuçta ortaya çıkan harita yukarıda gösterilmiştir (tüm bu koordinatları koda sabit kodlamanın ne kadar sıkıcı olabileceğini hayal edin).

Test Çalıştırıcısı

Yapılacak tek şey test çalıştırıcı işlevidir. Fonksiyonun şunları yapması gerekir:

  • Yukarıda tanımladığımız haritayı yükleyin.


  • Tüm test senaryoları tamamlanana kadar oyunun ileri adımlarını simüle edin.


  • Her adımda, tüm test senaryolarını yineleyin ve bunlar yapıldıysa beklenen konuma ulaşılıp ulaşılmadığını kontrol edin.


Kod oldukça basit.

 func run_level_with_mouse_test_cases(map_path: String): var level = load(map_path) map.load_level(level) var cases = MouseTestCase.cast_all_cases(get_tree().get_nodes_in_group(MouseTestCase.MTC_GROUP_NAME)) while (cases.any(func(case): return not case.done)): map.move_mice() for case in cases: if not case.done: case.steps_left -= 1 if case.steps_left == 0: case.done = true assert_eq(case.get_mouse_position(), case.expected_position, case.get_parent().name+"/"+case.name)

Bunun gelişeceğini hayal ediyorum, ancak mevcut uygulama şimdilik yeterince iyi. Testleri yazdım, mekaniği uyguladım ve testler aslında mekaniğin doğru şekilde uygulandığını doğruladı!

Başarılı test çalıştırmasını gösteren GUT bölmesi

Tartışmalar

Burada oyunlardaki testlere yaklaşmanın bir yolunu gösterdim. Açıkçası burada geliştirilecek daha pek çok şey var ve okuyucuları kodu ve çerçeveyi alıp ihtiyaçlarına göre uyarlamaya teşvik ediyorum.


Her zaman olduğu gibi kod GitHub'da mevcuttur: https://github.com/d-lowl/of-mice-and-bad-choices Ayrıca testi tanıtan özel PR'ye de göz atabilirsiniz. Bonus puan olarak eğer birisi bunları CI'da çalıştırabilirse bu harika olur. Şerefe.