囲碁における実用的なユニットテストWebクライアント


私はGOプロジェクト、軽量のHashicorp Vaultを始めました1 依存関係のないクライアントと、単純なAPI (ユーザ用).私がサードパーティ製のモジュールを使用しない理由の一部は、私はより良いインターフェイス、構造、および私のスキルを向上させるGOを理解したい.このポストでは、私がどのようにそれをテストしたかの実用的な例を行います.
プロジェクトの名前はlibvault , そして、それは私の最初のオープンソースプロジェクトです.
Vaultは、Web APIとCLIの秘密マネージャサービスです.アプリケーションはHTTP経由で通信できます.私はCLIを使いやすいが、公式のVaultライブラリは少し複雑です私が必要としたすべては単純な包丁であるとき、それはスイス軍ナイフのように感じられました.シンプルなAPIを維持しながら、基本的な機能をカバーするライトバージョンを実装することを決めた.

I'm not going to cover the basics in this post. The intention of it is to be practical and provide real-life, working examples. The opinions here are mine. It worked for me, still, it doesn't mean it would work for you.


すべてのエラー処理をコードから削除しました.エラーを処理してください.
go標準ライブラリは本当に良いテストパッケージを提供します.外部フレームワークやサードパーティのパッケージなしで管理することができます.私のシナリオでは、私が書いたWebクライアントをテストする必要があります.私が見つけたテクニックは模擬試験です.

Mock testing is an approach to unit testing that lets you make assertions about how the code under test is interacting with other system modules. In mock testing, the dependencies are replaced with objects that simulate the behaviour of the real ones. ... Such a service can be replaced with a mock object. ~ Wikipedia


どのコンポーネントをmockに選択しなければなりませんでした.
  • クライアント
  • Webサーバ
  • 高いレベルでは、クライアントのモッキングは、インターフェイスを実装するインターフェイスを実装する新しい構造体を作成することを意味します.次に、テスト中のコードにあなたのモッキングクライアントを提供します.例の良いライブラリですtestify .
    私は私のユースケースに役に立つとは知りませんでした.できればクライアントのコードを変更しない方がいいです.これは私のパッケージの信頼性の高いテストになります.それで、私は第2のオプションで行くほうを選びました.どうやって読むか.

    HttpTestパッケージ
    GOは非常にWebサービスに友好的ですそれはutility package (httptest) HTTPサーバのテスト.テストコードでWebサーバーを起動できます.
    最初に、私は本当のウェブサーバ(Vault Server)から正確な応答を得なければなりませんでした.例えば、/v1/auth/approle/login endポイントこの応答は以下のようになります.
    {
      "request_id": "de7c8097-1a38-50a6-b971-fe1836840e45",
      "lease_id": "",
      "renewable": false,
      ...
      ...
    }
    
    私はコンテンツを持っているので、ファイルに保存するのが簡単になります.試みtesting パッケージには別のクールな機能があります.

    The go tool will ignore a directory named "testdata", making it available
    to hold ancillary data needed by the tests.2


    ディレクトリ名を作りましたtestdata プロジェクト内でJSONコンテンツをファイルに配置します.JSON

    モッキングサーバを起動する
    コードから始めましょう.
    package main
    
    import (
        "fmt"
        "io"
        "net/http"
        "net/http/httptest"
    )
    
    func TestClientLogin(t *testing.T*) {
        mux := http.NewServeMux()
        ts := httptest.NewServer(mux)
        defer ts.Close()
    
        mux.HandleFunc("/v1/auth/approle/login", func(w http.ResponseWriter, r *http.Request) {
            // request validation logic
            ...
            // read json response
            jsonPayload, _ := ioutil.ReadFile("testdata/approleExample.json")
            w.Header().Set("Content-Type", "application/json")
            w.WriteHeader(200)
            w.Write(jsonPayload)
        })
    
        // initalize new client pointing to the testing server
        client, err := NewClient(ts.URL)
        if err != nil {
            // error handling
        }
    
        // test logic
    }
    
    あなたが行くHTTPパッケージに精通しているならば、このコードはかなり自明です.これは、標準ライブラリを使用する別の利点です-あなたが貢献するときに学ぶことが1つ少ない.
  • muxServeMux 種類HTTPリクエストマルチプレクサです.各受信要求のURLにマッチします(/v1/auth/approle/login ) 登録されたパターンのリストに対して、最も密接にURL(我々のmux . handlefunc機能体)にマッチするパターンのためのハンドラーを呼び出します.
  • tsServer 種類サーバはHTTPエンドサーバであり、ローカルループバックインターフェース上のシステム選択ポートで、エンドツーエンドのHTTPテストで使用する.使用することに注意httptest.NewServer を初期化する.
  • mux.HandleFunc(..) 呼び出すパスとハンドラ(関数)を定義します.内容は、サーバーの応答を説明します.
  • client, err := NewClient(ts.URL) 新しいクライアント(私のVaultクライアント)を作成し、テストサーバURLを動作させる.
  • このパターンの優雅さは、すべてのテストケースがすべての関連する構成を持つテストWebサーバーを持っています.モンクされた内容、テストロジックなどはすべて、テスト自体の内部で実装されます.
    これは実際には、デバッグ時には、テストケースのロジックやカバレッジを確認簡単に人生を作る.
    我々はさらに、コードをより明確かつ簡潔に改善することができます.このコードには、いくつかのBoilerPlateが含まれています.我々は、ちょうどこれらの要素を再評価する必要がありますsetup() 関数とreadJson(path string) , 例えば).次に、このsetup() すべてのテストケースの関数.決めるのは読者に任せるよ.

    概要
    ソフトウェアテストの重要性に関する多数の記事があります.移動は簡単になります.常にパッケージのテストを書く必要がありますそれはちょうどそれをスキップするように多くの利点があります.しかし、多くの人々がそれを行うと私は理由を仮定することができます、それはあなたのコードに任意の機能を提供していません.これらの人々の1つでないでください.
    GO標準ライブラリは素晴らしいツールを提供し、それらを使用する必要があります.個人的には、私は他の依存性よりも好きです.
    このポストでは、Webクライアントをテストすることができる方法の実用的な例を与えた.
    持ち帰り

  • 常にテストを書きます.彼らは、あきらめて、非常に簡単に行くことに価値があります.

  • コードが接続されている部分をモックしてください.あなたがサーバーを書くならば、クライアントをモックしてください、そして、逆に.それはあなたのテストをはるかに信頼性にする.
  • サーバーをモックアップする場合は、実際のサーバー応答を取得し、ファイルに保存
  • あなたがモックを望むすべてのAPIのためにそれをしてください
  • 用途testdata あなたのテストに必要な補助データを保持するディレクトリ
  • 次の記事では、TLS(HTTPS)Webサーバーと自己署名証明書でテストする方法を説明します.また、ソースコードでより多くの例を見つけることができます.
    フィードバックとコメントは歓迎です.
    https://www.vaultproject.io/
    https://golang.org/pkg/cmd/go/internal/test/