【一緒にRustを学ぶ・Project Combat】コマンドラインIOプロジェクト minigrep - 機能改善のためのテスト駆動開発


序文

前の 3 つのセクションでの検討の後、私たちの小さなツール minigrep は指定されたファイル コンテンツの読み取りを実現し、その後の開発とテストの便宜のために、プロジェクト全体を再構築してエラー処理を標準化し、モジュールを標準化しました。今回は测试驱动开发(以后简称TDD)同じパターンで開発を行い、プログラムのテストケースをいくつか書いて、クエリ文字列を検索し、一致する行の例を返すプログラムの機能をテストし、後の開発プロセスで使用します。

テスト駆動開発、英語の正式名称テスト駆動開発は、TDD と呼ばれ、従来のソフトウェア開発プロセスとは異なる新しい開発方法です。ある関数のコードを書く前にテストコードを書き、テストをパスする関数コードだけを書き、テストを通して開発全体を進める必要があります。これにより、クリーンで使いやすく高品質なコードを記述し、開発プロセスをスピードアップできます。


1. 課題の目的

测试驱动开发模式(TDD)その開発手順を理解し、熟知してください。TDD 開発モデルを使用して、必要なテスト機能コードを記述し、ソフトウェアの機能を徐々に増やします。

TDD は、次の手順に従うソフトウェア開発手法です。

  1. 失敗するテストを作成し、それを実行して、期待どおりに失敗することを確認します。
  2. 新しいテストに合格するのに十分なコードを作成または変更します。
  3. 追加または変更されたばかりのコードをリファクタリングし、テストが引き続き成功することを確認します。
  4. ステップ1からやり直し!

TDD 開発モデルを使用する利点

  1. コード設計の推進を​​支援
  2. 開発中に高いテスト カバレッジを維持するのに役立ちます

2. テストの失敗例を書く

1. テスト モジュールとテスト機能を追加する

ライブラリ作成時に同梱されていたテストコードを模倣し、テスト用の関数を記述したテストモジュールを記述し、one_resultクエリの検索キーワードと内容を定義し、実際の運用で得られたパラメータをシミュレートして呼び出しました。search今パラメータを渡して、断言キーワードを含む行のベクトルを返す関数。

ここで渡すキーワードは である芙蓉ため、search正しく機能すると が返されます芙蓉老秋霜,团扇羞网尘。戚姬髡发入舂市,万古共悲辛。

search関数はまだ書かれていないので, 直接コンパイルすると必然的にエラーが報告されます. ここで, これら2つの値を渡し, キーワードが配置されている行を返すことを望みます. 関数は呼び出した方法に従って書かれていますsearch.それ。

#[cfg(test)]
mod tests {
    
    
use super::*;

#[test]
fn one_result() {
    
    
    let query = "芙蓉";
    let contents = "\
中山孺子妾,特以色见珍。虽然不如延年妹,亦是当时绝世人。
桃李出深井,花艳惊上春。一贵复一贱,关天岂由身。
芙蓉老秋霜,团扇羞网尘。戚姬髡发入舂市,万古共悲辛。";

    assert_eq!(vec!["芙蓉老秋霜,团扇羞网尘。戚姬髡发入舂市,万古共悲辛。"], search(query, contents));
    }
}

2. 検索関数を書く

ここではテスト エラーのユース ケースを作成しているため、プログラム エラーが想定どおりであることを確認する必要があります。そのため、検索関数で空のベクトルを返し、コードがコンパイルされ、返される結果が次のようになることを確認します。私たちが期待したものではありません.コードは以下のように表示されます,

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    
    
    vec![]
}

At this point, we run the test, and the result returns an assertion 左值不等于右值, shown that the code we written is correct. このエラーは後で修正し、コード テストをパスさせます (下の図を参照)。

3. コードを変更し、コードのテストに合格する

現在、常に空のベクターを返すため、テストは失敗します。プログラムがテストに合格するには、search関数のロジックを改善して正しい結果を返す必要があります。searchプログラムのフローチャートは次のとおりです。

Created with Raphaël 2.3.0 开始 定义存储Vector 是否到达尾行? 结束 是否包含关键词 yes no

1. 行単位で読む

Rust はテキストを 1 行ずつ読み取るメソッドを提供しておりlines、彼の呼び出しメソッドは次のとおりです。

contents.lines()

このメソッドは、各要素がテキスト コンテンツの行である配列を返します。for ループを使って各行を読み込んで各行を操作するので、searchこのように関数を変更します。

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    
    
    for line in contents.lines() {
    
    
        // 对文本行进行操作
    }
}

2. キーワードを確認する

キーワードのチェックは実際には文字列を探すことであり、Rust の文字列は文字列を検索する方法も提供しますcontains

contents.contains(keyword)

これをsearch関数に追加します

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    
    
        for line in contents.lines() {
    
    
            // 对文本行进行操作
            if line.contains(query) {
    
    

            }
        }
    }

3. 検索結果の保存

これで、各行をトラバースし、各行をチェックして、探しているキーワードが存在するかどうかを確認できるようになりました。そのため、ここで検討する必要があるのは、キーワードを含むこれらの行を保存して返す方法です。for ループの外に Vector を作成することを検討し、該当する行があれば必ず for ループの判定に追加すると、コードは次のようになります。

pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    
    
    let mut results = Vec::new();

    for line in contents.lines() {
    
    
        if line.contains(query) {
    
    
            results.push(line);
        }
    }

    results
}

ここにVector型の可変変数を定義しresults、forループで判定し、条件に合う行があればそこresultsに追加し、最後に返すresults

4. テストを実行する

では、このテストケースを実行してみましょう.書いた関数が条件を満たし、テストに合格すること

がわかります.search

4番目に、プログラムでコードを使用します

プロジェクトのメイン ロジックはrun関数内に配置されているため、関数内で関数をrun呼び出しsearch、各行の内容を出力するだけで済みます。

pub fn run(config: Config) -> Result<(), Box<dyn Error>> {
    
    
    let contents = fs::read_to_string(config.filename)?;
    for line in search(&config.query, &contents){
    
    
        println!("{}", line);
    }
    Ok(())
}

このとき、プログラムを実行して効果を確認し、

比較的短いキーワードを入力し、すべての行が見つかるかどうかを確認し、

その中に存在しないキーワードを入力します


要約する

これで、この小さなツールの開発は基本的に完了し、独自の小さなツールを作成し、プログラムの編成方法、テスト開発を推進する開発方法、およびファイルの入出力、ライフサイクル、テスト、およびコマンドライン分析のコンテンツを学びました。 .

ここまでで、この小さなツールの主な機能が開発されました。今後は、環境変数の処理を最適化し、標準コンテンツを出力していきます。

手術

ここまでで、基本的にこの小さなケースを完了しました。次の点について考えてください。

  • 文字列の分割、文字列の置換などの文字列操作について、Rust を使用して記述する方法。
  • テスト駆動開発の利点とその手順について教えてください。

おすすめ

転載: blog.csdn.net/weixin_47754149/article/details/125761143