Skip to content
cccskills
FreePublished on GitHub

pytest-marks

pytestのマーク体系を設計・実装するスキル。

「テストをマークで分類したい」「CIでDockerテストをスキップしたい」「Dockerコンテナ内で実行できないテストを除外したい」「make testでDockerテストを実行したい」「テストの実行対象を環境ごとに切り替えたい」「新しいマークを追加したい」「skipifを使いたい」「pytestの--strict-markersで未定義マークエラーが出る」という依頼で起動。

マーク設計→pyproject.toml登録→テストコード付与→CI/ローカルコマンド整合の流れで実装する。

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md8.9 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

pytest マーク体系設計・実装スキル

pytestのカスタムマークを用いて、実行環境・所要時間・外部依存に応じてテスト実行を制御するパターンを設計・実装する。

仕組みの概要

テスト実行環境          除外すべきテスト           コマンド
─────────────   →   ─────────────────   →   ─────────────────────────
GitHub Actions CI      docker, slow        -m "not docker and not slow"
ローカル開発            (任意)              -m "not slow" など
Docker コンテナ内        docker + skipif     自動除外(skipif が動作)
ローカルDocker実行       (全て実行)        make test  # MakefileでDocker切り替え時

Step 1: マーク名の設計

テストを付与するマークは実行環境・制約の種類で命名する。unit / integration のような実装段階そのものの分類名をそのまま付けるのではなく、「このテストが動く/動かない条件」「何を必要とするか」を名前にする。

マーク設計表(参考)

マーク名意味除外すべき環境
slow実行に数十秒以上かかるCI(高速化が必要な場合)、ローカル日常開発
integration外部依存ありをまとめて表す包括ラベル(外部サービス・ファイルシステム・DB など)。可能なら external_service / db / filesystem など、より具体的なマークを優先するモック環境のみのCIジョブ
dockerDockerコマンド・Docker Compose等のホストレベル操作を含むCI、Dockerコンテナ内
network外部URLへの実通信を含むオフライン環境、CI回線制限時
browserPlaywrightなどのブラウザ自動操作を含むブラウザ未インストール環境
flaky環境依存・タイミング依存で不安定なテストCI strict実行

命名原則: 「このテストが何を必要とするか」を名前にする。integration を使う場合も「結合テストだから」ではなく「外部依存があるため制御したい」という制約ベースの意味に限定する。test_ メソッド名と重複させない。


Step 2: pyproject.toml への登録

markers へ追加しないと --strict-markers 設定下でエラーになる。

[tool.pytest.ini_options]
addopts = [
    "--strict-markers",   # 未登録マーク使用をエラーにする(必須)
    "--strict-config",
    # ...
]
markers = [
    "slow: marks tests as slow (deselect with '-m \"not slow\"')",
    "integration: marks tests as integration tests",
    "docker: marks tests as docker-related (deselect with '-m \"not docker\"')",
    # 追加する場合はここへ
    # "network: marks tests requiring outbound network access",
    # "browser: marks tests requiring a browser (Playwright etc.)",
]

登録書式:

"<マーク名>: <説明文>"

説明文は英語・日本語どちらでも可だが、英語が一般的。


Step 3: テストコードへのマーク付与

3-A: クラスレベルマーク(推奨)

同一クラスのテスト全体に同じマークを付ける場合は、クラス宣言へデコレートする。

import pytest
from pathlib import Path

@pytest.mark.docker
@pytest.mark.skipif(
    Path("/.dockerenv").exists(),
    reason="Dockerコンテナ内ではDockerコマンドが利用できないためスキップ",
)
class TestDockerBuild:
    """DockerビルドのテストはDockerホスト上でのみ実行する。"""
    ...

3-B: メソッドレベルマーク

一部のテストのみに付ける場合はメソッドへデコレートする。

class TestReportGenerator:

    def test_正常系_HTMLレポートを生成する(self) -> None:
        ...  # マーク不要な軽量テスト

    @pytest.mark.slow
    def test_正常系_大量データでレポートを生成する(self) -> None:
        ...  # 重いテストのみ slow マーク

3-C: skipif パターン(環境依存スキップ)

テストを除外する方法は2つある。使い分けを間違えないこと。

方法動作用途
-m "not docker"コレクション時点で除外(テスト一覧に出ない)CI の実行対象制御
pytest.mark.skipif(...)収集するが実行時スキップ("s"と表示)実行環境での自動判定

Docker コンテナ内での自動スキップ:

@pytest.mark.docker
@pytest.mark.skipif(
    Path("/.dockerenv").exists(),   # /.dockerenv はDockerコンテナ内に存在するファイル
    reason="Dockerコンテナ内ではDockerコマンドが利用できないためスキップ",
)
class TestDockerBuild:
    ...

他のskipif条件の例:

import os
import sys
import shutil

# OS依存
@pytest.mark.skipif(sys.platform != "linux", reason="Linuxのみ対応")

# コマンド依存
@pytest.mark.skipif(shutil.which("docker") is None, reason="docker コマンドが見つからない")

# 環境変数依存
@pytest.mark.skipif(
    os.environ.get("SLACK_WEBHOOK_URL") is None,
    reason="SLACK_WEBHOOK_URL が未設定",
)

Step 4: CI(GitHub Actions)での活用

4-A: 基本パターン(重いテスト・環境依存テストを除外)

