Testlerin Nasıl Çalıştırıldığını Kontrol Etme
Tıpkı cargo run
'un kodunuzu derlemesi ve ardından ortaya çıkan ikili dosyayı çalıştırması gibi,
cargo test
de kodunuzu test modunda derler ve ortaya çıkan test ikili dosyasını çalıştırır.
cargo test
tarafından üretilen ikilinin varsayılan davranışı, tüm testleri paralel olarak çalıştırmak ve test çalıştırmaları
sırasında üretilen çıktıyı yakalamak, çıktının görüntülenmesini önlemek ve test sonuçlarıyla ilgili çıktıyı okumayı kolaylaştırmaktır.
Bununla birlikte, bu varsayılan davranışı değiştirmek için komut satırı seçenekleri belirleyebilirsiniz.
Bazı komut satırı seçenekleri cargo test
'e, bazıları ise elde edilen test ikilisine gider.
Bu iki tür argümanı ayırmak için, cargo test
'e giden argümanları ve ardından ayırıcıyı --
ve ardından test ikilisine gidenleri
listelersiniz. cargo test --help
komutunu çalıştırdığınızda cargo test
ile kullanabileceğiniz seçenekler görüntülenir
ve cargo test -- --help
komutunu çalıştırdığınızda ayırıcıdan sonra kullanabileceğiniz seçenekler görüntülenir.
Testleri Paralel veya Ardışık Olarak Çalıştırma
Birden fazla test çalıştırdığınızda, varsayılan olarak iş parçacıkları kullanılarak paralel olarak çalışırlar, yani daha hızlı çalışırlar ve daha hızlı geri bildirim alırsınız. Testler aynı anda çalıştığından, testlerinizin birbirlerine veya geçerli çalışma dizini veya ortam değişkenleri gibi paylaşılan bir ortam da dahil olmak üzere herhangi bir paylaşılan duruma bağlı olmadığından emin olmalısınız.
Örneğin, testlerinizin her birinin diskte test-output.txt adında bir dosya oluşturan ve bu dosyaya bazı veriler yazan bir kod çalıştırdığını varsayalım. Ardından her test bu dosyadaki verileri okur ve dosyanın her testte farklı olan belirli bir değer içerdiğini iddia eder. Testler aynı anda çalıştığından, bir testin dosyayı yazması ve okuması arasında geçen sürede bir test dosyanın üzerine yazabilir. Bu durumda ikinci test, kod hatalı olduğu için değil, testler paralel olarak çalışırken birbirine karıştığı için başarısız olacaktır. Bir çözüm, her testin farklı bir dosyaya yazdığından emin olmaktır; başka bir çözüm ise testleri teker teker çalıştırmaktır.
Testleri paralel olarak çalıştırmak istemiyorsanız veya kullanılan iş parçacığı sayısı üzerinde daha ayrıntılı kontrol istiyorsanız,
--test-threads
bayrağını ve kullanmak istediğiniz iş parçacığı sayısını test ikilisine gönderebilirsiniz.
Aşağıdaki örneğe bir göz atın:
$ cargo test -- --test-threads=1
Test iş parçacığı sayısını 1
olarak ayarladık ve programa herhangi bir paralellik kullanmamasını söyledik.
Testleri tek bir iş parçacığı kullanarak çalıştırmak, paralel olarak çalıştırmaktan daha uzun sürecektir,
ancak testler durumu paylaşırlarsa birbirlerini etkilemeyeceklerdir.
Fonksiyon Çıktısını Gösterme
Varsayılan olarak, bir test geçerse, Rust'ın test kütüphanesi standart çıktıya yazdırılan her şeyi yakalar.
Örneğin, bir testte println!
komutunu çağırırsak ve test geçerse, uçbirimde println!
çıktısını görmeyiz; yalnızca testin
geçtiğini gösteren satırı görürüz. Bir test başarısız olursa, başarısız mesajının geri kalanıyla birlikte
standart çıktıya ne yazdırıldıysa onu görürüz.
Örnek olarak, Liste 11-10'da parametresinin değerini yazdıran ve 10
döndüren saçma bir fonksiyonun yanı sıra başarılı
olan bir test ve başarısız olan bir test vardır.
Dosya adı: src/lib.rs
fn prints_and_returns_10(a: i32) -> i32 {
println!("I got the value {}", a);
10
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn this_test_will_pass() {
let value = prints_and_returns_10(4);
assert_eq!(10, value);
}
#[test]
fn this_test_will_fail() {
let value = prints_and_returns_10(8);
assert_eq!(5, value);
}
}
Bu testleri cargo test
ile çalıştırdığımızda aşağıdaki çıktıyı göreceğiz:
$ cargo test
Compiling silly-function v0.1.0 (file:///projects/silly-function)
Finished test [unoptimized + debuginfo] target(s) in 0.58s
Running unittests (target/debug/deps/silly_function-160869f38cff9166)
running 2 tests
test tests::this_test_will_fail ... FAILED
test tests::this_test_will_pass ... ok
failures:
---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `5`,
right: `10`', src/lib.rs:19:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::this_test_will_fail
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass '--lib'
Bu çıktının hiçbir yerinde I got the value 4
ifadesini görmediğimize dikkat edin;
bu, geçen test çalıştırıldığında yazdırılan değerdir. Bu çıktı yakalanmıştır. Başarısız olan testin çıktısı,
I got the value 8
, test özeti çıktısının test başarısızlığının nedenini de gösteren bölümünde görünür.
Geçen testler için de yazdırılan değerleri görmek istiyorsak, Rust'a --show-output
ile başarılı testlerin
çıktısını da en sonunda göstermesini söyleyebiliriz.
$ cargo test -- --show-output
Liste 11-10'daki testleri --show-output
bayrağı ile tekrar çalıştırdığımızda aşağıdaki çıktıyı görüyoruz:
$ cargo test -- --show-output
Compiling silly-function v0.1.0 (file:///projects/silly-function)
Finished test [unoptimized + debuginfo] target(s) in 0.60s
Running unittests (target/debug/deps/silly_function-160869f38cff9166)
running 2 tests
test tests::this_test_will_fail ... FAILED
test tests::this_test_will_pass ... ok
successes:
---- tests::this_test_will_pass stdout ----
I got the value 4
successes:
tests::this_test_will_pass
failures:
---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `5`,
right: `10`', src/lib.rs:19:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::this_test_will_fail
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass '--lib'
Bir Test Alt Kümesini Ada Göre Çalıştırma
Bazen tam bir test paketi çalıştırmak uzun zaman alabilir. Belirli bir alandaki kod üzerinde çalışıyorsanız,
yalnızca o kodla ilgili testleri çalıştırmak isteyebilirsiniz. Çalıştırmak istediğiniz test(ler)in adını veya adlarını
cargo test
'e argüman olarak ileterek hangi testlerin çalıştırılacağını seçebilirsiniz.
Testlerin bir alt kümesinin nasıl çalıştırılacağını göstermek için, önce Liste 11-11'de gösterildiği gibi add_two
fonksiyonumuz için üç test oluşturacağız ve hangilerinin çalıştırılacağını seçeceğiz.
Dosya adı: src/lib.rs
pub fn add_two(a: i32) -> i32 {
a + 2
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add_two_and_two() {
assert_eq!(4, add_two(2));
}
#[test]
fn add_three_and_two() {
assert_eq!(5, add_two(3));
}
#[test]
fn one_hundred() {
assert_eq!(102, add_two(100));
}
}
Testleri daha önce gördüğümüz gibi herhangi bir argüman geçmeden çalıştırırsak, tüm testler paralel olarak çalışacaktır:
$ cargo test
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.62s
Running unittests (target/debug/deps/adder-92948b65e88960b4)
running 3 tests
test tests::add_three_and_two ... ok
test tests::add_two_and_two ... ok
test tests::one_hundred ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests adder
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Tekdüze Testleri Çalıştırma
Yalnızca bu testi çalıştırmak için herhangi bir test fonksiyonunun adını cargo test
'e geçirebiliriz:
$ cargo test one_hundred
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.69s
Running unittests (target/debug/deps/adder-92948b65e88960b4)
running 1 test
test tests::one_hundred ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
Sadece one_hundred
isimli test çalıştı; diğer iki test bu isimle eşleşmedi.
Test çıktısı, sonunda filtrelenen 2
'yi görüntüleyerek çalışmayan daha fazla testimiz olduğunu bilmemizi sağlar.
Bu şekilde birden fazla testin adını belirtemeyiz; yalnızca cargo test
'e verilen ilk değer kullanılır.
Ancak birden fazla test çalıştırmanın bir yolu var.
Birden Fazla Test Çalıştırmak için Filtreleme
Bir test adının bir kısmını belirtebiliriz ve adı bu değerle eşleşen herhangi bir test çalıştırılır.
Örneğin,testlerimizden ikisinin adı add
içerdiğinden, bu ikisini cargo test add
komutuyla çalıştırabiliriz:
$ cargo test add
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.61s
Running unittests (target/debug/deps/adder-92948b65e88960b4)
running 2 tests
test tests::add_three_and_two ... ok
test tests::add_two_and_two ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s
Bu komut, adında add olan tüm testleri çalıştırır ve one_hundred
adlı testi filtreler.
Ayrıca, bir testin göründüğü modülün testin adının bir parçası haline geldiğini unutmayın,
bu nedenle modülün adına göre filtreleme yaparak bir modüldeki tüm testleri çalıştırabiliriz.
Özel Olarak İstenmedikçe Bazı Testleri Yok Sayma
Bazen belirli birkaç testin yürütülmesi çok zaman alıcı olabilir, bu nedenle cargo test
'in çoğu çalıştırması
sırasında bunları hariç tutmak isteyebilirsiniz. Çalıştırmak istediğiniz tüm testleri argüman olarak listelemek yerine,
zaman alan testleri burada gösterildiği gibi dışlamak için ignore
niteliğini kullanarak açıklama ekleyebilirsiniz:
Dosya adı: src/lib.rs
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[test]
#[ignore]
fn expensive_test() {
// code that takes an hour to run
}
#[test]
'ten sonra, hariç tutmak istediğimiz teste #[ignore]
satırını ekliyoruz.
Testlerimizi çalıştırdığımızda it_works
çalışıyor, ancak expensive_test
çalışmıyor:
$ cargo test
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.60s
Running unittests (target/debug/deps/adder-92948b65e88960b4)
running 2 tests
test expensive_test ... ignored
test it_works ... ok
test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s
Doc-tests adder
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
expensive_test
fonksiyonu ignored
olarak listeleniyor. Yalnızca göz ardı edilen testleri çalıştırmak istiyorsak,
cargo test -- --ignored
'u kullanabiliriz:
$ cargo test -- --ignored
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.61s
Running unittests (target/debug/deps/adder-92948b65e88960b4)
running 1 test
test expensive_test ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s
Doc-tests adder
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Hangi testlerin çalışacağını kontrol ederek, cargo test
sonuçlarınızın hızlı olmasını sağlayabilirsiniz.
Yok sayılan testlerin sonuçlarını kontrol etmenin mantıklı olduğu bir noktaya geldiğinizde ve sonuçları beklemek için zamanınız
olduğunda, bunun yerine cargo test -- --ignored
komutunu çalıştırabilirsiniz.
Yok sayılsın ya da sayılmasın tüm testleri çalıştırmak istiyorsanız, cargo test -- --include-ignored
komutunu çalıştırabilirsiniz.