本文へ移動
cccskills
無料GitHub で公開

pytest-marks

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

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

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

インストール方法を見る

含まれるファイル(1)

  • SKILL.md8.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

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でユニットテストも除外されてしまうマークは「特別な条件が必要なもの」だけに付与

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

cc-sdd-restack-after-merge

無料日本語概要

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判定の順で進める。

studiogadget/skills32026年5月25日 更新

cc-sdd-review-slice-stack

無料日本語概要

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

studiogadget/skills32026年5月25日 更新

ci-stable-log-testing

無料日本語概要

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

studiogadget/skills32026年5月25日 更新

create-issue

無料日本語概要

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

studiogadget/skills32026年5月25日 更新

docker-deployment-guide

無料日本語概要

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

studiogadget/skills32026年5月25日 更新

hibernate-pc

無料日本語概要

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

studiogadget/skills32026年5月25日 更新

studiogadget のスキルをすべて見る

このスキルの問題を報告する