Karmaşık API'lara (örneğin Amazon S3) bağlı kod nasıl test edilir?


13

Amazon S3'e belge yükleyen bir yöntemi test etmekle uğraşıyorum, ancak bu sorunun önemsiz olmayan herhangi bir API / harici bağımlılık için geçerli olduğunu düşünüyorum. Sadece üç potansiyel çözüm buldum ancak hiçbiri tatmin edici görünmüyor:

  1. Kodu çalıştırın, aslında belgeyi yükleyin, AWS'nin API'sine yüklendiğini kontrol edin ve testin sonunda silin. Bu, testi çok yavaşlatacak, test her çalıştırıldığında paraya mal olacak ve her zaman aynı sonucu döndürmeyecektir.

  2. Sahte S3. Bu süper kıllı çünkü o nesnenin içselliği hakkında hiçbir fikrim yok ve yanlış geliyor çünkü çok karmaşık.

  3. MyObject.upload () öğesinin doğru argümanlarla çağrıldığından emin olun ve S3 nesnesini doğru kullandığım konusunda güven duyun. Bu beni rahatsız ediyor çünkü S3 API'yi tek başına testlerden doğru kullandığımdan emin olmanın bir yolu yok.

Amazon'un kendi SDK'larını nasıl test ettiğini kontrol ettim ve her şeyi alay ediyorlar. Alaycı yapan 200 hat yardımcısı var. Aynı şeyi yapmamın pratik olduğunu düşünmüyorum.

Bunu nasıl çözerim?


Bir cevap değil, ama pratikte maruz kaldığınız üç yaklaşımı kullanıyoruz.
jlhonora

Yanıtlar:


28

Burada ele almamız gereken iki konu var.

Birincisi, tüm testlerinize birim test perspektifinden bakıyorsunuz. Birim testleri son derece değerlidir, ancak tek test türü değildir. Testler aslında çok hızlı birim testlerinden daha az hızlı entegrasyon testlerine ve daha yavaş kabul testlerine kadar birçok farklı katmana ayrılabilir . ( İşlevsel testler gibi daha fazla katman kırılmış olabilir .)

İkincisi, üçüncü taraf kod çağrılarını iş mantığınızla bir araya getirerek, test zorlukları yaratıyor ve muhtemelen kodunuzu daha kırılgan hale getiriyorsunuz.

Birim testleri hızlı olmalı ve sık sık yapılmalıdır. Alaycı bağımlılıklar bu testlerin hızlı çalışmasına yardımcı olur, ancak bağımlılık değişirse ve alaycı değişmezse potansiyel olarak kapsamda delikler açabilir. Testleriniz hala yeşil renkte çalışırken kodunuz kırılabilir. Bazı alay kütüphaneleri, bağımlılığın arayüzü değişirse sizi uyaracak, bazıları değiştiremez.

Entegrasyon testleri ise, üçüncü taraf kütüphaneleri de dahil olmak üzere bileşenler arasındaki etkileşimleri test etmek için tasarlanmıştır. Gerçek nesnenin birlikte nasıl etkileştiğini görmek istediğimizden, alaylar bu test düzeyinde kullanılmamalıdır. Gerçek nesneler kullandığımız için, bu testler daha yavaş olacak ve bunları birim testlerimiz kadar sık ​​çalıştırmayacağız.

Kabul testleri, yazılım gereksinimlerinin karşılandığını test ederek daha da yüksek bir seviyeye bakar. Bu testler, dağıtılacak olan tüm eksiksiz sisteme karşı çalışır. Bir kez daha, alay konusu kullanılmamalıdır.

İnsanların alaylarla ilgili değerli buldukları bir kılavuz, sahip olmadığınız alay türlerini takmamaktır . Amazon, API'yı S3'e sahiptir, böylece altlarında değişmediğinden emin olabilirler. Öte yandan, siz bu güvencelere sahip değilsiniz. Bu nedenle, testlerinizde S3 API'sini alay ederseniz, kodunuz değişebilir ve kırılabilir, testlerinizin hepsi yeşil renkte görünür. Üçüncü taraf kitaplıkları kullanan test kodunu nasıl birimiziz?

Biz bilmiyoruz. Yönergeyi izlersek, sahip olmadığımız nesneleri alay edemeyiz. Ama… doğrudan bağımlılıklarımıza sahipsek, onları alay edebiliriz. Ama nasıl? S3 API için kendi paketleyicimizi oluşturduk. S3 API'sine çok benzeyebiliriz veya ihtiyaçlarımıza daha uygun hale getirebiliriz (tercih edilir). Hatta biraz daha soyut bir söyletebilirim PersistenceServicebir yerine AmazonS3Bucket. ve , görmek isteyebileceğimiz yöntem türlerine PersistenceServicesahip bir arayüz olabilir (bunlar örnektir, aslında farklı yöntemler isteyebilirsiniz). Şimdi S3 API'sini (diyelim ki a ), arama kodumuzdan uzaklaştırarak uygulayabiliriz .#save(Thing)#fetch(ThingId)PersistenceServiceS3PersistenceService

Şimdi S3 API'sini çağıran koda. Bu çağrıları bir PersistenceServicenesneye yapılan çağrılarla değiştirmemiz gerekiyor . Nesneye geçmek için bağımlılık enjeksiyonu kullanıyoruz PersistenceService. Bu önemlidir değil bir istemek için S3PersistenceServiceama istemeye PersistenceService. Bu, testlerimiz sırasında uygulamayı değiştirmemizi sağlar.

