はじめに
この実験では、Rust を使ったソフトウェア開発におけるテストの重要性と、ユニットテストや統合テストなどのさまざまな種類のテストを書く方法を探ります。また、Rust プロジェクトでテストを整理し、cargo testコマンドを使って実行する方法についても学びます。さらに、同時にテストを実行することで発生する可能性のある問題について議論し、これを示す例を挙げます。
注: 実験でファイル名が指定されていない場合、好きなファイル名を使うことができます。たとえば、
main.rsを使って、rustc main.rs &&./mainでコンパイルして実行することができます。
テスト
私たちが知っているように、テストはソフトウェアのどの部分にも不可欠です!Rust は、ユニットテストと統合テストに対して一流のサポートを備えています(TRPL のこの章を参照)。
上記のリンクされたテストの章から、ユニットテストと統合テストを書く方法がわかります。組織的には、ユニットテストをそれがテストするモジュールに配置し、統合テストを独自のtests/ディレクトリに配置することができます。
foo
├── Cargo.toml
├── src
│ └── main.rs
│ └── lib.rs
└── tests
├── my_test.rs
└── my_other_test.rs
tests内の各ファイルは、独立した統合テストです。つまり、依存クレートから呼び出されているかのように、ライブラリをテストするためのテストです。
テストの章では、3 つの異なるテストスタイル:ユニット、ドキュメント、および統合について詳しく説明されています。
cargoは自然に、すべてのテストを実行する簡単な方法を提供します!
$ cargo test
以下のような出力が表示されるはずです。
[object Object]
また、名前がパターンに一致するテストを実行することもできます。
$ cargo test test_foo
[object Object]
注意点として 1 つだけ:Cargo は複数のテストを同時に実行する場合があるので、互いに競合しないようにしてください。
この並列実行が問題を引き起こす 1 つの例は、2 つのテストがファイルに出力する場合です。例えば、以下のようになります。
#[cfg(test)]
mod tests {
// 必要なモジュールをインポート
use std::fs::OpenOptions;
use std::io::Write;
// このテストはファイルに書き込みます
#[test]
fn test_file() {
// ferris.txt を開き、存在しない場合は作成します。
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open("ferris.txt")
.expect("Failed to open ferris.txt");
// "Ferris"を 5 回表示します。
for _ in 0..5 {
file.write_all("Ferris\n".as_bytes())
.expect("Could not write to ferris.txt");
}
}
// このテストは同じファイルに書き込もうとします
#[test]
fn test_file_also() {
// ferris.txt を開き、存在しない場合は作成します。
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open("ferris.txt")
.expect("Failed to open ferris.txt");
// "Corro"を 5 回表示します。
for _ in 0..5 {
file.write_all("Corro\n".as_bytes())
.expect("Could not write to ferris.txt");
}
}
}
意図したのは以下のようになるはずです。
$ cat ferris.txt
Ferris
Ferris
Ferris
Ferris
Ferris
Corro
Corro
Corro
Corro
Corro
実際にferris.txtに入るのはこれです。
$ cargo test test_foo
Corro
Ferris
Corro
Ferris
Corro
Ferris
Corro
Ferris
Corro
Ferris
まとめ
おめでとうございます!あなたはテストの実験を完了しました。あなたのスキルを向上させるために、LabEx でさらに多くの実験を練習することができます。