[Rust] 同じ端末上で開発時、テスト時、本番時で値を切り替える方法
概要
基本的に環境によってコード内で利用する値を切り替えたい場合は環境変数を用いるのが一般的です。
Rustにはstd::env
という標準ライブラリが有るのでコレを使えば環境変数を利用できますし、dotenvというクレートを利用すれば.env
ファイルの中身を環境変数として利用することも出来ます。
しかし、開発する際にデータベースの向き先を開発時/テスト時で切り替えたい場面はよくあります。 その際、環境変数か.envファイルの中身を書き換えれば対応できますが、毎回それを手動で行うのは面倒です。
そこで、Rustのコンパイル時点で開発、テスト、本番それぞれの環境によって利用する値を変更する、という方法を利用すれば、自動的に利用する値やenvファイルを切り替えることが可能になります。
実際のコード
至って単純で、cfg!
マクロを使えば、コード内で環境などに応じでif分で分岐させることが出来ます。
fn get_value() -> String {
let result = if cfg!(test) {
"Testing".to_string()
} else if cfg!(debug_assertions) {
"Development".to_string()
} else {
"Production".to_string()
};
result
}
fn main() {
println!("Hello, world!, {}", get_value());
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test1() {
assert_eq!("Testing", get_value());
}
}
上記をそれぞれ実行すると以下のようになります。
# まずはビルド
[koji:change_by_status]$ cargo clean
[koji:change_by_status]$ cargo build
[koji:change_by_status]$ cargo build --release
# 実行
[koji:change_by_status]$ ./target/debug/change_by_status
Hello, world!, Development
[koji:change_by_status]$ ./target/release/change_by_status
Hello, world!, Production
[koji:change_by_status]$
# テストを実行してみる
[koji:change_by_status]$ cargo test
Compiling change_by_status v0.1.0 (/home/koji/code/rust/change_by_status)
Finished test [unoptimized + debuginfo] target(s) in 0.31s
Running unittests (target/debug/deps/change_by_status-0b25d0d2c2040940)
running 1 test
test tests::test1 ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
[koji:change_by_status]$
まとめ
本番環境で状況によって環境変数が変わる、ということは基本的に無いはずですので、このような方法をとるのは開発時のテストのときだけかな、とは思います。
具体的な利用シーンとしては、開発時は.env_dev
、ユニットテスト時は.env_test
というファイルをそれぞれdotenvで利用したい場合に、
let result = if cfg!(test) {
dotenv::from_filename(".env_test")
} else if cfg!(debug_assertions) {
dotenv::from_filename(".env_dev")
} else {
dotenv::dotenv()
};
という感じになると思います。
公開日:2021/08/17