Bir ünite testi kolay olacak bir oyunun yazılımı nasıl tasarlanır?


25

Oyun geliştirme durumunda JUnit gibi bir test çerçevesi kullanmak pratik midir? Oyununuzu daha test edilebilir hale getirmek için ne tür tasarım konularını takip edebilirsiniz? Oyunun hangi bölümleri test edilebilir / test edilmelidir ve insan testine hangi bölümler bırakılmalıdır?

Örneğin, oyun döngüsü bir işlevde kapsüllenmişse, test edilmesi çok zor olacak gibi görünüyor. Zaman deltası süren ve oyun mantığını ileri doğru hareket eden bir "güncelleme" işlevini yeniden düzenlemeyi seviyorum; Bu, sahte, yavaş zaman deltalarını besleyerek oyunu yavaşlatma yeteneği gibi bazı ilginç oyunlara izin verir.


6
Neredeyse sınırsız bir köle emeği ordusuna sahip olduğun zaman senin için oyun testi yapmak için neden is adam saatlerini yazıyorsun? Şaka yapıyorum, şaka yapıyorum ...;)
Mike Strobel

1
Aslında çocuğa ihtiyacın yok, bu gerçekten iyi bir nokta! Bunu düşünmedim, ancak oyunlar diğer insanların test etmeleri için en kolay yazılım türüdür. Sanırım otomatik oyun testinin zorluğunu biraz telafi ediyor (birim ya da başka bir şekilde).
Ricket

3
Ünite testi mutlaka uygulamanızın bir bütün olarak doğru çalıştığından emin olmak zorunda değildir (örn. İşlevsel test). Gelecekteki değişikliklerin mevcut işlevselliği bozmadığından emin olmak hakkında daha fazla şey. Elbette, bir kullanıcı uzay gemisinin ne zaman baş aşağı olduğunu görebilir, ancak yama algoritması 0,001 ile kapatıldığında, oyun 200 saat oynanana kadar etkiler görünmeyebilir. Bu, kodların kapıdan çıkmadan önce, birim testlerinin yakalayabileceği türler.
Wade Williams,

1
Oyun en kolay Kullanıcıların almak için yazılımlardır oynamak ama oyun! = Test . İyi hata raporları almak oldukça zordur. Bunun ötesinde, kodda bir hatanın nerede oluştuğunu izlemek ve yeni değişikliklerin var olan kodu bozmadığını doğrulamak, her ikisinin de otomatik testlerden büyük ölçüde faydalanmasını sağlar.
munificent

Yanıtlar:


25

TDD'nin ilkelerinden biri, TDD'nin bazı durumlarda tasarımınızı etkilemesine izin vermenizdir. Sistem için bir test yazarsınız, daha sonra bu testi geçmek için kodu yazın, bağımlılıkları mümkün olduğunca sığ tutun.

Benim için, birim testinin bir parçası olarak test etmediğim iki şey var:

İlk önce görsel unsurları ve nasıl göründüğünü test etmiyorum. Bunu test ettim ve nesne güncelledikten sonra doğru yerde olacak, bir kamera sınırlarının dışında bir nesneyi cilalayacak, dönüşümler (en azından gölgelendiriciler dışında yapılanlar) grafik motoruna teslim edilmeden önce doğru bir şekilde gerçekleştirilebilecek , ama grafik sistemine çarptığında çizgiyi çiziyorum. DirectX gibi şeylerle alay etmeye çalışmayı sevmiyorum.

İkincisi, ana oyun döngüsü işlevini gerçekten test etmiyorum. Makul bir delta geçtiğinde her sistemin işe yarayacağını ve ihtiyaç duyulduğunda sistemlerin birlikte çalıştığını test ediyorum. Sonra her sistemi oyun döngüsünde doğru delta ile güncellerim. Aslında her sistemin doğru delta ile çağrıldığını gösteren bir test yapabilirdim, ancak çoğu durumda bu fazladanlamayı buluyorum (deltanızı almak için karmaşık bir mantık yapmadığınız sürece, o zaman fazladan ödeme yapılmaz).


