Test Etme
Deno, hem JavaScript hem de TypeScript için test yazma ve çalıştırma amacıyla yerleşik bir test çalıştırıcısı sağlar. Bu, kodunuzun güvenilir olduğunu ve ek bağımlılık veya araçlar yüklemeden beklenildiği gibi çalıştığını sağlamayı kolaylaştırır. deno test
çalıştırıcısı, her test için izinler üzerinde hassas kontrol sağlar ve kodun beklenmedik bir şey yapmadığından emin olur.
Yerleşik test çalıştırıcısına ek olarak, Deno ile JS ekosisteminden Jest, Mocha veya AVA gibi diğer test çalıştırıcılarını da kullanabilirsiniz. Ancak bu belgede bunları ele almayacağız.
Test Yazma
Deno'da bir testi tanımlamak için Deno.test()
fonksiyonunu kullanırsınız. İşte bazı örnekler:
import { assertEquals } from "jsr:@std/assert";
Deno.test("basit test", () => {
const x = 1 + 2;
assertEquals(x, 3);
});
import { delay } from "jsr:@std/async";
Deno.test("asenkron test", async () => {
const x = 1 + 2;
await delay(100);
assertEquals(x, 3);
});
Deno.test({
name: "dosya okuma testi",
permissions: { read: true },
fn: () => {
const data = Deno.readTextFileSync("./somefile.txt");
assertEquals(data, "beklenen içerik");
},
});
Eğer "jest benzeri" expect
stilinde doğrulamalar tercih ediyorsanız, Deno standart kütüphanesi expect
fonksiyonunu assertEquals
yerine kullanabileceğiniz bir alternatif sunar:
import { expect } from "jsr:@std/expect";
import { add } from "./add.js";
Deno.test("toplama fonksiyonu iki sayıyı doğru toplar", () => {
const result = add(2, 3);
expect(result).toBe(5);
});
Testleri Çalıştırma
Testlerinizi çalıştırmak için deno test
alt komutunu kullanın.
Dosya adı veya dizin adı olmadan çalıştırıldığında, bu alt komut mevcut dizindeki (özellikle) tüm testleri otomatik olarak bulur ve çalıştırır. {*_,*.,}test.{ts, tsx, mts, js, mjs, jsx}
glob desenine uyan.
# Mevcut dizindeki ve tüm alt dizinlerdeki tüm testleri çalıştır
deno test
# util dizinindeki tüm testleri çalıştır
deno test util/
# sadece my_test.ts'yi çalıştır
deno test my_test.ts
# Test modüllerini paralel olarak çalıştır
deno test --parallel
# Deno.args'ta görünür olan test dosyasına ek argümanlar geç
deno test my_test.ts -- -e --foo --bar
# Deno'nun dosya sisteminden okuma yapmasına izin ver, bu yukarıdaki son testin geçmesi için gereklidir
deno test --allow-read my_test.ts
Test Aşamaları
Deno, testleri daha küçük, yönetilebilir parçalara ayırmanıza olanak tanıyan test aşamalarını destekler. Bu, bir test içerisindeki kuruluma ve temizlemeye yönelik işlemler için faydalıdır:
Deno.test("veritabanı işlemleri", async (t) => {
using db = await openDatabase();
await t.step("kullanıcı ekle", async () => {
// Kullanıcı ekleme mantığı
});
await t.step("kitap ekle", async () => {
// Kitap ekleme mantığı
});
});
Komut satırı filtreleme
Deno, --filter
seçeneğini kullanarak belirli testleri veya test gruplarını çalıştırmanıza olanak tanır. Bu seçenek, test adlarıyla eşleşmek üzere bir dize veya bir desen kabul eder. Filtreleme, adımlar üzerinde etkili olmaz; eğer bir test adı filtreyle eşleşiyorsa, tüm adımları çalıştırılır.
Aşağıdaki testlere göz atın:
Deno.test("my-test", () => {});
Deno.test("test-1", () => {});
Deno.test("test-2", () => {});
Dize ile filtreleme
Adında "my" kelimesini içeren tüm testleri çalıştırmak için:
deno test --filter "my" tests/
Bu komut, "my" kelimesini içerdiği için my-test
'i çalıştırır.
Desen ile filtreleme
Belirli bir desene uyan testleri çalıştırmak için:
deno test --filter "/test-*\d/" tests/
Bu komut, test-1
ve test-2
testlerini çalıştırır çünkü test-*
deseni ile bir rakamı takip eder.
Desen (regüler ifade) kullandığınızı belirtmek için filtre değerini kesme işaretleri /
içinde sarın, JavaScript’in regüler ifadeleri için olan sözdiziminde olduğu gibi.
Yapılandırma dosyasında test dosyalarını dahil etme ve hariç tutma
Ayrıca, Deno yapılandırma dosyasında
dahil edilecek veya hariç tutulacak yolları belirterek testleri filtreleyebilirsiniz.
Örneğin, sadece src/fetch_test.ts
ve src/signal_test.ts
’yi test etmek ve out/
içinde her şeyi hariç tutmak isterseniz:
{
"test": {
"include": [
"src/fetch_test.ts",
"src/signal_test.ts"
]
}
}
Ya da daha muhtemel bir şekilde:
{
"test": {
"exclude": ["out/"]
}
}
Test tanımı seçimi
Deno, test tanımlarının içinde testleri seçmek için iki seçenek sunar: testleri göz ardı etme ve belirli testlere odaklanma.
Testleri Göz Ardı Etme/Atlama
Belirli koşullara göre bazı testleri göz ardı edebilirsiniz. Test tanımındaki ignore
boolean'ını kullanarak. ignore
true
olarak ayarlandığında, test atlanır. Bu, örneğin bir testin yalnızca belirli bir işletim sisteminde çalışmasını istiyorsanız kullanışlıdır.
Deno.test({
name: "macOS özelliğini yap",
ignore: Deno.build.os !== "darwin", // Bu test, macOS'ta çalışmıyorsa göz ardı edilecektir
fn() {
// Burada MacOS özelliğini yap
},
});
Koşul geçmeden bir test atlamak isterseniz, Deno.test
nesnesinden ignore()
fonksiyonunu kullanabilirsiniz:
Deno.test.ignore("benim testim", () => {
// test kodunuz
});
Sadece Belirli Testleri Çalıştırma
Belirli bir teste odaklanmak ve diğerlerini göz ardı etmek istiyorsanız, only
seçeneğini kullanabilirsiniz. Bu, test çalıştırıcısına yalnızca only
ayarları true
olan testleri çalıştırmasını söyler. Birden fazla test bu seçenekle ayarlanabilir. Ancak, herhangi bir test sadece only
ile işaretlenmişse, genel test çalıştırması her zaman başarısız olur, çünkü bu yalnızca hata ayıklamak için geçici bir önlemdir.
Deno.test.only("benim testim", () => {
// bazı test kodu
});
veya
Deno.test({
name: "Yalnızca bu testi çalıştır",
only: true, // Yalnızca bu test çalıştırılacak
fn() {
// karmaşık şeyler burada test edilecek
},
});
Hızlı Hata Başlatma
Uzun süren bir test süitiniz varsa ve ilk hata da durmasını istiyorsanız, test süitini çalıştırırken --fail-fast
bayrağını belirtebilirsiniz.
deno test --fail-fast
Bu, test çalıştırıcısının ilk test hatasından sonra çalıştırmayı durdurmasını sağlar.
Raporlayıcılar
Deno, test çıktısını biçimlendirmek için üç yerleşik raporlayıcı içerir:
pretty
(varsayılan): Ayrıntılı ve okunabilir bir çıktı sağlar.dot
: Test sonuçlarını hızlı bir şekilde görmek için yaralı, kısa bir çıktı sunar.junit
: CI/CD araçlarıyla entegrasyon için yararlı olan JUnit XML formatında çıktı üretir.
Hangi raporlayıcının kullanılacağını --reporter
bayrağı ile belirtebilirsiniz:
# Varsayılan güzel raporlayıcıyı kullan
deno test
# Kısa çıktı için nokta raporlayıcısını kullan
deno test --reporter=dot
# JUnit raporlayıcısını kullan
deno test --reporter=junit
Ayrıca, --junit-path
bayrağını kullanarak JUnit raporunu bir dosyaya yazdırırken terminalde okunabilir bir çıktı alabilirsiniz:
deno test --junit-path=./report.xml
Casusluk, sahteleme (test ikizleri), kesme ve zamanı taklit etme
Deno Standart Kütüphanesi
casusluk, sahteleme ve kesme ile ilgili test yazmanıza yardımcı olacak bir dizi fonksiyon sağlar. Bu utiliteler hakkında daha fazla bilgi için @std/testing belgesine göz atabilirsiniz.
Kapsam
Deno, deno test
başlatırken --coverage
bayrağını belirttiğinizde kodunuz için test kapsamını bir dizinde toplar. Bu kapsam bilgisi, yüksek doğruluk sağlamak için doğrudan V8 JavaScript motorundan alınır.
Bu, ardından iç formattan lcov
gibi iyi bilinen formatlara dönüştürülebilir. Bunun için deno coverage
aracını kullanabilirsiniz.
Davranışa Dayalı Geliştirme
@std/testing/bdd modülüyle testlerinizi, Jasmine, Jest ve Mocha gibi diğer JavaScript test çatıları tarafından kullanılan testleri gruplandırma ve kurulum/temizleme kancaları ekleme konusunda tanıdık bir biçimde yazabilirsiniz.
describe
fonksiyonu, birden fazla ilgili testi gruplandıran bir blok oluşturur. it
fonksiyonu bir bireysel test durumunu kaydeder. Örneğin:
import { describe, it } from "jsr:@std/testing/bdd";
import { expect } from "jsr:@std/expect";
import { add } from "./add.js";
describe("toplama fonksiyonu", () => {
it("iki sayıyı doğru toplar", () => {
const result = add(2, 3);
expect(result).toBe(5);
});
it("negatif sayıları işler", () => {
const result = add(-2, -3);
expect(result).toBe(-5);
});
});
Bu fonksiyonlar ve kancalar hakkında daha fazla bilgi için JSR belgesine göz atın.
Belge Testleri
Deno, JSDoc veya markdown dosyalarında yazılmış kod parçacıklarını değerlendirmenize olanak tanır. Bu, belgelerinizdeki örneklerin güncel ve işlevsel olmasını sağlar.
Örnek kod blokları
/**
* # Örnekler
*
* ```ts
* import { assertEquals } from "jsr:@std/assert/equals";
*
* const sum = add(1, 2);
* assertEquals(sum, 3);
* ```
*/
export function add(a: number, b: number): number {
return a + b;
}
Üçlü ters tırnaklar, kod bloklarının başlangıcını ve sonunu işaretler; dil, kaynak belgesinin medya türüne göre tahmin edilir.
deno test --doc example.ts
Yukarıdaki komut, bu örneği çıkartacak, örnek görünümü aşağıdaki gibi görünmesini sağlayan bir test durumuna dönüştürecektir:
import { assertEquals } from "jsr:@std/assert/equals";
import { add } from "file:///path/to/example.ts";
Deno.test("example.ts$4-10.ts", async () => {
const sum = add(1, 2);
assertEquals(sum, 3);
});
ve ardından belge modülüyle aynı dizinde yaşayan bağımsız bir modül olarak çalıştırılacaktır.
JSDoc ve markdown dosyalarını çalıştırmadan daha önce tür kontrolü yapmak isterseniz, deno check
komutunu --doc
seçeneği ile (JSDoc için) veya --doc-only
seçeneği ile (markdown için) kullanabilirsiniz.
Dışa Aktarılan öğeler otomatik olarak içe aktarılır
Yukarıda üretilen test koduna bakıldığında, orijinal kod bloğunda bulunmasa bile add
işlevini içe aktaran import
ifadesini içerdiğini göreceksiniz. Bir modülü belgelendirirken, modülden dışa aktarılan herhangi bir öğe, aynı isimle üretilen test koduna otomatik olarak dahil edilir.
Diyelim ki elimizde şu modül var:
/**
* # Örnekler
*
* ```ts
* import { assertEquals } from "jsr:@std/assert/equals";
*
* const sum = add(ONE, getTwo());
* assertEquals(sum, 3);
* ```
*/
export function add(a: number, b: number): number {
return a + b;
}
export const ONE = 1;
export default function getTwo() {
return 2;
}
Bu, aşağıdaki test durumuna dönüştürülecektir:
import { assertEquals } from "jsr:@std/assert/equals";
import { add, ONE }, getTwo from "file:///path/to/example.ts";
Deno.test("example.ts$4-10.ts", async () => {
const sum = add(ONE, getTwo());
assertEquals(sum, 3);
});
Kod bloklarını atlama
Kod bloklarının değerlendirilmesini, ignore
niteliğini ekleyerek atlayabilirsiniz.
/**
* Bu kod bloğu çalıştırılmayacaktır.
*
* ```ts ignore
* await sendEmail("deno@example.com");
* ```
*/
export async function sendEmail(to: string) {
// verilen adrese e-posta gönder...
}
Sanitizer'lar
Test çalıştırıcısı, testlerin makul ve beklenen bir şekilde davranmasını sağlamak için çeşitli sanitizer'lar sunar.
Kaynak sanitizer'ı
Kaynak sanitizer'ı, bir test sırasında oluşturulan tüm I/O kaynaklarının kapatıldığından emin olur, bu da sızıntıları önler.
I/O kaynakları, Deno.FsFile
tutacakları, ağ bağlantıları, fetch
gövdesi, zamanlayıcılar ve otomatik olarak çöp toplayıcı tarafından alınmayan diğer kaynaklardır.
İşiniz bittiğinde her zaman kaynakları kapatmalısınız. Örneğin, bir dosyayı kapatmak için:
const file = await Deno.open("hello.txt");
// Dosyayla bir şeyler yap
file.close(); // <- Done geldiğinizde her zaman dosyayı kapatın
Bir ağ bağlantısını kapatmak için:
const conn = await Deno.connect({ hostname: "example.com", port: 80 });
// Bağlantıyla bir şeyler yap
conn.close(); // <- İşiniz bittiğinde her zaman bağlantıyı kapatın
Bir fetch
gövdesini kapatmak için:
const response = await fetch("https://example.com");
// Yanıtla bir şeyler yap
await response.body?.cancel(); // <- Eğer başka bir şekilde tüketmediyseniz, her zaman vücudu teslim etmeden önce iptal edin
Bu sanitizer varsayılan olarak etkindir, ancak bu test içinde sanitizeResources: false
ile devre dışı bırakılabilir:
Deno.test({
name: "sızıntı kaynak testi",
async fn() {
await Deno.open("hello.txt");
},
sanitizeResources: false,
});
Asenkron işlem sanitizer'ı
Asenkron işlem sanitizer'ı, bir testte başlatılan tüm asenkron işlemlerin, test bitmeden tamamlandığından emin olur. Bu önemlidir çünkü bir asenkron işlem beklenmiyorsa, test, işlem tamamlanmadan önce sona erer ve test, işlemin aslında başarısız olmasına rağmen başarılı olarak işaretlenir.
Her zaman testlerinizde tüm asenkron işlemleri beklemelisiniz. Örneğin:
Deno.test({
name: "asenkron işlem testi",
async fn() {
await new Promise((resolve) => setTimeout(resolve, 1000));
},
});
Bu sanitizer varsayılan olarak etkindir, ancak sanitizeOps: false
ile devre dışı bırakılabilir:
Deno.test({
name: "sızıntı işlem testi",
fn() {
crypto.subtle.digest(
"SHA-256",
new TextEncoder().encode("a".repeat(100000000)),
);
},
sanitizeOps: false,
});
Çıkış sanitizer'ı
Çıkış sanitizer'ı, test edilen kodun Deno.exit()
çağrısı yapmadığından emin olur, bu da yanlış bir test başarısını işaret edebilir.
Bu sanitizer varsayılan olarak etkindir, ancak sanitizeExit: false
ile devre dışı bırakılabilir.
Deno.test({
name: "yanlış başarı",
fn() {
Deno.exit(0);
},
sanitizeExit: false,
});
// Bu test asla çalışmaz, çünkü süreç "yanlış başarı" testinin sırasında çıkar
Deno.test({
name: "başarısız test",
fn() {
throw new Error("bu test başarısız olur");
},
});
Snapshot testi
Deno Standart Kütüphanesi
, geliştiricilerin değerleri referans anlık görüntüleriyle karşılaştırarak test yazmasına olanak tanıyan bir anlık görüntü modülü içerir. Bu anlık görüntüler, orijinal değerlerin serileştirilmiş temsilleridir ve test dosyalarıyla birlikte saklanır.
Anlık görüntü testi, çok az kodla geniş bir hata yelpazesini yakalamayı mümkün kılar. Özellikle, neyin teyit edilmesi gerektiğini tam olarak ifade etmenin zor olduğu, aşırı miktarda kod gerektirmeden veya bir testin yaptığı doğrulamaların sık sık değişmesi bekleniyorsa yararlıdır.