Behavior Driven Development (BDD) ve CucumberJS

Merhaba,

BDD üzerine Türkçe kaynağın çok az olması bu makaleyi yazmamda önemli bir faktör oldu. BDD üzerine biraz konuştuktan sonra CucumberJS ile örnek bir uygulama göstereceğim.

BDD Nedir?

Bu sorunun cevabını Liz Keogh vermiş bizler için, Ömür İskender de Türkçe’ye çevirmiş. Tam olarak “BDD, örnekler sunarak davranışları anlatma sanatıdır.” diyebiliriz.

BDD, daha çok kodunuzu test etmekten ziyade ürününüzün davranışlarını test eden bir konsepte sahiptir.

BDD vs TDD

Test Driven Development yaparken yazılan kodlar, developer tarafından yazılır, okunur ve anlaşılır. Bu yazılan testleri, developer dışında kimsenin okumasına gerek yoktur. Eğer testleriniz geçiyorsa, sorun yoktur.

Behavior Driver Development yaparken ise yazdığınız testlerin, sadece testi yazan developer değil herkesçe anlaşılabilmesi ve okunabilmesi beklenir. Bir şirkette çıkardığınız ürünün davranışlarını sadece geliştiriciler değil, birçok paydada görev yapan takımlar da izleyebilmeli ve takip edebilmelidir. Bu takımlar kimi zaman yöneticiler, kimi zaman da satış ve ürün analistleri olabilir. Bu yüzden girişimcimlere kurdukları yazılım ekiplerinde BDD faktörünü özellikle belirtmeleri bu anlamda çok önemli.

BDD ile Yola Çıkarken

BDD ile yola çıkarken elimizde daima iki kavram olmalı. Ve bu kavramlar, süreç boyunca kendini yenilemelidir. Bunlar gereksinimler ve muğlaklık kavramladır.

Gereksinimler:

  • Üye Girişi Yapılmalı

Muğlaklık:

  • Kullanıcı ismi ile mi e-mail ile mi giriş yapmalı?
  • Kaç yanlış giriş hakkı tanınlamalı?

En azından kısa bir örnekle bu şekilde özetleyebiliriz sanırım durumu. Gereksinimler ve muğlaklık durumlarının analizini yaptıktan sonra BDD ile örneklendiriyoruz.

Örnekler:

  • E-mail ile giriş yapılmalı.
  • Üç kez yanlış giriş hakkı tanınmalı.

Bu Örneklere Kimler Katkıda Bulunmalı?

  • Ürün Sahibi (Fikir veya şirket sahibi)
  • Yazılımcılar
  • Tasarımcılar
  • Test edenler

BDD Ne Zaman Tercih Edilir?

BDD, davranış testlerimizi oluşturduğu için ürünle ilgili tüm sürece hakim olmanız gerekmektedir.

Yöneticiniz BDD’e sıcak bakıyor ve size bilgileri bu yönde sürekli olarak aktarıyor ise, ürün ile aynı paydada çalışan birçok takım var ise, ürününüzün süreçle birlikte değişim göstereceği beklenen bir durum ise; başlangıçta zaman kaybı gibi gözükse de uzun vadede sürecin ayakta kalmasını sağlayan yegane etmen olacaktır.

CucumberJS ve Gherkin

Ben BDD için CucumberJS Framework‘unu kullanacağım. CucumberJS, Gherkin formatında test yazmanızı sağlar. Testlerinizi de yine Gherkin formatında yazdıklarınızla birlikte okuyarak yürütür.

Gherkin

Gherkin (DSL), BDD testlerimizi CucumberJS ile birlikte ürün üzerine aynı paydada çalışan takımlarca okunabilir bir formatta yazılabilmesine imkan sağlar. Bu dosyaların uzantısı genelde .feature olmakla birlikte, yazılan dosya gherkins olarak adlandırılır. Gherkin’de features ve scenarios kavramlarına sahibiz. Bu kavramlar sayesinde, ürün davranışlarını rahat bir şekilde yönetebileceğiz.

Gherkin’de bulunan senaryo, o dosyanın yaptığı işin tek cümlelik özeti olmalıdır. Yani kısaca aksiyon ve neticenin birleşiminden edinilen sonucu aktarır.

Given, When ve Then

Given, belirlenen senaryoda oluşturulan testimizin başlangıç durumunu belirtmek için kullanılır. When, testimizde yürütülecek gerçek olayları içermektedir. Then ise testimizin sonucu ortaya koymak için kullanılır.

Best practices olarak, adımların küçük tutulması önemlidir bu aşamada. Senaryonuza göre de  bazen tüm adımları kullanmanıza gerek yoktur. Mesela, given.

Gherkin Test Örneği

Given I have loaded Google
When I search for "cucumber.js"
Then the first result is "GitHub - cucumber/cucumber-js: Cucumber for JavaScript"

Burada, kodun nasıl çalışacağını değil ürünün nasıl davranış sergileyeceğini bize bildirdirdiğini görebiliyoruz. Google, UI değişikliğine gitse dahi Gherkin dosyamız işlevselliğini devam ettirebilecektir.

