実践例

Pythonによるテスト入門

Alexander Levin

Data Scientist

データとパイプライン

データ: データサイエンスの給与。

各行には、給与、職種、その他属性を持つデータサイエンス職の情報が入っています。

ds 給与テーブル

パイプライン: 平均給与の算出

  1. データを読み込む
  2. 雇用形態でフィルタ
  3. 平均給与を取得
  4. 結果を保存
Pythonによるテスト入門

パイプラインのコード

import pandas as pd

# データ取得用フィクスチャ
@pytest.fixture
def read_df():
    return pd.read_csv('ds_salaries.csv')
# データをフィルタする関数
def filter_df(df):
    return df[df['employment_type'] == 'FT']
# 平均を取得する関数
def get_mean(df):   
    return df['salary_in_usd'].mean()
Pythonによるテスト入門

統合テスト

テストケース:

  • データの読み込み
  • ファイルへの書き込み

コード:

def test_read_df(read_df):
    # データフレームの型を確認
    assert isinstance(read_df, pd.DataFrame)
    # 行があることを確認
    assert read_df.shape[0] > 0
Pythonによるテスト入門

統合テスト

Python がファイルを作成できるかの確認例。

def test_write():
    # 書き込みモードで開く
    with open('temp.txt', 'w') as wfile:
        # テキストを書き込む
        wfile.write('Testing stuff is awesome')
    # ファイルの存在を確認
    assert os.path.exists('temp.txt')
    # 後片付けを忘れずに
    os.remove('temp.txt')
Pythonによるテスト入門

ユニットテスト

テストケース:

  • フィルタ後のデータは雇用形態が 'FT' のみ
  • get_mean() は数値を返す

コード:

def test_units(read_df):
    filtered = filter_df(read_df)
    assert filtered['employment_type'].unique() == ['FT']
    assert isinstance(get_mean(filtered), float)
Pythonによるテスト入門

機能テスト

テストケース:

  • 平均が 0 より大きい
  • 平均がデータ内の最大給与を超えない

コード:

def test_feature(read_df):
    # データをフィルタ
    filtered = filter_df(read_df)
    # テスト: 平均は 0 より大きい
    assert get_mean(filtered) > 0
    # テスト: 平均は最大値を超えない
    assert get_mean(filtered) <= read_df['salary_in_usd'].max()
Pythonによるテスト入門

パフォーマンステスト

テストケース:

  • パイプラインの開始から終了までの実行時間

コード:

def test_performance(benchmark, read_df):
    # ベンチマーク用デコレータ
    @benchmark
    # 計測対象関数
    def get_result():
        filtered = filter_df(read_df)
        return get_mean(filtered)
Pythonによるテスト入門

最終テストスイート

import pytest

## Integration Tests
def test_read_df(read_df):
      # データフレームの型を確認
    assert isinstance(read_df, pd.DataFrame)
    # 行があることを確認
    assert read_df.shape[0] > 0
def test_write():
    with open('temp.txt', 'w') as wfile:
        wfile.write('12345')
    assert os.path.exists('temp.txt')
    os.remove('temp.txt')

## Unit Tests
def test_units(read_df):
    filtered = filter_df(read_df)
    assert filtered['employment_type'].unique() == ['FT']
    assert isinstance(get_mean(filtered), float)
## Feature Tests
def test_feature(read_df):
    # データをフィルタ
    filtered = filter_df(read_df)
    # テスト: 平均は 0 より大きい
    assert get_mean(filtered) > 0
    # テスト: 平均は最大値を超えない
    assert get_mean(filtered) <= read_df['salary_in_usd'].max()

## Performance Tests
def test_performance(benchmark, read_df):
    # ベンチマーク用デコレータ
    @benchmark
    # 計測対象関数
    def pipeline():
        filtered = filter_df(read_df)
        return get_mean(filtered)
Pythonによるテスト入門

Ayo berlatih!

Pythonによるテスト入門

Preparing Video For Download...