2024年5月22日 星期三

Python 專案如何在提交時觸發 pytest 自動測試

Python 專案如何在提交時觸發 pytest 自動測試

使用的工具是 pre-commit 和 pytest 這兩個庫

pip install pre-commit pytest pytest-html pytest-metadata



用法其實很容易大概看一下說明就能理解了這邊寫一個範例可以自跑測試

run_tests.py

import os
import subprocess
import pytest
import argparse
from datetime import datetime

# Define the report directory
report_dir = 'reports'

def main():
    parser = argparse.ArgumentParser(description="Run pytest and generate HTML report.")
    parser.add_argument('--hook', action='store_true', help="Run as a pre-commit hook with commit hash in report filename.")
    args = parser.parse_args()

    if not os.path.exists(report_dir):
        os.makedirs(report_dir)

    # Get the current timestamp
    timestamp = datetime.now().strftime('%Y%m%d-%H%M%S')

    if args.hook:
        # Get the current commit hash
        try:
            commit_hash = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD']).strip().decode('utf-8')
        except subprocess.CalledProcessError as e:
            print(f"Error getting commit hash: {e}")
            return

        # Define the report filename with timestamp and commit hash
        report_file = os.path.join(report_dir, f'test_report_{timestamp}_aftercommit-{commit_hash[:5]}.html')

    else:
        # Define the report filename with timestamp
        report_file = os.path.join(report_dir, f'test_report_{timestamp}.html')

    # Run pytest with the HTML report option
    pytest_args = ['tests/', '--html', report_file]
    print(f"Running pytest with arguments: {pytest_args}")
    pytest.main(pytest_args)

if __name__ == "__main__":
    main()

然後直接運行就可以了,會自動測試存放在 tests 資料夾裡面的測試


比如說這個測試檔案 tests/test_sample.py-

import pytest

def divide(a, b):
    return a / b

# 正常測試
def test_divide_normal():
    assert divide(6, 3) == 2, "測試 divide(6, 3) 失敗,期望結果為 2"
    print("測試 divide(6, 3) 成功,期望結果為 2")

# 異常測試
def test_divide_abnormal():
    with pytest.raises(ZeroDivisionError):
        divide(1, 0)
    print("測試 divide(1, 0) 成功,期望拋出 ZeroDivisionError")

# 邊界測試
def test_divide_boundary():
    assert divide(1e10, 1e5) == 1e5, "測試 divide(1e10, 1e5) 失敗,期望結果為 1e5"
    print("測試 divide(1e10, 1e5) 成功,期望結果為 1e5")


也可以直接呼叫 pytest 進行測試,參數是指定資料夾

pytest tests/

會自己抓 test_ 開頭的檔案中 test_ 開頭的函式測試


使用 --html 將報告生成到 html 上

pytest tests/ --html=report.html




再來是寫 hook 這邊用工具產生的所以只要寫在 .pre-commit-config.yaml 這份檔案裏面就可以了

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: run-tests
        name: Run Tests
        entry: python run_tests.py --hook
        language: system
        stages: [commit]
        pass_filenames: false

然後執行命令安裝到 git 中

pre-commit install

這樣就完成了,再來嘗試提交看看就會自動測試了

沒有留言:

張貼留言