S3 API'sini doğrudan kullanmak için kullanılan tüm kod artık bizimkini kullanıyor PersistenceServiceve S3PersistenceServiceşimdi S3 API'sına yapılan tüm çağrıları yapıyor. Testlerimizde, sahip olduğumuzdan alay edebilir PersistenceServiceve kodumuzun doğru çağrıları yaptığından emin olmak için sahte kullanabiliriz. Ama şimdi bu nasıl test edileceğini bırakıyor S3PersistenceService. Öncekiyle aynı sorunu yaşıyor: harici servisi aramadan birimi test edemiyoruz. Yani… birim testi yapmıyoruz. Biz olabilir S3 API bağımlılıkları dışarı alay, ancak bu bize küçük-to-hiçbir ek güven verecekti. Bunun yerine, daha yüksek bir seviyede test etmeliyiz: entegrasyon testleri.

Bu, kodumuzun bir bölümünü test etmememiz gerektiğini söyleyen biraz rahatsız edici gelebilir, ancak başardıklarımıza bakalım. Biz bir yerde bir kod vardı şimdi birim üzerinden test edilebilir birim testi olamazdı PersistenceService. Üçüncü taraf kütüphane karışıklığımız tek bir uygulama sınıfıyla sınırlı. Bu sınıf, API'yi kullanmak için gerekli işlevselliği sağlamalıdır, ancak ona bağlı herhangi bir harici iş mantığı yoktur. Bu nedenle, bir kez yazıldıktan sonra, çok kararlı olmalı ve çok fazla değişmemelidir. Kod istikrarlı olduğu için sık çalışmadığımız daha yavaş testlere güvenebiliriz.

Bir sonraki adım entegrasyon testlerini yazmaktır S3PersistenceService. Bunlar, hızlı birim testlerimizden ayrı olarak çalıştırabilmemiz için ad veya klasörle ayrılmalıdır. Entegrasyon testleri, kod yeterince bilgilendirici ise birim testlerle aynı test çerçevelerini kullanabilir, bu nedenle yeni bir araç öğrenmemize gerek yoktur. Entegrasyon testinin asıl kodu Seçenek 1'iniz için yazacağınız koddur.


soru, ifşa ettiğiniz API için entegrasyonu veya daha çok e2e testlerini nasıl çalıştırdığınızdır. Belirgin nedenlerle PersistenceService ile alay edemezsiniz. Ya bir şeyi yanlış anladım ya da uygulama API'sı ve AWS API'sı arasına başka bir katman ekleyerek, birim testleri yapmak için daha kolay zaman vermekten başka bir şey
vermiyor

@Yerken Düşündüğüm gibi, bu soruya uzun bir cevap daha verebileceğime eminim. Bu benim için bile değerli olabilir, çünkü benim yanıtımdan daha fazlasını alabilirsiniz.
cbojar

4

Her ikisini de yapmanız gerekiyor.

Çalıştırma, yükleme ve silme bir entegrasyon testidir. Harici bir sistemle arayüz oluşturur ve bu nedenle yavaş çalışması beklenebilir. Muhtemelen yerel olarak yaptığınız her bir yapının parçası olmamalı, ancak bir CI yapısının veya gece yapısının bir parçası olmalıdır. Bu, bu testlerin yavaşlığını dengeler ve yine de otomatik olarak test edilmesinin değerini sağlar.

Daha hızlı çalışan birim testlerine de ihtiyacınız var. Harici bir sisteme çok fazla bağımlı olmamak genellikle akıllı olduğu için (böylece uygulamaları değiştirebilir veya geçiş yapabilirsiniz) muhtemelen S3 üzerinden kod yazabileceğiniz basit bir arayüz yazmayı denemelisiniz. Bu arayüzü unittests ile alay et, böylece hızlı çalışan unittestlere sahip olursun.

İlk testler kodunuzun gerçekten S3 ile çalıştığını kontrol eder, ikinci testler kodunuzun S3 ile konuşan kodu doğru çağırdığını test eder.


2

API kullanımınızın karmaşıklığına bağlı olduğunu söyleyebilirim .

  1. Kesinlikle en azından S3 API'sini başlatan ve uçtan uca çalıştığını doğrulayan bazı testler yapmanız gerekir.

  2. Ayrıca, gerçekten API'yı aramayan ek testler yapmanız gerekir, böylece API'yi her zaman çağırmadan kendi yazılımınızı yeterince test edebilirsiniz.

Geriye kalan soru şudur: API'yi taklit etmeniz mi gerekiyor?

Bence bu onunla ne kadar yaptığına bağlı. Sadece bir veya iki basit eylem gerçekleştiriyorsanız, bir modelin tüm sorunlarına gitmeniz gerektiğini düşünmüyorum. Sadece fonksiyonları kullanmayı kontrol etmekten ve canlı testler yapmaktan memnun olurum.

Bununla birlikte, kullanımınız daha karmaşıksa, sonuçları etkileyebilecek farklı senaryolar ve farklı değişkenlerle, muhtemelen daha kapsamlı testler yapmak için alay etmelisiniz.


1

Önceki cevaplara ek olarak, asıl soru S3 API'sini testleriniz için taklit etmek isteyip istemediğinizi (ve nasıl) sormaktır.

Tek tek S3 yanıtlarını el ile alay etmek yerine, çok karmaşık bazı mevcut alaycı çerçevelerden yararlanabilirsiniz. Örneğin moto , gerçek S3 API'sine çok benzer işlevler sağlar.

Mevcut araçları birleştiren ve entegrasyon testini kolaylaştıran tamamen işlevsel bir yerel bulut ortamı (S3 dahil) sağlayan bir çerçeve olan LocalStack'a da bakabilirsiniz .

Bu araçlardan bazıları diğer dillerde (Python) yazılmış olsa da, test ortamını, örneğin Java / JUnit'teki testlerinizden harici bir süreçte döndürmek kolay olmalıdır.

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.