İçeriğe geç

.NET Core ve Visual Studio for Mac ile Behavior Driven Development (BDD)

Agile bir development takımı düşünelim, Developer’ından Product Owner’ına, Scrum Master’ından Stake Holder’larına kadar hepsinin product development konusunda collaborative olarak birbirlerine bağlı bir şekilde çalışıyor oldukları.

Kulağa harika geliyor değil mi? Ama maalesef bu her zaman %100 mümkün olmuyor.

Peki, bugün ise Behavior Driven Development hakkında konuşacağız.

Bu makale kapsamında BDD hakkındaki bilgilerimizi tazeleyip hemen ardından macOS üzerinde .NET Core ve Visual Studio kullanarak, içerisinde bir takım basit fonksiyonlar içeren bir API’ı, BDD yaklaşımı ile geliştirmeye çalışacağız.

Açıkcası bu makaleyi tamamlayabilmek için, uzun bir süredir SpecFlow‘un, .NET Core support’unun gelmesini bekliyordum.

Bu makale kapsamında ise, aşağıdaki başlıklara sırasıyla değineceğiz:

  1. Kısaca BDD‘ı Hatırlamak
  2. BDD‘ın Faydaları
  3. macOS üzerinde .NET Core ve Visual Studio ile BDD

Kısaca BDD‘ı Hatırlamak

Temelini Test Driven Development (TDD) dan almakta olan BDD, özellikle “kaliteli kod” üretimi üzerine oldukça fazla bir şekilde yoğunlaşmaktadır.

Hemen hemen ~2 yıllık deneyimlerime dayanarak BDD‘nin bize sağladığı en büyük faydalarını söylemem gerekirse eğer, proje geliştirme aşamaları sırasında karşılaşılan iletişimden kaynaklı zorluklara karşı önemli bir aracı olması ve bize proje için harika dokümantasyon sağlıyor olmasıdır diyebilirim.

Peki, nedir bu iletişim zorlukları ve neye sebep oluyor?

Projeyi geliştirecek olan ekibin, müşterinin tüm ihtiyaçlarını doğru bir şekilde anlayabilmesi, genelde business ekiplerinin ellerindedir.

Fakat bir çok durumda business ekiplerinin teknik tarafa uzak olmalarından dolayı da, kalitesiz kod ve eksik ihtiyaçlar da ortaya çıkabilmektedir. BDD ise bu noktada “ortak bir dil” yaratarak, karşılaşılan bu durumu çözümleyebilmemize olanak sağlamaktadır. Yani, developer’lar, test ekipleri ve business ekipleri arasında iletişimin daha iyi bir hale gelebilmesi ve gereksinimlerin kolay bir şekilde anlaşılabilmesi için bir nevi rehberlik yapmaktadır.

Ayrıca BDD, business outcome‘ına doğrudan katkı sağlayacak olan behavior‘ları, developer’lara, test ekiplerine ve business ekiplerine erişilebilir bir şekilde açıkça tanımlamaktadır. BDD‘da bu tanımlamanın odak noktasında ise, user story içerisindeki gereksinimleri bulmak ve bunlara dayalı olarak acceptance test’lerini yazmak vardır. Yani projenin baştan sona acceptance criteria’ları doğrultusunda geliştirilmesi için bir yol çizmektedir.

NOT: BDD içerisinde, müşteri de development sürecinin içerisine sokulmaktadır.

Senaryolar

BDD içerisinde acceptance criteria’lar, “senaryolar” olarak tanımlanmaktadır. Senaryolar yapısaldır ve bir özelliğin farklı durumlarda veya farklı parametreler ile nasıl davranması gerektiğini açıklamaktadır.

Örneğin:

  • X kişisi Google’a girdi.
  • Arama kutusuna “kedi” yazdı.
  • Kedi ile ilgili arama sonuçları ekrana geldi.

Ek olarak senaryolar, “Gherkin” olarak adlandırılan linguistic bir formatta yazılıp, Given, When ve Then bölümlerinden oluşmaktadır.

  • Given: Senaryonun context’ini açıklamaktadır.
  • When: Action’ı tanımlamaktadır.
  • Then: Burada ise ne olacağı, yani “outcome” tanımlanmaktadır.

Gördüğümüz gibi senaryolar, basit bir kalıp ile konuşma dili olarak yazıldığı için, anlaşılması da tüm ekipler tarafından kolay bir hale gelmektedir ve ayrıca bir dokümantasyon niteliği de taşımaktadır.

Bu konu hakkındaki daha detaylı bilgiye ise, buradan ulaşabilirsiniz.

BDD‘nin Faydaları

İlk olarak BDD, test otomasyon projelerinde de kullanılan yöntemlerden birisidir. Gherkin formatında yazılan test senaryolarının “otomasyon sürecinde” kullanılmasının yanı sıra ise, projenin yaşayan ve güncel bir dokümantasyonunun da oluşmasını ayrıca sağlamaktadır.

