Unit test nedir? Nodejs restful api unit test yazalım.

Phoique 7

Katılımcı Üye
14 Mar 2017
505
1
Manisa
Merhaba arkadaşlar, yazılımda test dediğimizde bazıları test ne ya ben kodu yazar sonra bakarım çalışıyor mu diyenlerin sayısını azaltmak için yazlımda test nedir nasıl yazılır konusunu açmış bulunmaktayım.

Unit test nedir?

Unit test geliştirmiş olduğunuz proje veya yazdığınız bir kodun doğru çalışıp çalışmadığını istediğimiz gibi çıktı üretmesi veya doğru davranması gibi yazılan test koduna denir. Şimdi diyeceksiniz ki ben yazdığım kodu kendim kontrol ederim ne gerek var test kodu yazmaya? Haklısınız aslında ne gerek var ki siz bu kafaya devam edebilirsiniz biz konumuza devam edelim.

Diyelimki bir proje geliştiriyorsunuz ve birisi size bende projene dahil olabilirmiyim dedi. tamam dedin diyelim. Github lnkini attın projenin sonra x bölümünü yeni ekip arkadaşın beğenmedi ve değiştirip denemeden github pull request yolladı size sizde denemeden kabul edip projenizde çalışan kod ile çalışmayan kodu değiştirdiniz. Sonra fark ettiniz ki kod çalışmıyor ee hani kontrol ederdiniz? bak gözden kaçtı kod bozuldu.

İşte bu ve bu gibi durumlar için test yazıyoruz.Test yazsaydın o arkadaşın o kısmı testten geçirip, testten geçemez ise pull request atamayacaktı çünkü testten geçemedi. (continuous integration)

Tabiki ben bu işte uzmanım çok iyiyim gibi birşey demiyorum sadece ve sadece giriş seviyesi mi dersiniz yeni başlayan mı dersiniz test yazmaya başlayan birisiyim. Mutlaka konu içinde yanlışım atladığım bir şey olur ise söyleyin. :)

Şimdi gelelim nodejs de unit test nasıl yazacağımıza neden nodejs derseniz ben nodejs sevdiğim için basit ve etkili geliyor bana. :) Her yazılım dilinde de test yazıldığını unutmayın.

Nodejs'de restful Api yazalım.

Nodejs yeni başlayan ve expressjs ile ilgilenmiş birisi bile bu kodu rahatça okuyabilecek şekilde hem sade hemde basit anlaşılır şekilde yazdım.Bir klasör oluşturalım ben Unit-Test adında bir klasör oluşturdum. Console ekranını açıp o klasöre girelim. cd cd diyerek.

Kod:
[COLOR="SeaGreen"][B]npm init[/B][/COLOR]

yazdıktan sonra yönelgeleri takip edelim ve bir adet klasörümüzde package.json oluşacak. Şimdi ise sırasıyla kurulumlara başlıyalım.

Kod:
[COLOR="SeaGreen"][B]npm install express --save[/B][/COLOR]
Kod:
[COLOR="seagreen"][B]npm install body-parser --save[/B][/COLOR]
Kod:
[COLOR="seagreen"][B]npm install chai -D[/B][/COLOR]
Kod:
[COLOR="seagreen"][B]npm install chai-http -D[/B][/COLOR]
Kod:
[COLOR="seagreen"][B]npm install mocha -D[/B][/COLOR]
Kod:
[COLOR="seagreen"][B]npm install nodemon -D[/B][/COLOR]


Burada zaten express bizim kullandığımız nodejs frameworkü, body-parser post methodundan gelen veriler için. Chai, chai-http, mocha ise test için gerekli modüller mocha testimizi çalıştırmak için chai chai-http ise test bunun ile yazacağız test kodlarımızı. bunları ve nodemon devdependencies olarak kurdum. Nodemon ise yazdığımız projeyi tekrar tekrar sunucuyu aç kapat derdinden kurtaran modül.

Package.json şöyle görünecek sizde tabi ben bazı eklemeler yaptım ama aşağı yukarı böyle görünecek.

45vKcW.png


Şimdi gelelim restful api yazmaya. index.js dosyası oluşturalım ve içine bunları yazalım. Basit ve anlaşılır bir şekilde yazdım kodları express ile ilgilenen hemen anlayacaktır zaten.

