Bir Sistemi Test Etmek, Yan Etkileri İzole Etmek

Yan etkilerin ortadan kaldırılması test edilebilir kod oluşturmanın en iyi yollarından biridir

İki erkek dövüşçü arasındaki boks maçı resmi. Yüzleri çerçevenin dışında. Soldaki dövüşçü, sağdaki dövüşçüye sol kancayı gönderdi. Sağdaki savaşçı, Sovyetler Birliği'nin küçük bir simgesi olan kırmızı bir kısa giyiyor.

Nock, ağ isteklerini saplamak için JavaScript'te yazılmış ünlü bir kütüphanedir. Bir HTTP sunucusu olmasa bile çalışabilmeleri için testler için statik bir yanıt döndürür.

Ancak, aynı zamanda bir koku.

Veri Kaynağı ve Test Edilen Sistem arasında ortaya çıkan eşleşme, kod yenileme ve bakım yapılabilirliği etkileyebilecek bir maliyettir.

İşte nedeni.

Diyelim ki bir gönderi listesi döndüren bir sunucu ve bir gönderi başlığı listesi oluşturmak için bu sunucudan cevabı tüketen bir işlev var diyelim. İşlev testi, sunucudan gelen yanıtı saplamak için Nock kullanır:

Solda

Kodun kapsamı iyi. Ancak bununla ilgili bazı sorunlar var.

Yanıtın içerik türünde değişiklik yaparsanız, kodun davranışı aynı kalsa bile testleri değiştirmeniz gerekir:

Aynı şey, Nock’ün saplama yaptığı URL’de, başlıklarda veya parametrelerde değişiklik yaparsanız geçerlidir. Sistemin davranışı aynı kalsa bile testleri değiştirmeniz gerekir:

"Kayıt listesi oluşturma" işlevi, Test Edilen Sistem'dir (SUT). HTTP çağrısından gelen veriler Veri Kaynağıdır.

Kodu, Veri Kaynağının SUT'a takılabilir genel bir arayüze sahip olması için tasarlayabilirsiniz. Bu durumda, mantığı çok fazla kuruma gerek kalmadan çalıştırabilirsiniz.

Soldaki “yazı başlıklarının listesi” başlıklı bir bloğu gösteren bir şema. Bir ok “Bellek İçi Veri Kaynağı” başlıklı bir bloğa işaret eder. Diğer ok, “HTTP Sunucu Veri” başlıklı bir bloğa işaret eder. Kaynak.

Bir test ortamı için, bir “Bellek içi Veri Kaynağı” enjekte edebilirsiniz. Üretim için, “HTTP Sunucusu Veri Kaynağı” nı kullanabilirsiniz.

Önceki JSFiddle'daki “genel arayüz”, “mesaj başlığını bulma” yöntemidir. Arayüzü nasıl kurduğunuza bakılmaksızın, tüm arayanlar üzerinde kontrol sizdedir. Bu nedenle, değişiklikler basittir. Martin Fowler buna “yayınlanmamış bir arayüz” diyor.

Diğer yandan, eğer sunucu Yayınlanmış Arayüzünün sözleşmesini ihlal ederse, sınıf niteliğinin post-başlıktan makale-başlıklara değiştiğini söyleyin, yalnızca Veri Kaynağı uygulamasını değiştirmeniz gerekir. Her yerde değişiklik yapmak zorunda değilsin.

Test etmek ve erken geribildirim almak için önemli olan, verilere değil, davranışa karşı yapılan testlerdir. Bu nedenle, mantıktaki değişiklikler için gerekli çaba miktarını azaltmak için kodu tasarlamak önemlidir. Bu durumda, mantık, girdilerin Veri Kaynağından HTML sıralanmamış listesine dönüştürülmesidir.

Yeni tasarımla Veri Kaynağını Test Edilen Sistemden ayırdınız. Bu nedenle Nock'i ​​kaldırabilirsiniz.

Yeni tasarım ayrıca kopyala / yapıştır olmadan sisteme yeni bir kural eklemek için gereken işi azaltır:

Yine de, "HTTP Sunucusu Veri Kaynağı" özel işlevi içinde "sorgu gönderen başlık html'den" bazı denenmemiş bir mantığa sahiptir.

Bunu test etmek için aynı deseni tekrarlayabilirsiniz. Yan etkileri bastırın ve "istek al" mekanizmasını "HTTP Sunucusu Veri Kaynağı" içine takılabilir hale getirin. Bu şekilde Nock’a gerek kalmadan kodu hala test edebilirsiniz:

"Gönderiler listesinin başlığı" nın "Bellek İçi Veri Kaynağı" ile çalıştığını onaylayan testlere zaten sahipseniz, Veri Kaynağını doğru sonucu döndürdüğünden emin olmak için ayrı ayrı test etmeye karar verebilirsiniz:

Yan etkiyi tamamen mantıktan dışarı ittiniz. Bu durumda, gerçek “istek al” işlevi yan etkidir. Şimdi bunu kapatmak için Nock kullanabilirsiniz.

Bununla birlikte, "alma isteği" içindeki mantık önemsiz olduğu ve Nock'un önemli bir maliyeti olduğu göz önüne alındığında, yan etki de dahil olmak üzere tüm başvuruyu uygulayabilecek az sayıda Entegrasyon Testine sahip olmak mantıklıdır. Canlı bir sunucuyla bağlantı kurmaktan kaçınmak için Nock'i ​​kullanabilirsiniz ve tüm parçalar birbirine uyduğunda uygulamanın makul bir yanıt verip döndürmediğini doğrulamak için HTTP isteklerini kullanabilirsiniz.

Nock, bağlantıyı HTTP katmanında saplamak ve statik bir yanıt sağlamak için kullanışlıdır. Ancak, dikkatli kullanın. Sapladığınız her test için, önemli birleşme ve değişim maliyetini arttırırsınız.

Dikkatli kullanılmazsa, Nock bir Nock Hell yaratabilir.

Çözmek istediğiniz sorun böcek sayısını ve değişim maliyetini azaltmaktır. Davranışta değişiklik yapmadan kodun yapısını değiştirirseniz, testler bozulmamalıdır. Olurlarsa, yararlı testler yazmakta başarısız oldunuz.

Amacınız, önem verdiğiniz mantığa test kapsamının kalitesini yükseltmek ve erken geri bildirim almak olmalıdır. Bütün bunlar kodu yeniden gözden geçirme yeteneğinizi etkilemeden.

Yan etkileri ayırın ve Nock gibi araçların kullanımını uygulama sınırlarıyla sınırlandırın.

Bu size değişiklik yapmak ve işleri kırmamak için yeterli güven sağlamalıdır.

Kavgaya katıl, yan etkileri zorla ve sonra ... Çeneni çıkar.

Okuduğunuz için teşekkürler. Geri bildiriminiz varsa, Twitter, Facebook veya Github üzerinden bana ulaşın.

Bu yazıya içgörüsel geribildirimleri için Eduardo Slompo ve Guilherme J. Tramontina'ya teşekkürler.