Rust学習まとめ - テスト作成に入門する、等/学習のふりかえり
今日はテスト作成入門。学んだことを本題に書いておいた。
Rust、難しい、な。この学習ノートはコレで最後にすることにしたので、次のアクションを最後にかきます。
本題
Rustのテストコード作成方法を理解する日だった。
書き方を把握してから文法の理解を目的とした簡単なテストコードを書く。そっとコードを置いておく。このタイミングでrustdocの使い方なども試した。細々としたレベルが上がった気がする。
↓調べたり実践したことを書き残しておく。
テスト記述法の確認
↑テストの記述法が紹介されているのを簡単に確認した。
単体テスト
単体テストはテスト対象のコードと同じファイル(src/**/*.rs)に記述
各ファイルにtestsという名前のモジュールを作成。
testsモジュール内にテスト関数(テストコード)を実装。
testsモジュールを#[cfg(test)]で注釈する。#[cfg(test)]注釈の効果は、通常のコンパイル時(cargo build)の成果物サイズ節約。cargo test実行時だけテストコードがコンパイル対象になるよう制御される為。(言い換えると、#[cfg(test)] 注釈がついているモジュールはcargo buildコマンド実行時にコンパイル対象から外れる)
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
結合テスト
結合テストでは、
結合テストのコードはsrcディレクトリの外で管理(テスト対象のライブラリの外でコード管理)具体的には、プロジェクトディレクトリのトップ階層、srcの隣にtestsディレクトリを作成するルール。
そしてtestsディレクトリ内にテストファイルを作成していく。
結合テストという言葉のままだが、テスト対象のクレート(=ライブラリ)を通常実行しつつ検証するというテスト。
Cargoは cargo test コマンドを実行すると、testsディレクトリ内のそれぞれのファイルを個別のクレートとしてコンパイルしテストが実行される仕様。
特定の結合テストファイルにあるテストだけをテスト実行したい場合 cargo test --test integration_test のようにcargo testの後ろに続けて--test <テストファイル名(拡張子を除く)>と書くことで実行できる。
使い方は理解できた。以下は結合テストのサンプル。adderというライブラリクレートの結合テストをしている模様。この辺はコードを書いて実践してみることにしよう。
// in: tests/integration_test.rs
extern crate adder;
#[test]
fn it_adds_two() {
assert_eq!(4, adder::add_two(2));
}
慣用マクロ・関数を確認しておく
テストコード作成に使える関数の確認をする。ありていだがこのサイトを読もう。
↑読んだ。
assertマクロシリーズ
assert!
assert_eq!
assert_ne!
assert_matches!
debug_asset_* vs assert_*
デバッグとリリース。
負荷のかかるテストにつけるとよさそう。
デプロイパイプライン構築時に使い分けるやつか。
こだわってみたいけど、実践で器用に住み分けられるか?(笑)
should_panic属性
これは把握しておこう。
panic自体の付き合い方が腑に落ちてない部分が残ってるが panicに陥るパターンのテストケースに使う。
基本的な関数が並んでいることは理解。余談だが、rust/cargo、ベンチマーク測定サポートしてるのか。今の所、unstableでnightly のみ使える状態、と。ついでなのでとりあえずbencherを使ってみることにする。(stableからnightlyの切り替えのやり方に苦戦しながら..)
モック化の方法
調べた。mockallというクレートを使って手軽に実現できることがわかった。使い方を確認して導入してみた。コードにコミットしていく。
その他
テストの話題からすこし反れる気もするが、エディションガイドによると、Rust2018からextern構文が省略できるらしい。
しかし↑でみてきた「doc.rust-jp.rs」のテスト記述法では結合テストのコードにexternが含まれている。
なので、手元で適当にコードを書いて、省略できるか確認した。
Cargo.tomlファイルを開いて、editionの設定が2018(か2021)であることを確認
$ cat Cargo.toml
[package]
name = "adder"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
「extern crate adder;」をコメントアウト
$ cat tests/integration_test.rs
// extern crate adder;
mod tests {
use adder::add;
#[test]
fn test_add() {
let res = add(1,2);
assert_eq!(res, 3);
}
}
実行してみる。
たしかに動いた!
$ cargo test --test integration_test
Compiling adder v0.1.0 (/Users/e_fujikawa/Documents/git/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.40s
Running tests/integration_test.rs (target/debug/deps/integration_test-2a8b11d4840294f3)
running 1 test
test tests::test_add ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
次に、Cargo.tomlのeditionを2015に変えてみる。
Rust 2015だと、どうなるか。
$ cat Cargo.toml
[package]
name = "adder"
version = "0.1.0"
edition = "2015"
実行してみたところ。以下のようにエラーになった。「maybe a missing crate `adder` 」と表示される。
$ cargo test --test integration_test
Compiling adder v0.1.0 (/Users/e_fujikawa/Documents/git/adder)
error[E0432]: unresolved import `adder`
--> tests/integration_test.rs:4:7
|
4 | use adder::add;
| ^^^^^ maybe a missing crate `adder`?
For more information about this error, try `rustc --explain E0432`.
error: could not compile `adder` due to previous error
エコシステム
あとから知ったので追記。
Trybuild というクレートがあるらしい。NEAR SDKで使われてるのを目撃。いわゆるテストハーネス(test harness)。覚えておこう。
よし。こんなものだろう。
バージョンの違いは気をつけつつ、実装していくことにしよう。
本題+α
RustのコマンドラインツールとWeb API作成のお作法のキホンをやっていく。
それぞれ最も使われていると言われるクレート(≒ライブラリ)を選び、実践していく。長くなるといけないので「使ったクレート」と「やってみたコード」だけおいておく。
コマンドラインツール作成
使ったクレート: clap
やってみたコード:
Web API作成
使ったクレート: actix-web
actix-web - https://github.com/actix/actix-web
actix-extra - https://github.com/actix/actix-extras
やってみたコード
長かった。キホン確認。あとは簡単にふりかえりしてから「次のアクション」へ。
ふりかえり
ふりかえりを簡単に行う。
キホンの学習はやれたと思う。
まったく知らない言語の学習ということで不安だったが、なんとか学べた。
ブロックチェーンを作るというお題で練習しながら実際にコードも書いた。
静的型付言語のキホンを通すことはできたと思う。
所有権、参照・借用などの概念も一定理解した。
基本的な構文を読んで実践した。構造体、関連関数/メソッド/クロージャ、モジュール、条件式、エラーハンドリング、ジェネリクスなど。
習熟度・理解度の状況は?↓の記事にも所感をかいたがやや不届き。
着手してから2週間は妥当な気もする。
この辺でキホン学習をしめてあとは実践といこう(→次のアクション)
ダラダラやるのは避けたい。
次のアクション
この学習ノートはこれでおしまい。次は、dAppとRust開発の実習をやる。別なノートを作ってやる。
ざっくりかくと、自分で決めたお題で開発を行って、腕をあげていくヤツ。
前提条件は、Web APIとスマートコントラクト実装。そこにRustを使う(バックエンドはRust)。フロントエンドにはNext.jsを使う。期間は2週間以内。
↓次のアクションのためのノートはつくっておいた。
また次回!
この記事が気に入ったらサポートをしてみませんか?