Pythonパッケージテストの実行#

テストを実行することは、パッケージが期待通りに動作していることを確認するために重要です。 テストは、あなたのコンピュータと、Python のバージョンやオペレーティングシステムが異なるユーザのコンピュータで実行されることを考慮するのがよい習慣です。 テストを実行する際には、以下のことを考慮してください:

  1. テストスイートは、Python のバージョンとユーザーが使用する可能性のあるオペレーティングシステムを表す環境のマトリックスで実行します。

  2. 隔離された環境でテストを実行することで、テストとその再現性に自信を持つことができます。 これにより、あなたのコンピュータの設定によってテストがランダムにパスすることがなくなります。 たとえば、あなたのパッケージの依存関係リストで宣言されていない依存関係を、予期せずローカルシステムにインストールしてしまったかもしれません。 このような見落としは、他の人があなたのパッケージを自分のコン ピュータにインストールしたり実行しようとしたときに、問題につながる可能性 があります。

このページでは、隔離された環境でテストを実行したり、Python のバージョンを越えてテストを実行したりするために使えるツールについて学びます。

テストを実行するためのツール#

さまざまな環境でのテストのセットアップと実行を容易にするツールには、3つのカテゴリーがあります:

  1. テストフレームワーク とは、テストを書いたり実行したりするための特定の構文やツールのセットを提供するパッケージのことです。 いくつかのテストフレームワークにはプラグインがあり、テストがカバーするコードの範囲を評価するなどの機能を追加することができます。 以下では、科学的なエコシステムで最もよく使われている Python テストフレームワークの一つである pytest フレームワークについて学びます。 テストフレームワークは必要不可欠ですが、テストを実行するためだけのものです。 これらのフレームワークは、追加の自動化ツールの助けを借りずに Python のバージョンをまたいだテストを簡単に実行する方法は提供しません。

  2. 自動化ツール を使うと、ユーザー定義のコマンドを使って、テストのようなワークフローを特定の方法で実行することを自動化できます。 例えば、1つのコマンドで異なるPythonのバージョンにまたがってテストを実行できると便利です。 noxtox のようなツールも、Pythonのバージョンをまたいでテストを実行できます。 しかし、noxとtoxだけを使って異なるオペレーティングシステムでビルドをテストするのは難しいでしょう - ここで継続的インテグレーション(CI)の出番です。

  3. 継続的インテグレーション (CI): は、テストを実行するために必要な最後のツールです。 CI は、nox や tox を使って作成した自動ビルドを複製して、異なる Python 環境でパッケージを実行できるようにするだけではありません。 また、異なるオペレーティングシステム(Windows、Mac、Linux)でテストを実行することもできます。 テストを実行するためにCIを使うことについては、ここで説明します

テーブル: テスト&自動化ツール#

機能

テストフレームワーク (pytest)

テストランナー (Tox)

自動化ツール(Nox)

継続的インテグレーション(GitHub Actions)

ローカルでテストを実行する

オンラインテストを実行する

Pythonのバージョンにまたがってテストを実行する

隔離された環境でのテストの実行

オペレーティングシステム(Windows、MacOS、Linux)にまたがるテストの実行

その他の自動化タスクに使用する(ドキュメントの作成など)

テストを実行するには、どのテストフレームワーク/パッケージを使用すればよいですか?#

パッケージテストのビルドと実行には Pytest を使うことを推奨します。 Pytest は Python のエコシステムで最もよく使われているテストツールです。

Pytestパッケージ には、以下のような機能を追加するために使用できる多くの拡張機能もあります:

  • pytest-cov を使うと、テスト中にパッケージのコードカバレッジを分析し、 codecov にアップロードできるレポートを生成することができます。

注釈

お使いのエディタや IDE には、テストを実行したり、ブレークポイントを設定したり、 -no-cov フラグを切り替えたりするための便利な機能が追加されているかもしれません。 詳しくはエディタのドキュメントを参照してください。

pytest を使ってテストを実行する#

pytest を使用している場合、テストをローカルで実行することができます:

pytest

また、特定のテストファイル - このファイルを "test_module.py" と呼ぶことにします - を実行したい場合は、次のようにします:

pytest test_module.py

詳しくは ドキュメントスタートガイド をご覧ください。

あなたのコンピュータで pytest を実行すると、現在有効になっている Python 環境でテストが実行されます。 つまり、テストは単一のバージョンのPythonで、ローカルで実行しているオペレーティングシステム上でのみ実行されます。

自動化ツールは、様々な Python 環境でテストを実行するプロセスを単純化することができます。

オペレーティングシステムをまたいだテスト

異なるオペレーティングシステム間でテストを実行したい場合は、 継続的インテグレーション。 詳細はこちら を使用することができます。

テストの実行を自動化するツール#

一つのコマンドで様々な Python のバージョンや特定の環境でテストを実行するには、 noxtox のような自動化ツールを使うことができます。 noxtox も、隔離された仮想環境を作成することができます。 これにより、複数の環境や Python のバージョンをまたいだテストを簡単に実行することができます。

このガイドでは、 Nox に焦点を当てます。 nox は Python ベースの自動化ツールで、 maketox の機能をベースにしています。 nox はテストと開発のワークフローを簡素化し、効率化するように設計されています。 nox で行うことはすべて、Pythonベースのインターフェースを使って実装することができます。

