[NODE JS] Mocha ve Chai ile Test Yazma
Selam arkadaşlar, bu yazıda Node.js dünyasının köklü test framework'ü Mocha ve onunla sıklıkla kullanılan assertion kütüphanesi Chai'dan bahsedeceğim. Jest çok popüler olsa da Mocha hâlâ birçok projede tercih ediliyor ve iş mülakatlarında karşınıza çıkabiliyor. Ben de birkaç projemde Mocha kullandım, özellikle esnekliğini seviyorum.
Mocha, Jest'ten farklı olarak minimalist bir yapıya sahiptir. Kendi başına bir assertion kütüphanesi içermez, bu yüzden Chai gibi harici bir kütüphane kullanmanız gerekir. Bu ilk başta dezavantaj gibi görünse de aslında size esneklik sağlar. İstediğiniz assertion stilini seçebilirsiniz.
Chai üç farklı assertion stili sunar: should, expect ve assert. Should stili BDD yaklaşımına daha yakındır ve okunabilirliği yüksektir. Expect stili de BDD'ye uygundur ama should gibi prototype'a müdahale etmez. Assert stili ise TDD yaklaşımına daha yakındır ve Node.js'in dahili assert modülüne benzer. Ben genellikle expect stilini tercih ederim çünkü hem okunabilir hem de güvenlidir.
Mocha'nın describe ve it blokları Jest'tekine çok benzer. describe ile test grupları oluşturursunuz, it ile ise tekil testleri yazarsınız. before, after, beforeEach, afterEach hook'ları da mevcuttur. Mocha'nın güzel yanlarından biri, testleri seri veya paralel çalıştırma seçeneği sunmasıdır. Büyük projelerde paralel çalıştırma ciddi zaman kazandırır.
Async test desteği Mocha'da birkaç şekilde sağlanır. done callback'i kullanabilirsiniz, Promise döndürebilirsiniz veya async/await kullanabilirsiniz. done callback'i kullanırken dikkatli olun, done'ı çağırmayı unutursanız test timeout'a düşer. Ben bu yüzden async/await tercih ederim, daha temiz ve hataya daha az açık.
Mocha'nın reporter sistemi de oldukça zengindir. spec, dot, nyan, landing gibi dahili reporter'lar vardır. Ayrıca mochawesome gibi harici reporter'larla HTML formatında güzel test raporları oluşturabilirsiniz. CI/CD pipeline'larında bu raporlar çok işe yarar.
Test organizasyonu konusunda da Mocha esnektir. Test dosyalarınızı istediğiniz dizin yapısında organize edebilirsiniz. .mocharc.yml dosyası ile konfigürasyon yapabilirsiniz. Glob pattern'ler ile hangi dosyaların test olarak çalışacağını belirleyebilirsiniz.
Skip ve only özellikleri de testlerinizi yönetirken çok işe yarar. it.skip ile bir testi geçici olarak devre dışı bırakabilirsiniz. it.only ile sadece belirli bir testi çalıştırabilirsiniz. Bu özellikle debugging yaparken harikadır ama commit etmeden only'leri kaldırmayı unutmayın, yoksa CI'da sadece o test çalışır.
Kod:
// stringUtils.js - Test edilecek yardımcı fonksiyonlar
function buyukHarfYap(str) {
if (typeof str !== 'string') {
throw new TypeError('Parametre string olmalıdır');
}
return str.toUpperCase();
}
function kelimeSayisi(str) {
if (typeof str !== 'string') {
throw new TypeError('Parametre string olmalıdır');
}
if (str.trim() === '') return 0;
return str.trim().split(/\s+/).length;
}
function terstenYaz(str) {
if (typeof str !== 'string') {
throw new TypeError('Parametre string olmalıdır');
}
return str.split('').reverse().join('');
}
function palindromMu(str) {
if (typeof str !== 'string') {
throw new TypeError('Parametre string olmalıdır');
}
const temiz = str.toLowerCase().replace(/[^a-z0-9]/g, '');
return temiz === temiz.split('').reverse().join('');
}
function kisalt(str, maxUzunluk) {
if (typeof str !== 'string') {
throw new TypeError('Parametre string olmalıdır');
}
if (str.length <= maxUzunluk) return str;
return str.substring(0, maxUzunluk - 3) + '...';
}
module.exports = { buyukHarfYap, kelimeSayisi, terstenYaz, palindromMu, kisalt };
// stringUtils.test.js - Mocha + Chai ile test
// npm install --save-dev mocha chai
// package.json: "scripts": { "test": "mocha" }
const { expect } = require('chai');
const {
buyukHarfYap,
kelimeSayisi,
terstenYaz,
palindromMu,
kisalt
} = require('./stringUtils');
describe('String Yardımcı Fonksiyonları', function () {
describe('buyukHarfYap()', function () {
it('küçük harfleri büyük harfe çevirmeli', function () {
expect(buyukHarfYap('merhaba')).to.equal('MERHABA');
});
it('zaten büyük olan harfleri korumalı', function () {
expect(buyukHarfYap('ABC')).to.equal('ABC');
});
it('string olmayan değerde hata fırlatmalı', function () {
expect(function () { buyukHarfYap(123); }).to.throw(TypeError);
});
it('boş string için boş string döndürmeli', function () {
expect(buyukHarfYap('')).to.equal('');
});
});
describe('kelimeSayisi()', function () {
it('kelimeleri doğru saymalı', function () {
expect(kelimeSayisi('Node.js çok güzel')).to.equal(3);
});
it('fazla boşlukları görmezden gelmeli', function () {
expect(kelimeSayisi(' bir iki üç ')).to.equal(3);
});
it('boş string için 0 döndürmeli', function () {
expect(kelimeSayisi('')).to.equal(0);
});
it('tek kelime için 1 döndürmeli', function () {
expect(kelimeSayisi('merhaba')).to.equal(1);
});
});
describe('terstenYaz()', function () {
it('stringi ters çevirmeli', function () {
expect(terstenYaz('merhaba')).to.equal('abahrem');
});
it('boş string için boş string döndürmeli', function () {
expect(terstenYaz('')).to.equal('');
});
it('tek karakteri aynı döndürmeli', function () {
expect(terstenYaz('a')).to.equal('a');
});
});
describe('palindromMu()', function () {
it('palindrom olan stringi tanımalı', function () {
expect(palindromMu('aba')).to.be.true;
});
it('palindrom olmayan stringi reddetmeli', function () {
expect(palindromMu('merhaba')).to.be.false;
});
it('büyük/küçük harf farkını görmezden gelmeli', function () {
expect(palindromMu('Aba')).to.be.true;
});
});
describe('kisalt()', function () {
it('uzun stringi kısaltmalı ve ... eklemeli', function () {
expect(kisalt('Bu bir uzun cümledir', 10)).to.equal('Bu bir...');
});
it('kısa stringi olduğu gibi döndürmeli', function () {
expect(kisalt('kısa', 10)).to.equal('kısa');
});
it('kısaltılan stringin uzunluğu maxUzunluk olmalı', function () {
const result = kisalt('Bu çok uzun bir metin parçasıdır', 15);
expect(result).to.have.lengthOf.at.most(15);
});
});
});
// .mocharc.yml örneği
// spec: test/**/*.test.js
// timeout: 5000
// reporter: spec
// recursive: true
Mocha ve Chai ikilisi yıllardır Node.js ekosisteminde kendini kanıtlamış araçlardır. Jest'e kıyasla daha fazla konfigürasyon gerektirir ama bu esneklik büyük projelerde avantaja dönüşür. Hangi framework'ü seçerseniz seçin, önemli olan test yazmayı alışkanlık haline getirmektir. Hadi kolay gelsin!
Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 1
- Görüntüleme
- 7
- Cevaplar
- 1
- Görüntüleme
- 11
- Cevaplar
- 1
- Görüntüleme
- 14
- Cevaplar
- 1
- Görüntüleme
- 10
- Cevaplar
- 1
- Görüntüleme
- 12