6
İlk paragraf anahtardır. Gerçek şu ki, TDD kodunuzu, test etmenize izin vermeden, onsuzdan daha iyi tasarlamanızı gerektirir. Onlar tasarım konusunda uzmandırlar, ama tabii ki çoğu kendi becerileri ile etkilendim olanlar ... genellikle öğrenmeye En çok olanlar olduğunu elbette pek çok düşünmek Of
çizgi-tom-bang

2
Sonuç olarak kodun mutlaka daha iyi tasarlandığı konusunda hemfikir değilim. Test edilebilir bağımlılıkları enjekte etmek için daha önce temiz bir ara yüzün açık olarak parçalanması ve enkapsülasyonun kırılması gereken birçok kullanım gördüm.
Kylotan

4
Bunun, testlerin başka yollardan ziyade önceden var olan sınıflar için yazıldığı durumlarda daha fazla olduğunu buluyorum.
Jeff,

@Kylotan muhtemelen daha yanlış tasarım / kötü test tasarımının bir belirtisidir. Yenileyici ve temiz testler yapmak için alay kullanmak, kodunuzu kötü duruma sokmak; Bu olması gerekenlerin tam tersi.
timoxley

2
Kapsülleme iyi bir şeydir, ancak daha önemlisi neden Niçin iyi bir şey olduğunu anlamaktır. Sadece bağımlılıkları ve büyük çirkin bir arayüzü gizlemek için kullanıyorsanız, kaputun altındaki tasarımınızın muhtemelen çok iyi olmadığı yükünü haykırıyor. Kapsülleme öncelikle çirkin kodu ve bağımlılıkları gizlemekle ilgili değildir, öncelikle kodunuzu anlamayı kolaylaştırmak ve tüketicinin kodu düşünmeye çalışırken izlemesi gereken daha az yolu bulmasına izin vermekle ilgilidir.
Martin Odhelius

19

Noel Llopis, aradığına inandığım ölçüde birim testini yaptı:

Tüm oyun döngüsünün test edilmesiyle ilgili olarak, kodunuzdaki işlevsel gerilemeleri önlemek için başka bir teknik var. Buradaki fikir, oyununuzun kendisini bir yeniden oynatma sistemi ile oynamasını sağlamaktır (örneğin, ilk önce oynatıcı girişlerini kaydeder ve sonra bunları farklı bir çalıştırmada tekrar oynatır). Yeniden oynatma sırasında, her kare için her nesnenin durumunun bir anlık görüntüsünü yaratırsınız. Bu devlet koleksiyonuna daha sonra "altın görüntü" denebilir. Kodunuzu yeniden gözden geçirirken, tekrar oynatmayı çalıştırın ve her karenin durumunu altın resim durumuna göre karşılaştırın. Farklıysa test başarısız olmuştur.

Bu tekniğin faydaları açık olsa da, dikkatli olmanız gereken birkaç şey var:

  • Oyunun deterministik olması gerekiyor, bu yüzden sistem saatine, sistem / ağ olaylarına, deterministik olarak ekilmemiş rastgele sayı üreteçlerine bağlı olarak dikkatli olmalısın. vb.
  • Altın görüntünün oluşturulduktan sonraki içerik değişiklikleri, altın görüntünüzle yasal farklılıklara neden olabilir. Bunu çözmenin bir yolu yok - içeriğinizi değiştirirken altın görüntünüzü yeniden oluşturmanız gerekir.

+1 Bu yaklaşımın değerinin doğrudan "altın görüntünün" uzunluğu ile doğrudan ilişkili olduğunu da belirtmek gerekir: Yeterince uzun değilse, hataları kolayca özleyebilirsiniz; çok uzunsa, yapmayı bekleyen çok şey olacak. Bu modda, normal çalışma koşullarında, zaman aşımına uğramaktan daha hızlı bir şekilde daha büyük bir düzende koşmaya çalışın. Render atlamak yardımcı olabilir!
Mühendis