Kod:
[COLOR="white"]const express = require('express');[/COLOR]
[COLOR="white"]const app = express();[/COLOR]
[COLOR="SeaGreen"]// Posttan gelen verileri alabilmek için lazım olan kütüphane[/COLOR]
[COLOR="White"]const bodyParser = require('body-parser');[/COLOR]
[COLOR="white"]
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());[/COLOR]

[COLOR="SeaGreen"]// Anasayfa (/) bir json çıktısı gönderiyoruz. {hello: 'Hello world'}[/COLOR]
[COLOR="White"]app.get('/', (req, res) => {
  res.json({hello: 'Hello world'});
});[/COLOR]

[COLOR="SeaGreen"]// Ekleme (/add) Post methodu ile data göndermesi için uyarı mesajı veriyoruz.[/COLOR]
[COLOR="White"]app.get('/add', (req, res) => {
  res.json({Açıklama: 'Bu dizinin postuna data gönderin.'});
});[/COLOR]

[COLOR="SeaGreen"]// Ekleme (/add) Burada ise post gönderiyor bize data adında bir key value şeklinde. {data: 'example'}[/COLOR]
[COLOR="white"]app.post('/add', (req, res) => {
  let { data } = req.body;
  // Gönderdiği veriyi burada gösteriyoruz.
  res.json({text: data});
});
[/COLOR]
[COLOR="SeaGreen"]// http://localhost:3000[/COLOR]
[COLOR="white"]app.listen(3000);[/COLOR]

[COLOR="White"]module.exports = app;[/COLOR]

Şimdi sunucumuzu çalıştıralım. Package.json dosyasımızda scripts kısmına start, ve start:dev şeklinde yukarıdaki resimdeki gibi eklemeyi unutmayın.

Kod:
[COLOR="White"][B]npm run start:dev[/B][/COLOR]

Sunucumuz çalıştı. Bu api kendiniz test etmek için postman adlı programı kullanabilirsiniz. Konuda daha fazla detaylı anlatmayacağım restful api yoksa konu çok uzuyor sorunuz olursa özelden veya yorum olarak belirtin.

Unit test yazmaya başlayalım.

İlk önce test adında bir klasör oluşturalım. Ben index klasörü için test yazacağımdan index.test.js oluşturdum.

Kod:
[COLOR="white"]const chai = require('chai');
const chaiHttp = require('chai-http');

chai.use(chaiHttp);
const should = chai.should();
const server = require('../index');[/COLOR]

Chai, chai-http import ettik chai should ise şu şu olmalı gibisinden demek oluyor mesela a obje olmalı array olmalı gibi. En sonda serverimizi dahil ettik yukarıda yazdığımız api dosyasını yani

Şimdi projemizi küçük parçalara ayırarak o küçük parçalara testler yazacağız. Benim restful api 3 kısım mevcut.

Get(/) anasayfada bir json çıktısı var.
Get(/add) Post methoduna data göndermesini söylüyoruz.
Post(/add) post mehodu ile gönderdiği veriyi ekranda gösteriyoruz.

3 adet test kodu(blogu) yazacağım. 1. sunucu çalışıyor mu yani / dizinine girdiğinde status yani durumu 200 mü bunun kontrolü.

2. ise Get(/) Anasayfada bir obje varmı hatırlarsanız {hello: 'Hello world'} şöyle bir obje olacaktı.

3. ise Post(/add) bir data göndereceğiz ve bu data sayfada gösteriliyor mu diye kontrol edeceğiz o zaman başlıyalım.

Bir tane en dışta olacak şekilde describe oluşturalım. Yazdığınız testlere isim vermeye ve içinde it yani test kodlarınız yer alıyor.


Kod:
[COLOR="white"]describe('Node Server', () => {
  describe('GET(/) Home Page', () => {
    it('Home page status 200?', (done) => {
      chai.request(server).get('/').end((err, res) => {
        res.should.have.status(200)
        done();
      });
    });
  });
});[/COLOR]