Genel olarak faydalarına baktığımızda ise:

  • Ekibin her bir üyesi tarafından kullanılabilecek, basit ve anlaşılabilir bir dil sunmaktadır.
  • İş birliğini arttırıp, geliştirmektedir.
  • Odak noktasında müşteri vardır ve uygulamanın davranışlarını takip etmektedir.
  • Projenin güncel bir dokümantasyonunu sağlamaktadır.

Bunlarla birlikte BDD, yazılım geliştirme süreci içerisinde “end user” ve “user acceptance” testleri için harcanan zamanı da büyük ölçüde azaltmaktadır.

macOS üzerinde .NET Core ve Visual Studio ile BDD

Bir e-ticaret firmasında çalıştığımızı düşünelim. Bizden kullanıcıların beğendikleri ürünleri favori listelerine ekleyebilmeleri için bir API geliştirmemiz isteniyor. Bu API‘ı, BDD ile geliştirelim ve nasıl işleyeceğini görelim.

Ben API‘ı, macOS üzerinde Visual Studio ve .NET Core 2.2 kullanarak geliştireceğim. BDD framework’ü olarak ise, SpecFlow kullanacağız.

SpecFlow, .NET çatısı altında Gherkin parser’ını kullanarak human-readable acceptance test’leri tanımlayabilmemize ve yönetebilmemizi sağlayan, open-source bir Behavior Driven Design framework’üdür.

Öncelikle macOS üzerinde Visual Studio‘ya sahip değilseniz, buradan indirebilirsiniz. Visual Studio‘yu açtıktan sonra “Extensions” bölümüne girelim ve “Gallery” tab’ına tıklayalım. Search kutusuna “Straight8’s SpecFlow Integration” yazalım ve aşağıdaki gibi ilgili extension’ın kurulumunu gerçekleştirelim.

Bu extension sayesinde, projemize kolaylıkla feature’lar ve step definition’lar ekleyebileceğiz.

Şimdi “MyFavouriteAPI.Tests” adında bir .NET Core 2.2 NUnit Test Projesi oluşturalım. Ardından sırasıyla “SpecFlow“, “SpecFlow.Tools.MsBuild.Generation” ve “SpecFlow.NUnit” paket’lerini projeye NuGet üzerinden dahil edelim.

Genel configuration opsiyonları için ise, aşağıdaki gibi “specflow.json” adında bir configuration file’ı oluşturalım.

Bu opsiyon ile, feature file’larının İngilizce olacağını belirtmiş oluyoruz.

Configuration file’ını oluşturduktan sonra, “Features” adında bir klasör oluşturalım. Ardından bu klasör içerisine aşağıdaki gibi “FavouriteList” adında bir feature dosyası ekleyelim.

Extension, template olarak bize aşağıdaki gibi bir feature dosyası yaratacaktır.

Şimdi ise bu template’in içeriğini düzenleyerek, kendi feature senaryomuzu oluşturalım.

Senaryonun Tanımlanması

Feature olarak bizim istediğimiz şey, “kullanıcıların beğendikleri ürünleri daha sonra satın alabilmeleri için, favori listeleri oluşturup ürün ekleyebilmeleri veya silebilme işlemleri“.

Ozaman feature’ı aşağıdaki gibi düzenleyelim.

Şimdi ilk senaryomuzu tanımlayalım. Öncelikle bir favori listesi oluşturmaya ihtiyacımız var. Bunun için senaryo kısmına, “yeni bir favori listesi oluşturma” işlemi diyelim.

Peki bu senaryo ne zaman gerçekleşecek, yani buradaki action nedir? Buradaki action’ın tanımı için ise, “yeni bir favori listesi oluşturduğumda” desek yeterli olur sanırım. Şimdi bu işlemin sonucunda ise ne olacak, buradaki outcome nedir?

Bunun için ise, “favori listesi boş olarak oluşturulmuş olmalıdır” diyebiliriz. Bu senaryodan yola çıkarak, feature dosyasını ise aşağıdaki gibi düzenleyelim.

Yukarıda tanımlamış olduğumuz bu senaryo, yapılacak olan işi ne kadar da net anlatıyor değil mi? Ekibin her bir üyesi tarafından kullanılabilecek ve anlaşılabilecek basit bir dil.

Senaryonun Kodlanması

Senaryoyu tanımlamanın ardından, projemizi build edelim ve IDE üzerinden “Unit Tests” pad’ine geçelim.

Ahha! Projeyi build etmenin ardından, bizim için “CreateANewFavouriteList” test’ini oluşturmuş durumda.

Ozaman test’i run edelim ve sonucuna test result pad üzerinde bir bakalım.

Henüz herhangi bir kod yazmadığımız için “No matching step definition found for one or more steps.” mesajını bize veriyor.

Şimdi ise senaryomuz ile alakalı, step definition’ları tanımlamamız gerekiyor. Bunun için ise, extension’ın result pad’de bize vermiş olduğu örnek kod parçasını kullanabiliriz.