CucumberJS’in dökümanlarında adımlarla ilgili daha fazla bilgiye erişebilirsiniz.

CucumberJS

Gherkin formatında yazdığımız test dosyalarının JavaScript yönünde yorumlanması ve adımların ilgili JavaScript bloklarında sırası ile işlenmesi gerekmektedir. Burada devreye CucumberJS girmekte. Yukarıda paylaştığımız örnek Gherkin testine ait CucumberJS kodunu aşağıdaki gibi yazabiliriz.

Given('I have loaded Google', function() {});
When('I search for {stringInDoubleQuotes}', function() {});
Then('the first result is {stringInDoubleQuotes}', function() {});

CucumberJS Yükleyelim

CucumberJS’i her JavaScript modülü gibi npm ya da yarn paket yöneticilerini kullanarak yükleyebiliriz.

yarn cucumber --save

Yarn ile uygulamamıza dahil edelim. Genel olarak, Gherkin dosyalarımız features  dizininde yer alır. JavaScript yönünde yürütülen testlerin hangi dizinde olacağına ayrı bir parametrede karar vermezsek, CucumberJS aynı dizinde hem Gherkin’i hem de steps‘leri arayacaktır. Genişletilebilir bir mimari için ayrı dizinlerde oluşturmak en mantıklısı.

$ ./node_modules/.bin/cucumber-js ./myFeatures -r mySteps

Yukarıdaki komutta kullanılan -r parametresi, JavaScript kodlarının ilgili adımlarla otomatik olarak çalışmasını sağmaktadır. CucumberJS dökümanında tüm parametrelerle ilgili bilgilere ulaşabilirsiniz.

Bu şekilde manuel çalıştırmak yerine package.json dosyanızda script bloğunda alias olarak komut tanımlayabilirsiniz.

"scripts": {
  "cucumber": "cucumber-js ./myFeatures -r ./mySteps"
}

Bu aşamadan sonra yarn cucumber diyerek BDD testlerinizi çalıştırabilirsiniz.

CucumberJS İle Login Test Örneği

Şu sıralar NodeJS’te bir REST API geliştiriyorum ve TDD ile birlikte uygulamanın davranış testlerini de yazıyorum. Bununla ilgili, kullanıcının giriş testini Gherkin ve CucumberJS olarak birlikte inceleyelim.

Gherkin

features/login.feature

Feature: Logging User
    Scenario: Successfuly User Logged
        Given Username is "mksglu"
        And password is 123456
        When the user is logging in
        Then the user should be logged in
            | attribute | type    | value                                |
            | Role      | numeric | 1                                    |
            | Auth      | boolean | true                                 |
            | User      | string  | test12                               |
            | Token     | string  | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 |

Given, And, When ve Then adımlarını içeren bir Gherkin dosyası oluşturdum. Tek bir dosyamda, tek bir senaryo tanımlıyorum ve buna ait özellikleri belirliyorum. Given ve And‘te elimdeki mevcut veriyi paylaşıyorum, When‘de tetikleyici metodu yazıyorum ve Then‘de sonuç verimi tablolaştırıyorum.

CucumberJS yönünde, Then’de yazdığımız tablonun doğrulamasını sunucumuza istek atarak yapacağız.

Burada bahsetmediğim bir adım olarak da And kullandım. Eğer adımlarınızın daha okunabilir olmasını istiyorsanız And kullanabilirsiniz.

CucumberJS

steps/login.js

const defineSupportCode = require('cucumber').defineSupportCode;
const expect = require('chai').expect;
const querystring = require('querystring');
const axios = require('axios');
defineSupportCode(function({ Given, Then, When }) {
	Given('Username is {string}', username => {
		this.username = username;
	});
	Given('password is {int}', password => {
		this.password = password;
	});
	When('the user is logging in', async () => {
		const url = 'http://localhost:8080/auth/login';
		this.email = 'ejj@f.g2';
		this.password = 123456;
		const form = {
			email: this.email,
			password: this.password,
		};
		const { data } = await axios.post(url, querystring.stringify(form));
		this.resQuery = data;
	});
	Then('the user should be logged in', resTable => {
		this.resTable = resTable
			.raw()
			.map(row => row[2])
			.map(v => v);
		expect(this.resTable[3]).to.equal(this.resQuery.user);
		expect(this.resQuery.auth).to.be.equal(true);
	});
});

Burada da Gherkin’de tanımladığım adımları sırası ile kendi bloklarında kontrol ettirdim. Bu yürütme işlemini de JavaScript yönünde bizim için CucumberJS halletti.

Then adımında, sunucuma istek atıyorum ve gelen yanıtı Gherkin’de tanımladığım tablo ile kontrol ettiriyorum. Eğer sonuçlar birbirini tutuyorsa, uygulamamın davranış testleri başarılı bir şekilde geçmiş oluyor.

Kaynak ve İleri Okuma

  • https://www.sitepoint.com/bdd-javascript-cucumber-gherkin/
  • https://www.slideshare.net/YolcuIskender/behat-ve-bdd

Bir cevap yazın

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.