API'yi Test Etme
Tümleştirme testleri
API'yi Test Etme, CoddyKit'te ücretsiz bir Learn Rust Coding dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Learn Rust Coding öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Learn Rust Coding kursu toplamda 4 dersten oluşur.
Bir API Neden Test Edilir?
Testler, uç noktaların doğru davrandığından ve kodu değiştirirken çalışmaya devam ettiğinden emin olmanızı sağlar. Bir REST API için en değerli testler tümleştirme testleridir: gerçek yönlendiriciyi uçtan uca çalıştırır, istek gönderir ve yanıtları doğrular.
Bu derste birim testleri, Tower'ın oneshot yöntemi ve tam tümleştirme testleri ele alınmaktadır.
Saf Mantık için Birim Testleri
Doğrulama gibi ağa dokunmayan mantık, yalnızca Rust birim testleriyle test edilebilir. Bunları kodun yanındaki bir #[cfg(test)] modülüne yerleştirin. Bu testler cargo test ile hızlı çalışır.
fn validate_title(title: &str) -> bool {
!title.trim().is_empty()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rejects_empty() {
assert!(!validate_title(" "));
assert!(validate_title("buy milk"));
}
}Eşzamansız Testler
İşleyiciler eşzamansızdır; bu nedenle await kullanan test işlevlerinin bir çalışma zamanı üzerinde çalışması gerekir. #[test] yerine #[tokio::test] kullanın. Bu, söz konusu test için bir Tokio çalışma zamanı başlatır ve eşzamansız kodu .await ile çağırmanızı sağlar.
async fn add(a: i32, b: i32) -> i32 { a + b }
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn adds() {
assert_eq!(add(2, 3).await, 5);
}
}Ağ Olmadan Test Etme
Axum yönlendiricileri Tower'ın Service özelliğini uygular; bu nedenle bir bağlantı noktasına bağlamadan istekleri doğrudan yönlendiriciye verebilirsiniz. oneshot yöntemi tek bir Request alır ve Response döndürür. Bu, tümleştirme testlerini hızlı ve belirleyici hâle getirir.
// dev-dependencies needed: tower (for ServiceExt), http-body-util
use axum::{Router, routing::get};
use axum::http::{Request, StatusCode};
use axum::body::Body;
use tower::ServiceExt; // brings in oneshot
async fn check() {
let app = Router::new().route("/health", get(|| async { "ok" }));
let res = app
.oneshot(Request::builder().uri("/health").body(Body::empty()).unwrap())
.await.unwrap();
assert_eq!(res.status(), StatusCode::OK);
}Durum Kodunu Doğrulama
Çoğu testin kontrol ettiği ilk şey HTTP durumudur. Eksik bir kaynak 404, başarılı bir oluşturma işlemi 201 ve hatalı bir gövde 400 döndürmelidir. Rota için bir istek oluşturun ve res.status() değerini beklenen kodla karşılaştırın.
use axum::http::{Request, StatusCode};
use axum::body::Body;
use tower::ServiceExt;
async fn missing_returns_404(app: axum::Router) {
let res = app
.oneshot(Request::builder()
.uri("/todos/999")
.body(Body::empty()).unwrap())
.await.unwrap();
assert_eq!(res.status(), StatusCode::NOT_FOUND);
}Yanıt Gövdesini Okuma
JSON'u doğrulamak için yanıt gövdesini baytlarda toplayıp serileştirmesini geri alın. http_body_util::BodyExt::collect yardımcı işlevi gövdeyi toplar; ardından serde_json bunu alan düzeyinde doğrulamalar yapabilmeniz için modelinize ayrıştırır.
use http_body_util::BodyExt;
async fn read_json(res: axum::http::Response<axum::body::Body>) {
let bytes = res.into_body().collect().await.unwrap().to_bytes();
let todo: serde_json::Value = serde_json::from_slice(&bytes).unwrap();
assert_eq!(todo["done"], false);
}JSON Gövdesi Gönderme
Bir POST isteğini test etmek için JSON gövdeli ve doğru içerik türü başlığına sahip bir istek oluşturun. Girdi yapınızı serileştirin, content-type: application/json değerini ayarlayın ve oneshot üzerinden gönderin.
use axum::http::{Request, StatusCode, header};
use axum::body::Body;
use tower::ServiceExt;
async fn create_returns_201(app: axum::Router) {
let body = serde_json::json!({ "title": "test" }).to_string();
let res = app
.oneshot(Request::builder()
.method("POST").uri("/todos")
.header(header::CONTENT_TYPE, "application/json")
.body(Body::from(body)).unwrap())
.await.unwrap();
assert_eq!(res.status(), StatusCode::CREATED);
}Yeniden Kullanılabilir Test Uygulaması Oluşturucusu
Her test temiz bir durumdan başlamalıdır. Yeni bir bellek içi veya test veritabanına sahip, yeni bir yönlendirici oluşturan bir yardımcı işlev yazın. Bu işlevin her testte çağrılması testleri birbirinden yalıtır; böylece bir test diğerini etkileyemez.
use axum::Router;
use std::sync::{Arc, Mutex};
fn test_app() -> Router {
let store = Arc::new(Mutex::new(Vec::new()));
build(store) // same build() the real server uses
}tests Dizini
Tümleştirme testleri üst düzey bir tests/ klasöründe bulunur. Buradaki her dosya, kitaplığınızın herkese açık API'sini kullanan ayrı bir kasa olarak derlenir. Bu, gerçek kullanıcıların gördüğü arayüz üzerinden test yapmaya zorlar.
tests/api.rs, uç nokta testlerinizi içerir.- Tümünü
cargo testile çalıştırın.
// tests/api.rs
use my_api::build_router; // exported from lib.rs
#[tokio::test]
async fn health_ok() {
let _app = build_router();
// send a request and assert ...
}Veritabanına Karşı Test Etme
İşleyiciler sqlx kullandığında testlerin de bir veritabanına ihtiyacı olur. Yaygın stratejiler şunlardır: özel bir test veritabanı, her testten sonra geri alınan işlemler veya her test için temiz bir veritabanı sağlayan sqlx'in #[sqlx::test] makrosu.
// requires sqlx test features and a DATABASE_URL
use sqlx::PgPool;
#[sqlx::test]
async fn inserts_todo(pool: PgPool) {
let todo = create(&pool, "learn rust").await.unwrap();
assert_eq!(todo.title, "learn rust");
assert_eq!(todo.done, false);
}Neleri Test Etmeli?
Dengeli bir test kümesi hedefleyin:
- Başarılı yol: geçerli istekler doğru durumu ve gövdeyi döndürür.
- Hatalar: eksik kaynaklar 404, hatalı girdiler 400 döndürür.
- Sınır durumları: boş listeler, sınır değerleri ve yinelenenler.
Dağıtımdan önce gerilemelerin yakalanması için CI'da cargo test çalıştırın.
Kısa Kontrol
API'yi test etme hakkındaki anlayışınızı test edin.
Özet
Bir Rust REST API'sini test etmeyi öğrendiniz:
- Saf mantık için birim testleri kullanın; eşzamansız kod için
#[tokio::test]kullanın. oneshot, yönlendiriciyi doğrudan çalıştırır; bağlantı noktası gerekmez.- Gövdelere ve başlıklara sahip istekler oluşturun; yanıt gövdelerini toplayıp ayrıştırın.
- Yalıtım için her testte yeni bir uygulama oluşturucusu kullanın; tümleştirme testlerini
tests/içine koyun. #[sqlx::test]temiz veritabanları sağlar; başarılı yolları, hataları ve sınır durumlarını kapsayın.
Sıkça Sorulan Sorular
“API'yi Test Etme” dersi ücretsiz mi?
Evet — “API'yi Test Etme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Learn Rust Coding kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Learn Rust Coding kursu toplamda 4 dersten oluşur.
“API'yi Test Etme” dersinde ne öğreneceğim?
Tümleştirme testleri Learn Rust Coding ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Learn Rust Coding öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Learn Rust Coding, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“API'yi Test Etme” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Learn Rust Coding dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Learn Rust Coding dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Proje Kurulumu
- Uç Noktalar ve Modeller
- Veritabanı Tümleştirmesi
- API'yi Test Etme