- name: Run tests
  run: |
    uv run pytest tests/ \
      --ignore=tests/poc \
      -m "not docker and not slow" \
      -v

4-B: 複数ジョブで役割分担する

jobs:
  test-unit:
    name: Unit Tests
    steps:
      - run: uv run pytest tests/ -m "not docker and not slow and not network"

  test-integration:
    name: Integration Tests
    if: github.ref == 'refs/heads/main'   # mainブランチのみ
    steps:
      - run: uv run pytest tests/ -m "integration and not docker"

  test-docker:
    name: Docker Tests
    if: github.ref == 'refs/heads/main'
    steps:
      - run: uv run pytest tests/ -m "docker"

4-C: スケジュール実行で重いテストだけ実行

on:
  schedule:
    - cron: "0 0 * * 1"   # 毎週月曜

jobs:
  test-slow:
    name: Slow Tests (Weekly)
    steps:
      - run: uv run pytest tests/ -m "slow"

Step 5: ローカル開発でのコマンド例

# 全テスト(ローカル通常実行)
uv run pytest tests/

# docker・slow を除いて実行(CI相当)
uv run pytest tests/ -m "not docker and not slow"

# docker テストだけ実行
uv run pytest tests/ -m "docker"

# slow テストだけ実行(週次レビュー等)
uv run pytest tests/ -m "slow"

# Docker コンテナ内でテスト実行(docker マーク付きは skipif で自動除外)
make test  # MakefileでDocker実行に切り替え後

チェックリスト

新しいマークを追加するとき:

  • pyproject.toml の markers に登録した(--strict-markers でエラーにならないか確認)
  • マーク名が「何を必要とするか」を示している(実装内容ではなく制約)
  • skipif が必要な場合は条件式が正しい(Path("/.dockerenv").exists() 等)
  • CI workflow で適切に除外または含めている
  • ローカル開発用コマンド(Makefile 等)を更新した

アンチパターン

アンチパターン問題代替策
unit / e2e という名前のマーク実装分類であり、実行可否の判断に使えないslow, docker, network など制約ベースで命名
--strict-markers なしでマーク使用タイポが検出されず、指定したマークが無視されるaddopts に --strict-markers を追加
skipif のみで CI 制御(-m なし)テストが収集されるため実行時間が増加する-m "not docker" で収集前に除外する
全テストに integration マークCIでユニットテストも除外されてしまうマークは「特別な条件が必要なもの」だけに付与

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

stacked PRの下位PRがマージされた後に上位branchをrestack(rebase/cherry-pick再構成)する際に使用。「restackして」「上位PRを更新して」「restack after merge」「PRのbaseを更新」「スタックを整理」という依頼でトリガーする。対象sliceの特定→rebase→変更ファイル確認と代表テスト実行→force-with-leaseでpush→PR base更新→auto-merge判定の順で進める。

The English summary is being prepared. Showing the original description.

studiogadget/skills3Updated May 25, 2026

cc-sdd実装用統合ブランチのコミット群(ベースブランチとの差分)をreview slice単位のstacked PRに再構成する際に使用。「review sliceに分割」「stacked PRを作成」「PRをスタックして」「レビュー用にPRを分けて」「review slice stack」という依頼でトリガーする。dry-run(既定)でslice計画を提示し、apply指示で実際にブランチ・PRを作成する。

The English summary is being prepared. Showing the original description.

studiogadget/skills3Updated May 25, 2026

CI環境で安定動作するPythonテスト(特にstructlogのログ検証)を書く際に使用。「CIで失敗する」「capture_logsが不安定」「ログアサーションがCIだけ落ちる」「caplogフォールバック」「ANSI混入」「xdistでログが取れない」という課題で起動。capture_logs→caplogフォールバック→ANSI正規化→アサーション設計の流れで堅牢なテストを書く。

The English summary is being prepared. Showing the original description.

studiogadget/skills3Updated May 25, 2026

GitHub Issueを作成してGitHubに投稿するスキル。「Issueを作成」「Issue作成」「Issueにして」「Issueとして投稿」「GitHubにIssue」「create issue」「open issue」「バグ報告」「機能追加をIssueに」「改善提案をIssueに」などの依頼でトリガーする。コンテキスト収集→Issue本文生成→ラベル存在確認・作成→gh issue create投稿の流れでIssueを作成する。

The English summary is being prepared. Showing the original description.

studiogadget/skills3Updated May 25, 2026

Dockerベースのアプリケーションのデプロイメント手順書(Markdown)を作成するスキル。「デプロイ手順書」「デプロイメント手順」「deployment guide」「本番環境への配置手順」「サーバーへの配置手順」などの依頼でトリガーする。Docker Composeビルド→イメージ転送→サーバー配置→設定→動作確認→cron設定の流れで手順書を生成する。

The English summary is being prepared. Showing the original description.

studiogadget/skills3Updated May 25, 2026

タスク完了後にPCを休止状態にする。Use when: ユーザーが「休止」「hibernate」「タスク完了後に休止状態」「作業後にPCをスリープ/休止」と明示的に指示した場合のみ。正常終了時だけでなく、エラーや未解決事項が残っていても、明示指示があれば最後に休止へ移行する。Windows only.

The English summary is being prepared. Showing the original description.

studiogadget/skills3Updated May 25, 2026

See all skills by studiogadget

Report a problem with this skill