9

Hem Jeff'in hem de jpaver'ın yorumlarına katılıyorum. Ayrıca, mimariniz için bir bileşen model benimsemenin test edilebilirliğini büyük ölçüde artırdığını da eklemek istedim. Bir bileşen modelinde, her bir bileşen tek bir iş birimi yapmalı ve izolasyonlu (veya sınırlı sahte nesnelerle) test edilebilir olmalıdır.

Aynı şekilde, oyunun varlıklara dayanan diğer kısımları da sadece çalışacak bileşenlerin bir alt kümesine dayanmalıdır. Uygulamada bu, bu alanların test edilmesini kolaylaştırmak için genellikle birkaç sahte bileşenle alay edebildiğiniz veya test amaçlı kısmi varlıklar oluşturabileceğiniz anlamına gelir. Örneğin, görüntü oluşturma ve girdi bileşenlerini dışarıda bırakırsınız, çünkü bunların fizik testine gerek duyulmaz.

Son olarak, oyun dünyasındaki bazı insanlardan arayüzlerle ilgili aldığınız performans önerilerini görmezden gelirdim. Kodları arayüzlerle iyi bir şekilde yazın; yolun aşağısındaki performans sorunlarıyla karşılaşırsanız, sorunu çözmek için kolayca profil oluşturabilir, tanımlayabilir ve düzeltici olabilirsiniz. Noel'in arayüzlerin performans etkisi veya ekledikleri karmaşıklık yükü hakkındaki endişeleri beni ikna etmedi.

Bununla birlikte, her küçük şeyi bağımsız olarak test etmek için denize atmayın. Testlerin ve tasarımın çoğu şey gibi, doğru dengeye oturtulması ile ilgilidir.


Lütfen, SX'te yeni görünmese de, cevapların sipariş edilmediğini ve "yukarıdaki yorumların her ikisi de" gibi bir şey söylediğini söylerken, şu anda bir oylamadan önce oy kullandığınız için hızlı bir şekilde kullanımdan kaldırılmaya mecbur olduğuna dikkat edin. şu anda diğer iki cevaptan :)
Ricket

Teşekkürler yorum yaparken bunu düşünmedim. Bireysel yorumları seçmek için yorumu güncellendi.
Alex Schearer

3

OP'nin, kullanıcının birim sınamalarını değiştirebileceği yorumuna yanıt olarak ikinci bir cevap ekleyeceğimi düşündüm. Ünite testlerinin amacı kaliteyi sağlamak değil, bunun tamamen yanlış olduğuna inanıyorum. Programınızın kalitesini sağlamak için testler yapmak istiyorsanız, senaryo testlerini araştırmanız veya mükemmel izlemeye yatırım yapmanız gerekir.

(Mükemmel izleme ve bir servis olarak çalışan bir ürün ile müşteriye biraz "test" yapmak zor olabilir ancak hataları hızlı bir şekilde algılayan ve sorumlu değişiklikleri geri alan sofistike bir sisteme sahip olmanız gerekir. küçük bir geliştirme ekibi.)

Birim testlerinin ana yararı, geliştiriciyi daha iyi tasarlanmış kod yazmaya zorlamalarıdır. Test işlemi geliştiriciyi endişeleri ayırmaya ve verileri kapsamaya zorlar. Ayrıca geliştiriciyi arayüzleri ve diğer soyutlamaları kullanmaya teşvik eder, böylece yalnızca bir şeyi test eder.


Kabul ediyorum, ünite testleri hariç, geliştiricileri iyi kod yazmaya zorlamaz. Başka bir seçenek var: gerçekten kötü yazılmış testler. Yorulmalarını engellemek için kodlayıcılarınızdan birim testleri fikrine kararlı olmanız gerekir.
tenpn

2
Tabii ama bebeği banyo suyuyla atmak için hiçbir sebep yok. Aletleri sorumlu bir şekilde kullanın, ancak önce aletleri kullanın.
Alex Schearer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.