【Go言語(Golang)】ユニットテスト時にgo-flagsに任意の引数を渡す方法

前書き:flag(Go標準)のテスト方法ばかり検索ヒット

Go言語は、コマンドライン引数をパースする機能を持つflagパッケージが標準機能として提供されています。flagパッケージは、引数パース機能に対するユニットテストを簡単にするために、”flag.Commandline.Set()”が用意されています。

その一方で、OSSとして公開されているgo-flagsパッケージはどうでしょうか?flagパッケージよりも、go-flagsの方がコマンドライン引数を簡単に扱える特徴(ショート/ロングオプションサポート、Helpメッセージ自動生成など)がありますが、テスト用の仕組みが見当たりません。

Googleで検索しても、go-flagsパッケージによるコマンドライン引数パースをテストする方法が出てこなかったため、本記事ではその方法(ベストな方法ではなく、妥協した方法)を紹介します。

                                                         

妥協案:os.Argsをテスト用の引数で上書き

まず、go-flagsパッケージを用いたコードの例として、以下を示します。n(name)オプションはオプション引数が必須ですが、それ以外のオプションはオプション引数が不要です。

上記コードでは、args() -> parseArgs() -> Parse()の順で処理が進み、最終的にコマンドライン引数のパース結果(オプション情報)が変数optsに格納されます(オプション以外の情報は、os.Argsに残ります)。

args()メソッドに任意のコマンドライン引数を渡してユニットテストするには、主に3つの処理を実装します。

  1. テスト開始時に、os.Args(コマンドライン引数を保持するstring配列)をバックアップ
  2. os.Argsに任意のコマンドライン引数(string配列)を代入
  3. テスト終了後に、os.Argsを元の状態に復元

テストコードの実装例を以下に示します。

ユニットテスト実行直後は、テスト用のコマンドライン引数がos.Argsにセットされていますが、テストコード中で使われていないように見えました(コードベースの裏取りはしておらず、テスト実行時の挙動を見てそのように判断しました)。

カバレッジもキチンと取得されています(カバレッジ結果画像中のコードは、上記のテストコードと細部が異なりますが、大枠は同じです)

他に正しい方法があるかも知れません。しかし、今回紹介した方法でもgo-flagsパッケージに対するユニットテスト実施およびカバレッジ取得が出来ます。

                    

おすすめ