Node Server adında bir describe var. Bu describe içine bir tane daha describe oluşturdum. it ile bir açıklama ve test kodunu yazıyoruz. chai.request(server).get('/').end((err, res) chai bir request yolluyor bu get methodu en son olarak err ve res callback döndürüyor. bu res yani çıktı should.have.status(200) status durumu 200 sahip mi 200 mü diye soruyor ve 200 ise done(); diyerek testten geçiyor eğer 200 değilde 404 ise bunu size bildiriyor.

Package.json scripts kısmına

Kod:
[COLOR="White"]"test": "mocha --exit --recursive"[/COLOR],

yazın buradaki mocha yazdığımız testleri çalıştırıyor. Test klasörünün içindeki --exit ise test bittikten sonra console ekranından çıkıyor --recursive ise varsa test klasörünün içinde başka klasörler içlerine tek tek bak diyor. Yukarıdaki package.json yazdığım gibi yazınız.

Şimdi testimizi deniyelim.


Kod:
[COLOR="white"]npm test[/COLOR]

BQkWpb.png


Benim testim görüldüğü gibi geçti. Şimdi ise 2. aşamayı anasayfada bir obje varmı kontrol edelim.

Kod:
[COLOR="white"]describe('GET(/) Home Page', () => {
    it('Are there objects on the homepage?', (done) => {
      chai.request(server).get('/').end((err, res) => {
        res.body.should.be.a('object');
        done();
      });
    });
  });[/COLOR]

chai yine bir request yolluyor / dizinine ve dönen callbackden res.body diyerek kullanıcıya gösterilen '{hello: 'Hello world'} bizimkisi böyle' sahip mi bir objeye diyor array yazarsanız çıktınız array olmak zorundadır. Yoksa testten geçemez.

Şimdi ise 3. testimiz /add dizinine bir data gönderip bunu json olarak geri döndürmüş mü diye bakalım.


Kod:
[COLOR="white"]describe('POST(/add)', () => {
    it('add data', (done) => {
      chai.request(server).post('/add').send({data: 'example'}).end((err, res, req) => {
        res.body.should.have.property('text');
        done();
      });
    });
  });[/COLOR]

chai bir request atıyor /add dizine post methodu ile send ile data yolluyoruz obje yani burada ben data adında bir key value şeklinde değer istediğim için data yazmak zorundayım. Data yerine başka birşey yazarsam testten geçemeyecek. en sonda ise res.body ile gösterdiğin property sahip mi varmı yani text içinde Yani ben /add dizinine giriyorum post olarak key data value ise istediğiniz değer olacak şekilde veri istiyorum ve bunu gösterirken ise text: girdiğiniz değer şekilde gösteriyorum bu yüzden burada bir keyi data olacak şekilde obje yolladım ve bunu gösteririken ise text şeklinde gösterdiğimden bu gösterdiğim içinde texti aradım.

Umarım anlatabilmişimdir baya zorlandım unit testi anlatırken :). Şimdi ise şöyle bir tekrar bakalım ve en başta yaptığımız sunucu status durumu yani 200 mü describe before yani ben baştaki node server describe hemen altına yazalım. Before en başta ben çalışacağım sonra altımdakiler demek. :)

Kod:
[COLOR="white"]describe('Node Server', () => {
  
  before((done) => {
    chai.request(server).get('/').end((err, res) => {
      res.should.have.status(200);
      done();
    });
  })

  describe('GET(/) Home Page', () => {
    it('Are there objects on the homepage?', (done) => {
      chai.request(server).get('/').end((err, res) => {
        res.body.should.be.a('object');
        done();
      });
    });
  });

  describe('POST(/add)', () => {
    it('add data', (done) => {
      chai.request(server).post('/add').send({data: 'example'}).end((err, res, req) => {
        res.body.should.have.property('text');
        done();
      });
    });
  });

});[/COLOR]

Before içinde it felan yok sadece test kodlarınız yer alıyor. İlk önce before çalışır sonra altındaki test kodları eğer before patlar ise dğerlerine bakılmadan kullanıcıya bildirir. Bakın tüm testlerden geçtim.

8Ip0HP.png


Şimdi ise bir hata yapalım mesela before status kodu 200 mü yerine 404 yazalım.

aTjN93.png


Bana 200 geldi sen 404 istiyorsun olmaz böyle diyor. Umarım anlaşılır bir şekilde yazmışımdır ciddi anlamda zorlandım çünkü yazarken yaklaşık 2.30 saattir yazıyorum konuyu. Umarım anlamışsınızdır ki hemen anlamak zor ama ingilizcesi biraz biraz olan birisi anlacaktır. Should have zaten ingilizce bilgisi gerektiren şeyler :) Konuda anlamadığınız yeri mutlaka sorun çekinmeyin. Sağlıcakla kalın...
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.