web-dev-qa-db-ja.com

OSSプロジェクトの統合テスト-認証でサードパーティを処理する方法?

私の(オープンソースの)趣味プロジェクトの1つは、GitHub、Bitbucketなどからリポジトリのオフラインバックアップを作成するバックアップツールです。
ホスティング業者のAPIを呼び出してリポジトリのリストを取得し、Git/Mercurial/whateverを使用してリポジトリをローカルコンピュータに複製/プルします。

つまり、認証を使用してGitHub APIを呼び出す統合テストがあります。
(そして、クローン/プル機能が終了すると、おそらくGitHubからリポジトリをクローンするテストがあり、認証も必要になります)

特にこれらの統合テストで使用するために ユーザー組織 を作成しました。

問題:オープンソースであり、コードがGitHubで公開されているため、ソースコードのどこかにパスワードをハードコードすることはできません。


私が今やっていること

テストでは、環境変数からすべてのユーザー名、パスワード、リポジトリ名を取得しています。
例はこちら

config.Name = TestHelper.EnvVar("GithubApiTests_Name");
config.Password = TestHelper.EnvVar("GithubApiTests_PW");

TestHelper.EnvVarは、環境変数の値を取得し、存在しない場合は例外をスローするヘルパーメソッドです)

次に、これらの環境変数を設定するバッチファイルがあります。
実際のもの(environment-variables.bat)は、ビルドスクリプトでテストを実行する前に呼び出されますが、ソース管理では無視されるため、実際にはリポジトリにありません。

ソース管理のenvironment-variables.bat.sample であり、同じ環境変数を設定しますが、偽のパスワードを使用します。

rem copy/rename this file to environment-variables.bat

echo Setting environment variables for integration tests...

set GithubApiTests_Name=scm-backup-testuser
set GithubApiTests_OrgName=scm-backup-testorg
set GithubApiTests_PW=not-the-real-password
set GithubApiTests_Repo=scm-backup

リポジトリを自分のマシンに複製し、このファイルの名前をenvironment-variables.batに変更し、偽のパスワードを実際のパスワードに置き換えると、すべての統合テストが機能します。

これは継続的インテグレーションでも機能します-私はAppVeyorを使用しており、そこで これらの環境変数をWeb UIで設定します です。


それについて私が嫌いなこと

私はそれがOSSプロジェクトにとって良い解決策ではないと思います、そして特にthisプロジェクトではそうではありません:

理論的には、私のプロジェクトの貢献者は、次の方法で統合テストをすぐに実行できます。

  • gitHubに自分のテストユーザーとテスト組織を作成する
  • テストリポジトリの作成
  • 独自のバージョンのenvironment-variables.batを異なる値で作成する

問題は、私のアプリケーションが複数のソースコードホスティングサービスをバックアップできることです。
現在、GitHubのみをサポートしていますが、適切なインターフェースを実装するいくつかのクラスを追加することで、より多くのホスティング事業者のサポートを簡単に追加できます。

したがって、後でより多くのホスティング事業者のサポートを実装すると、環境変数の数が増加します。
すべての統合テストを実行できるようにするには、潜在的な貢献者が、GitHub、Bitbucket、GitLabなどで独自のユーザー、組織、テストリポジトリを作成します。そして、誰がさらに多くを知っていて、それらすべてを彼のenvironment-variables.batバージョンに追加します。

コードが公開されているプロジェクトでこれを行う方法のより良い解決策はありますか?

他のプロジェクトが、私が現在やっていることと同じようなことをしていることを知っています。
Octokit.net たとえば、GitHub APIを呼び出す統合テスト用に a script to setup environment variables があります。
しかし、必要なのは1人のユーザーと1つの組織だけであり、さらに多くのものが必要になります。

たぶん、寄稿者が実際にall統合テストを実行できるようにするソリューションは必要ありません。
たとえば、誰かが私のプロジェクトのGitHubサポートに貢献したい場合は、GitHub統合テストを実行できればよいだけです。
それで、統合テストを無数の「グループ」(?)に分割し、「グループ「Github」に属するすべてのテストを実行する」ことができるようにするための健全な方法が必要かもしれません。 。

10

現在の設定で問題ないと思いますが、いくつか調整を行います。

すべての統合テストを実行できるようにするには、潜在的な寄稿者がGitHub、Bitbucket、GitLabなどで独自のユーザー、組織、テストリポジトリを作成し、さらに詳しい情報を知っている人がすべてを環境変数に追加します。 .batバージョン。

はい、そうですが、コントリビューターはプロジェクトでPRを作成する前に、必ずしもすべての統合テストを実行する必要はありません。 PRが作成されると、CIは完全なテストスイートを実行します。

どういうわけか簡単に実行できないテストスイートがあるのが一般的です。多くの組織では、実行に数日かかるテストスイートを維持しています。そのため、開発者は実行が簡単なテストを選択的に実行し、より厳密なテストのためにコードをプッシュする必要があります。私は同じアプローチを提案しています。

通常の/信頼できる寄稿者の場合、プロジェクトの実際の寄稿者にして、PRを作成する前にブランチでCIを実行できるようにする必要がありますbefore

そうは言っても、あなたは貢献者が完全なテストスイートを実行することを防止していません。彼らは独自のGitHub資格情報を提供したり、独自のテストアカウントを作成したりできます。通常の寄稿者がこれを行う可能性があります。

私が提案する調整は次のとおりです。

まず、ほとんどのテストカバレッジユニットテストを行います。これらは、コードベースのすべてのブランチをカバーする必要があります。

次に、エンドポイントがモックされる統合テストを記述します。これらのAPIのトランスポート層をモックして、偽のGitHub Restサービスを開始することで、HTTP要求/応答フローをシミュレートすることもできます。例(疑似コード):

// Test failed authentication to GitHub
val server = new WebServer("localhost", 9453, { request =>
    return Response(401, "unauthenticated")
})
server.start()
val backupService = new GitHubBackupService("http://localhost:9453")
backupService.backup must throw UnauthenticatedException()
server.stop()

これらのテストはより複雑になりますが、

  1. 偽のアカウントとリポジトリを作成せずにテストする
  2. 実際のGitHubでシミュレートするのが難しいであろう障害状態をテストします。たとえば、502応答、接続タイムアウト、異常な/解析不可能な応答本文。

3番目に、特別な知識が必要なテストを通常のビルドで実行しないようにします。ほとんどのビルド管理ツールには、統合テストまたはタグテストを分離して選択的に実行する方法があります。コントリビューターは、ソフトウェアをビルドしてテストできる必要がありますなし以前の構成。完全なテストスイートは、CIでの各ビルド後に実行する必要があります。

最後に、貢献者がテストを実行することを選択できるように、テストとその実行方法をテストドキュメントに文書化します。

2
Samuel