Rustdoc Birleşik Testleri
Özet
- Doctest’ler artık tek bir ikili dosyada birleştirilir; bu da kayda değer bir performans iyileşmesi sağlamalıdır.
Ayrıntılar
2024 sürümünden önce rustdoc’un “test” modu, belgelerinizdeki her kod bloğunu ayrı bir çalıştırılabilir dosya olarak derliyordu. Bunu uygulamak görece basitti; ancak çok sayıda belge testi olduğunda ciddi bir performans yükü oluşturuyordu. 2024 sürümüyle birlikte rustdoc, belge testlerini tek bir ikili dosyada birleştirmeye çalışır; böylece doctest derleme ek yükü önemli ölçüde azalır.
#![allow(unused)]
fn main() {
/// Iki sayiyi toplar
///
/// ```
/// assert_eq!(add(1, 1), 2);
/// ```
pub fn add(left: u64, right: u64) -> u64 {
left + right
}
/// Iki sayiyi cikarir
///
/// ```
/// assert_eq!(subtract(2, 1), 1);
/// ```
pub fn subtract(left: u64, right: u64) -> u64 {
left - right
}
}
Bu örnekte iki doctest artık tek bir çalıştırılabilir dosyada derlenir. Rustdoc, özünde her örneği tek bir ikili içindeki ayrı bir fonksiyona yerleştirir. Testler yine eskisi gibi bağımsız süreçlerde çalışır; bu yüzden genel durum (örneğin global static’ler) doğru çalışmaya devam eder.1
Bu değişiklik, birleşik çalıştırılabilir yapıda çalışmayabilecek mevcut doctest’lerle olası uyumsuzlukları önlemek için yalnızca 2024 sürümünde sunulur. Yine de bu uyumsuzlukların son derece nadir olması beklenir.
standalone_crate etiketi
Bazı durumlarda rustdoc’un örnekleri tek bir çalıştırılabilir dosyada birleştirmesi mümkün değildir. Rustdoc bunun mümkün olmadığı durumları otomatik olarak tespit etmeye çalışır. Örneğin bir test aşağıdaki durumlarda diğerleriyle birleştirilmez:
- Örneğin derlenememesi gerektiğini belirten
compile_failetiketini kullanıyorsa. - Örneğin hangi sürüme ait olduğunu belirten
editionetiketini kullanıyorsa.2 - Diğer testlerle çakışma çıkarabilecek
global_allocatorgibi genel öznitelikler kullanıyorsa. - Crate düzeyinde öznitelikler tanımlıyorsa (
#![feature(...)]gibi). $cratekullanan bir makro tanımlıyorsa; çünkü$crateyolu doğru çalışmaz.
Ancak rustdoc, bir örneğin diğer örneklerle birleştirilemeyeceği tüm durumları
otomatik olarak belirleyemez. Böyle durumlarda örneğin ayrı bir çalıştırılabilir
olarak derlenmesi gerektiğini belirtmek için standalone_crate dil etiketini
ekleyebilirsiniz. Örneğin:
#![allow(unused)]
fn main() {
//! ```
//! let location = std::panic::Location::caller();
//! assert_eq!(location.line(), 5);
//! ```
}
Bu örnek, derleme sırasında kodun nasıl yapılandırıldığına duyarlıdır ve
“birleşik” yaklaşımda çalışmaz; çünkü doctest’lerin nasıl birleştirildiğine göre
satır numaraları kayar. Böyle durumlarda örneğin önceki sürümlerde olduğu gibi
ayrı derlenmesini zorlamak için standalone_crate etiketini ekleyebilirsiniz:
#![allow(unused)]
fn main() {
//! ```standalone_crate
//! let location = std::panic::Location::caller();
//! assert_eq!(location.line(), 5);
//! ```
}
Taşıma
Hangi doctest’lerin standalone_crate etiketiyle işaretlenmesi gerektiğini
belirleyen otomatik bir taşıma yoktur. Verilen bir doctest’in taşındığında doğru
çalışmaması pek olası değildir. Önerimiz, crate’inizi 2024 sürümüne güncelleyip
belge testlerini çalıştırmanız ve başarısız olan olup olmadığına bakmanızdır.
Bir test başarısız olursa, ya birleşik yaklaşımla uyumlu olacak şekilde yeniden
yazmanız ya da önceki davranışı korumak için standalone_crate etiketini
eklemeniz gerekir.
Özellikle dikkat edilmesi ve kaçınılması gereken bazı durumlar şunlardır:
std::panic::Locationdeğerlerini ya daLocationkullanan şeyleri sınamak. Artık birden fazla test aynı test crate’i içinde bulunduğu için kodun konumu farklıdır.std::any::type_namedeğerini sınamak; çünkü bunun modül yolu artık farklıdır.
-
Bunun nasıl çalıştığının ayrıntıları için “Doctests - How were they improved?” yazısına bakın. ↩
-
Rustdoc’un testleri yalnızca tüm crate 2024 veya daha yeni bir sürümdeyse birleştireceğini unutmayın. Daha eski sürümlerde
edition2024etiketini kullanmak, bu testlerin birleşmesine yol açmaz. ↩