はじめに
FIELDNOTES は小さな実習用博物館です。来館者は展示を見て入口を調べ、オフラインで読める案内をダウンロードします。サイトを更新する前に、トップページの応答成功だけでなく、来館に必要な一連の機能を確認できるテストが必要です。
短い Python テストを補い、正常なパッケージを受け入れ、欠落や誤案内のあるダウンロードを拒否できることを確かめます。基本的な端末操作ができれば十分です。必要な Python と HTTP はこの実習で説明します。サイト開発、外部アカウント、ソフトウェアのインストールは不要です。博物館と住所は架空です。
Live Website はポート 8081 の現在のサイト、Candidate Preview はポート 8082 の独立したプレビューです。Workstation は /home/labex/project/release-gate にある準備済み端末です。各単元は独立して開始し、プレビューが公開サイトを変更することはありません。
来館者の一連の操作を確認する
このステップでは、実際の来館者の要件を自動テストにし、正常なパッケージと不具合のあるパッケージを区別できることを確認します。Live Website から始めます。
正常なサービスを理解する
Explore the exhibition ↗ を開き、Close to home を読んで Plan your visit ↗ を選びます。来館案内には Entrance: East gate と表示されます。Download visitor guide ↓ を選び、ダウンロードしたテキストを開きます。こちらにも Entrance: East gate が必要です。ダウンロードはブラウザーが保存するファイルで、保存先はブラウザーの設定によります。FIELDNOTES でホームに戻ります。Visit から Step-free route ↗ も開きます。アクセス案内ページとそのダウンロードは Garden ramp を説明しています。これらの機能を維持する必要があります。
Workstation に切り替えます。ls はディレクトリ内の名前を一覧表示し、cat はファイルを表示します。
ls
packages、drafts、live、preview、tests.py、pipeline.sh、tools.py があるはずです。パッケージは保存されたファイルの集まりで、.tar.gz は圧縮アーカイブ形式です。drafts/ は編集可能な作業コピーです。tools.py は提供されたローカル実行ツールであり、ホスト型 CI サービスではありません。
cat tests.py
HTTP はブラウザーが使う要求と応答のプロトコルです。200 は応答成功、404 は要求したリソースがないことを示します。入口が間違った 200 の応答も、来館者にとっては失敗です。接続エラーは利用可能な応答が届かなかったことを意味します。
内容の確認を補う
python3 は Python コードを実行します。提供された read(base, path) 関数は指定パスを要求し、そのテキストを返します。base は実行ツールが選ぶ一時サーバーのアドレスです。def は関数を定義し、字下げした行はその関数に属します。with は読み終えた応答を閉じます。assert condition, 'message' は条件が偽なら失敗にします。in は応答に期待するテキストが含まれるか調べます。引用符内はそのままの文字列です。= は代入、+ は文字列の連結です。補うのは来館案内のアサーションだけですが、確実に編集できるよう小さなファイル全体を示します。
cat > tests.py はファイルを置き換えます。<<'PYTHON' はヒアドキュメントの開始です。最後の PYTHON を単独行にするところまで、ブロック全体を貼り付けます。引用符によりコードはそのまま保たれます。字下げを正確に維持してください。
cat > tests.py <<'PYTHON'
from urllib.request import urlopen
def read(base, path):
with urlopen(base + path, timeout=3) as response:
assert response.status == 200, 'Expected HTTP 200: ' + path
return response.read().decode('utf-8')
def check(base):
home = read(base, '/')
assert 'FIELDNOTES' in home, 'Missing museum homepage'
assert 'href="/visit.html"' in home, 'Missing visit link'
visit = read(base, '/visit.html')
assert 'Entrance: East gate' in visit, 'Wrong entrance on visit page'
assert 'href="downloads/guide.txt"' in visit, 'Missing visitor download link'
guide = read(base, '/downloads/guide.txt')
assert 'Entrance: East gate' in guide, 'Wrong visitor guide content'
PYTHON
ページの href="downloads/guide.txt" は相対リンクです。/visit.html からは /downloads/guide.txt に解決されます。/ で始まるリンクはサイトのルートを起点にします。実際のリンクとリンク先の内容の両方を調べます。使われていない別の URL だけを調べると、来館者の不具合を見逃す可能性があります。
信頼する前にテストを検証する
実行ツールの check は、一つのパッケージを一時ディレクトリに展開し、本物の HTTP サーバーを起動して check(base) を呼びます。合格したバイト列を後で使えるよう保存します。パッケージの公開や修復は行いません。
python3 tools.py check packages/reference.tar.gz
PASS: visitor checks. Frozen package ... が表示されます。末尾の識別子は変動します。Python が SyntaxError や IndentationError を出したらテスト自身の誤りです。ブロックを書き直し、候補を判断する前に正常な参照パッケージで再確認します。
次の二つは意図的に失敗させます。
python3 tools.py check packages/missing.tar.gz
ダウンロードが存在しないため、FAIL: HTTP Error 404: File not found が表示されます。同じ端末で続けてください。失敗しても端末は閉じません。
python3 tools.py check packages/wrong.tar.gz
FAIL: Wrong visitor guide content が表示されます。この候補は 200 を返しますが、来館者を間違った入口へ案内します。合格させるためにアサーションを消してはいけません。参照を拒否したり、この候補を受け入れたりするテストは役に立ちません。
ブラウザーの結果と比較する
preview は Candidate Preview のファイルだけを選びます。
python3 tools.py preview packages/wrong.tar.gz
Candidate Preview に切り替えて再読み込みします。展示を開き、Plan your visit に進みます。ページは East gate のままですが、ダウンロードした来館案内は West gate と記されています。この不一致が内容アサーションの必要性を示します。
Workstation に戻り、正常な候補のプレビューを選びます。
python3 tools.py preview packages/candidate.tar.gz
Candidate Preview でホームに戻り、再読み込みして来館案内とダウンロードを繰り返します。今度は両方とも East gate です。Live Website の元のサイトも正常です。不具合のある候補を公開せずに業務動作を調べられました。ブラウザーでのダウンロード自体は自動テストを実行しません。二つの観察は別々の証拠になります。
まとめ
来館者の操作経路を確認し、内容アサーションを補い、ダウンロードの欠落と応答成功でも内容が誤っている場合を区別しました。公開サイトは変更されていません。