その他の自動化ツール

  • Tox is an automation tool that supports common steps such as building documentation, running tests across various versions of Python, and more.

  • Hatch は、hatchlingと呼ばれる人気のあるビルドバックエンドで動作する最新のエンドツーエンドパッケージングツールです。 hatchtox のようなセットアップを提供し、異なる Python バージョンを使ってローカルでテストを実行することができます。 パッケージングのワークフローをサポートするために hatch を使っているのであれば、 nox を使うよりも hatch のテスト機能を使った方が良いかもしれない。

  • make: ビルド自動化ツールであるMakeは汎用性が高いため、テストの実行に使う開発者もいます; 特定の言語に縛られることなく、さまざまなビルドプロセスを実行するために使うことができます。しかし、Makeのユニークな構文とアプローチは、特にあなたがまだMakeに慣れていない場合、習得を難しくする可能性があります。Makeはまた、 nox がやってくれるような環境管理もしてくれません。

noxでPythonのバージョンにまたがってテストを実行する#

Nox は素晴らしい自動化ツールです:

  • Pythonベースですので、Pythonをすでに知っていれば利用しやすいです。

  • ワークフローを実行するための隔離された環境を構築します。

nox はテスト環境の作成と管理を簡単にします。 nox を使うと、仮想環境をセットアップし、好きな環境マネージャを使って Python のバージョンをまたいだテストをコマンド一つで実行することができます。

注釈

Noxのインストール

異なる Python バージョン間でテストを実行するために nox をインストールして使用する場合、nox は nox 関数で指定した Python バージョンごとに個別の venv 環境を作成して管理します。

Noxはそれぞれの環境を独自に管理します。

nox は、ドキュメントのビルド、パッケージ配布の作成、PyPI 関連の環境 (venv や virtualenv など) と conda (conda-forge` など) の両方にわたるインストールのテストなど、その他の開発作業にも使用できます。

noxを使い始めるには、プロジェクトディレクトリのルートに noxfile.py ファイルを作成します。 そして、Pythonの関数を使ってコマンドを定義します。 以下にその例をいくつか挙ます。

テスト環境#

デフォルトでは、 nox は Python 組み込みの venv 環境マネージャを使用します。 仮想環境 (venv) は自己完結型の Python 環境で、異なる Python プロジェクトの依存関係を分離して管理することができます。 プロジェクト固有のライブラリやパッケージが互いに干渉しないようにし、クリーンで整理された開発環境を促進します。

noxを使ってPythonバージョン3.9、3.10、3.11、3.12の venv 環境でテストを実行する例を以下に示します。

警告

以下のコードが動作するためには、 nox が見つけることができる4つのバージョンのPythonがコンピュータにインストールされている必要があることに注意してください。

venv環境のnox#

以下は、Pythonに組み込まれている環境マネージャーである venv を使ってテストを実行するようにnoxをセットアップする例です。

以下の例では、 pipが理解できる方法でテストの依存関係を宣言するようにpyproject.tomlをセットアップする ことを前提としていることに注意してください。 そのセットアップの例を以下に示します。

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "pyosPackage"
version = "0.1.0"
dependencies = [
  "geopandas",
  "xarray",
]

[project.optional-dependencies]
tests = ["pytest", "pytest-cov"]

上記の設定ができていれば、 session.install(".[tests]") を使ってテストの依存関係をインストールすることができます。 以下のように、1つのnoxセッションで4つの異なるPython環境(Python 3.9、3.10、3.11、3.12)でテストを実行できることに注意してください。

# This code would live in a noxfile.py file located at the root of your project directory
import nox

# For this to run you will need to have python3.9, python3.10 and python3.11 installed on your computer. Otherwise nox will skip running tests for whatever versions are missing

@nox.session(python=["3.9", "3.10", "3.11", "3.12"])
def test(session):

    # install
    session.install(".[tests]")

    # Run tests
    session.run("pytest")

上の例では、 @nox.session デコレーターを使って関数の形で nox セッションを作成しています。 デコレータの中で、実行したい python のバージョンを宣言していることに注意してください。

上記を実行するには、 --session-s と短縮されることもある)でセッションを指定し、以下のコマンドを実行します。上記の関数はtestという名前なので、セッション名はtestです。

nox --session test

conda / mamba による nox#

以下は、noxが環境マネージャーにmamba(またはconda)を使うように設定する例です。venvと違って、condaは必要なPythonの様々なバージョンを自動的にインストールできることに注意してください。conda/mambaを使う場合は、 venv のように4つのPythonバージョンをインストールする必要はありません。

注釈

noxconda を動作させるには、コンピュータに condamamba のどちらかがインストールされていることを確認する必要があります。

# This code should live in your noxfile.py file
import nox

# The syntax below allows you to use mamba / conda as your environment manager, if you use this approach you don’t have to worry about installing different versions of Python

@nox.session(venv_backend='mamba', python=["3.9", "3.10", "3.11", "3.12"])
def test_mamba(session):
    """Nox function that installs dev requirements and runs
    tests on Python 3.9 through 3.12
    """

    # Install dev requirements
    session.conda_install(".[tests]")
    # Run tests using any parameters that you need
    session.run("pytest")

上記のセッションを実行するには、次のようにします:

nox --session test_mamba