ドキュメンテーションテスト - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# ドキュメンテーションテスト

Rustのプロジェクトでは、ソースコードに注釈する形でドキュメントを書くのが主流です。ドキュメンテーションコメントの記述はCommonMark Markdown specificationで行い、コードブロックも使えます。Rustは正確性を重視しているので、コードブロックもコンパイルされ、テストとして使われます。

    /// 最初の行には関数の機能の短い要約を書きます。
    ///
    /// 以降で詳細なドキュメンテーションを記述します。コードブロックは三重のバッククォートで始まり、
    /// 暗黙的に`fn main()`と`extern crate <クレート名>`で囲われます。
    /// `playground`クレートをテストしたいときには、次のように記述します。
    ///
    /// ```
    /// let result = playground::add(2, 3);
    /// assert_eq!(result, 5);
    /// ```
    pub fn add(a: i32, b: i32) -> i32 {
        a + b
    }

    /// 一般的に、ドキュメンテーションコメントは
    /// "Examples", "Panics", "Failures" という章から成ります。
    ///
    /// 次の関数は除算を実行します。
    ///
    /// # Examples
    ///
    /// ```
    /// let result = playground::div(10, 2);
    /// assert_eq!(result, 5);
    /// ```
    ///
    /// # Panics
    ///
    /// 第2引数がゼロであればパニックします。
    ///
    /// ```rust,should_panic
    /// // ゼロで除算するとパニックします
    /// playground::div(10, 0);
    /// ```
    pub fn div(a: i32, b: i32) -> i32 {
        if b == 0 {
            panic!("Divide-by-zero error");
        }

        a / b
    }

ドキュメンテーションコメント中のコードブロックは、`cargo test`コマンドで自動的にテストされます。

    $ cargo test
    running 0 tests

    test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

       Doc-tests playground

    running 3 tests
    test src/lib.rs - add (line 7) ... ok
    test src/lib.rs - div (line 21) ... ok
    test src/lib.rs - div (line 31) ... ok

    test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

## ドキュメンテーションテストの目的

ドキュメンテーションテストの主な目的は、実行例を示すことであり、これは最も大切なガイドラインの一つにもなっています。これにより、ドキュメントの例を実際に動くコードとして使うことができます。しかしながら、`main`が`()`を返すために、`?`を使うとコンパイルに失敗してしまいます。ドキュメンテーションでコードブロックの一部を隠す機能で、この問題に対処できます。つまり、`fn try_main() -> Result<(), ErrorType>`を定義しておきながらそれを隠し、暗黙の`main`の内部で`unwrap`するのです。複雑なので、例を見てみましょう。

    /// ドキュメンテーションテストで、`try_main`を隠して使います。
    ///
    /// ```
    /// # // 行頭に `#` を置くと行が隠されるが、コンパイルには成功します。
    /// # fn try_main() -> Result<(), String> { // ドキュメントの本体を囲う行
    /// let res = playground::try_div(10, 2)?;
    /// # Ok(()) // try_mainから値を返します
    /// # }
    /// # fn main() { // unwrap()を実行します。
    /// #    try_main().unwrap(); // try_mainを呼びunwrapすると、エラーの場合にパニックします。
    /// # }
    /// ```
    pub fn try_div(a: i32, b: i32) -> Result<i32, String> {
        if b == 0 {
            Err(String::from("Divide-by-zero"))
        } else {
            Ok(a / b)
        }
    }

## 参照

- RFC505 ドキュメンテーションのスタイルについて
- API Guidelines ドキュメンテーションのガイドラインについて