diesel
で MySQL
を制御している Rust
のコードがありました。
cargo test
で色々とデータベースを操作した後に、すっかり汚れちまったテーブルを放置しておくと次回のテストが失敗するので、ターミナルからコマンドを叩いてテーブルをクリアしていたわけです。
$ mysql -uroot -ppassword -h127.0.0.1 -e'truncate table test_database.test_teble;'
毎回叩くのも面倒なので、cargo test
と一緒にやりたい。それがささやかな望みでした。
// Clean up the test_table
#[test]
fn test_cleanup_hash_file() {
let conn = setup();
diesel::sql_query("truncate table test_db.file_hashes").execute(&conn).unwrap();
}
こんな感じで、ユニットテストのコードを追加して $ cargo test
しました。ファイルの最後に書いたので、最後に実行されてテーブルがクリアされるでしょう。そう信じて疑いませんでした。
しかし、現実は厳しいものです。そう簡単に希望を叶えてくれることはありませんでした。
とっとと結論をいいますが、cargo test
によるユニットテストは 並行実行 ってコトらしいです。
今回の例でいうと、テーブルのクリアがどのタイミングで実行されるかがわからないので、テーブルクリア前提のテストは成功するか保証できないということです。
基本的に各ユニットテストはそれぞれで完結させるべきなのでしょう。
まあ、今回のように最後に後片付けしたいってコトは、DB操作とかのプログラムではありがちかもなので、どうしても順番に実行したい場合は
$ cargo test -- --test-threads=1
こうゃって。
テストを1スレッドで実行(マルチスレッドで並行実行しない)が、正解でした。
めでたしめでたし。