Şimdi “StepDefinitions” adında bir klasör oluşturalım ve içerisinde, “FavouriteListSteps” adında bir class tanımlayalım.

Ardından örnek kod parçasını kopyalayalım ve aşağıdaki gibi “FavouriteListSteps” class’ı içerisine yapıştıralım.

NOT: “MyNamespace” ve “StepDefinitions” kısımlarını düzenlemeyi unutmayalım.

Burada ne yapmamız gerektiği gayet açık, değil mi?

Kodlamaya başlamadan önce assertion’ları kolaylıkla yapabilmemiz için, projeye “FluentAssertions” paketini de NuGet üzerinden dahil edelim.

Ardından örnek senaryomuzu ise, aşağıdaki gibi kodlamaya başlayalım.

Burada basitçe “When” ve “Then” adımlarımızı kodladık. İlk önce kullanıcı için yeni bir favori listesi yarattık, ardından favori listesinin boş olduğunu doğruladık.

Şimdi “CreateANewFavouriteList” test’ini tekrar çalıştıralım.

Gördüğümüz gibi test başarıyla geçti.

Şimdi feature’a yeni bir senaryo daha ekleyelim. Kullanıcı artık favori listesine, ürün ekleyebilmeli. Birde favori listesinden ürünü silebilmeli.

Bunun için senaryomuzu aşağıdaki gibi genişletelim.

Senaryoyu kaydettikten sonra projeyi tekrar build edelim ve “Unit Tests” pad’ine tekrar bir bakalım.

Build işleminin ardından, yeni tanımlamış olduğumuz senaryo için de extension, “AddANewProductToTheFavouriteList” ve “RemoveAProductFromTheFavouriteList”  isimli test’ler oluşturulmuş durumda.

Test’leri run edelim ve yine test result pad ekranındaki örnek method snippet’larını alalım.

Şimdi feature’ı tamamlayabilmek için bizden beklemiş olduğu bu davranışları, “FavouriteListSteps” class’ı içerisinde aşağıdaki gibi implemente edelim.

Burada bir kaç noktaya değinmek istiyorum. Eğer daha önce implemente ettiğimiz benzer bir senaryo varsa, onu tekrardan kodlamamıza gerek yok. Tek yapmamız gereken, feature file’ında da olduğu gibi, “Given” context’ini gerekli yere eklemek.

Örneğin favori listesine yeni bir ürün ekleyebilmek ve silebilmek için, önce bir favori listesi oluşturmamız gerekmektedir. Bunun için ise daha önce implemente etmiş olduğuz “WhenICreateANewFavouriteList” method’una, “[Given(@”I create a new favourite list”)]” attribute’ünü eklememiz yeterli olacaktır.

Devamında ise, bizden beklenen davranışları implemente ettik. Şimdi “Unit Tests” pad’ine tekrar geçelim ve tüm test’leri çalıştıralım.

Tada! “FavouriteList” feature’ının tamamlanabilmesi için gerekli tüm senaryolar başarıyla geçti.

Makalenin giriş kısmında BDD‘nin faydalarından bahsederken, aşağıdaki madde’lerden bahsetmiştik:

  • Ekibin her bir üyesi tarafından kullanılabilecek, basit ve anlaşılabilir bir dil sunmaktadır.
  • İş birliğini arttırıp, geliştirmektedir.
  • Odak noktasında müşteri vardır ve uygulamanın davranışlarını takip etmektedir.
  • Projenin güncel bir dokümantasyonunu sağlamaktadır.

Şimdi ise oluşturmuş olduğumuz feature file’ına bir bakalım.

Bu feature file, ekibin her bir üyesi tarafından kullanılabilecek basit ve anlaşılabilir bir dile sahip, projenin güncel bir dokümantasyonudur. Development sırasında ise bizi, uygulamanın davranışlarını takip ettirerek, kodumuza yön vermiştir.

Sonuç

BDD, özellikle product development konusunda collaborative olarak işbirliğine ihtiyaç duyulduğu zamanlarda kullanılabilecek önemli bir methodology’dir. Kullanıcıyı ve uygulamanın davranışlarını da odağına alarak, maintanance ve ek maliyetleri de minimize etmektedir. Ayrıca uygulamanın güncel dokümantasyonunu da oluşturmasıyla birlikte, test otomasyon sürecine de büyük ölçüde destek vermektedir.

Link: https://github.com/GokGokalp/BDDSampleWithNetCoreSpecFlow

Referanslar

https://specflow.org/getting-started/
https://specflow.org/documentation/
https://specflow.org/2018/specflow-3-public-preview-now-available/

Bu makale toplam (631) kez okunmuştur.

11
0



Tarih:.NET CoreASP.NET CoreBehavior Driven DevelopmentTest Driven Development

İlk Yorumu Siz Yapın

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*