web-dev-qa-db-ja.com

Pydev(PythonおよびEclipse)を使用した継続的な単体テスト

バックグラウンドユニットテストをPydevEclipse環境と統合する方法はありますか?

私の単体テストはうまく実行されますが、ソースファイルの変更に基づいてバックグラウンドで実行するように統合し(たとえば、noseを使用)、結果をEclipseに統合します(コンソールでテストが失敗すると、大きな赤いXを考えています)およびトレースログビュー)。

いいえ、コマンドプロンプトの側面の鼻水はカウントされません。

RoRのものを開発するとき、私はこのEclipse統合を行いました。

ありがとう、

タル。

編集:新しいPydev(1.6.4)をチェックしてください http://pydev.org/manual_adv_pyunit.html

43
Tal Weiss

この機能はPyDev2.0.1に追加され、pythonファイルが変更されるたびに、最後のテスト実行でテストを再起動するオプションがあり、エラーのみを再実行するオプションが追加されています。エラーが見つからなかった場合は、完全なテストスイートを実行します。これは、エラーを処理し、すべてが合格したら、スイート全体の最終起動が完了したためです(その後、別のタスクに進むことができます)。

現在のナイトリービルドには、この機能が組み込まれています。

Picture with new action

36
Fabio Zadrozny

Pydevにはいくつかの単体テスト統合がありますが、それは実行構成としてのみです...だから...

これはあまりエレガントな方法ではありませんが、次の場合:

  1. プロジェクトを有効にする->自動ビルド
  2. プロジェクトのプロパティで、Programタイプの新しいビルダーを追加します
  3. テストを実行するように構成し、「自動ビルド中」を選択します

そうすれば、少なくとも、リソースの節約時にテスト結果をコンソールに出力するものが得られます。

9

PyDevにはかなり強力なスクリプトサポートがあることに気づきました。残念ながら、私はあなたのためにそれをすべて行う時間がありません(しかし、これを完了した場合は、ここに投稿してください:)

_pyedit_nose.py_という名前のファイルを作成した場合、それ以外の場合は空のフォルダーに次のようになります。

_assert cmd is not None
assert editor is not None

if cmd == 'onSave':
    from Java.lang import Runtime
    from Java.io import BufferedReader
    from Java.io import InputStreamReader

    from org.Eclipse.core.resources import ResourcesPlugin
    from org.Eclipse.core.resources import IMarker
    from org.Eclipse.core.resources import IResource

    proc = Runtime.getRuntime().exec('ls -al')
    extra_message = BufferedReader(InputStreamReader(proc.inputStream)).readLine()

    r = ResourcesPlugin.getWorkspace().getRoot()
    for marker in r.findMarkers(IMarker.PROBLEM, False, IResource.DEPTH_INFINITE):
        if marker.getAttribute(IMarker.MESSAGE).startsWith("Some test failed!"):
            marker.delete()

    for rr in r.getProjects():
        marker = rr.createMarker(IMarker.PROBLEM)
        marker.setAttribute(IMarker.MESSAGE, "Some test failed! " + extra_message)
        marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH)
        marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR)
_

このディレクトリを指すように[設定]-> [PyDev]-> [スクリプトPydev]を設定すると、ファイルが保存されるたびに、ワークスペース内のすべてのプロジェクトにエラーのマークが付けられます。

lsではなく、解析しやすい形式でテスト結果を返すスクリプトを実行し、出力を解析することで、マーカーを適切な場所に配置できるようになります。

いくつかの出発点については、これを参照してください。

  • PydevのJythonスクリプト
  • IMarker はマーカーを表すものです。
  • IResource は、マーカーを付けるものです。ワークスペース、プロジェクト、ファイル、ディレクトリなどにすることができます。resource.createMarker(IMarker.PROBLEM)は問題マーカーを作成します。
  • IProject は、プロジェクトを表すIResourceのタイプです。 members()メソッドを使用してコンテンツを取得します。
5

初めて手動でテストを実行します(実行>実行> Python単体テスト)。その後、 Ctrl+Shift+F9で保存して魔法が起こることを期待する代わりに、Ctrl+Sを使用してファイルを保存してテストを実行します。

Ctrl+Shift+F9キーの組み合わせは、最後の実行構成を再起動します。

免責事項:私はEclipseとPyDevを初めて使用するので、愚かな/明白な/間違った何かを提案している可能性があります

1
xverges

「nosy」スクリプトを拡張して、ドキュメントを自動的に作成し、テストを継続的に実行します。素晴らしいものはありませんが、仕事を成し遂げます。元のリンクがダウンしたため、ここに投稿します。元のせんさく好きなスクリプトとは異なり、これはディレクトリを再帰的にスキャンし、複数のパターンを探すことができます。

import os
import os.path
import sys
import stat
import time
import subprocess
from fnmatch import fnmatch


def match_patterns(pathname, patterns):
    """Returns True if the pathname matches any of the given patterns."""
    for pattern in patterns:
        if fnmatch(pathname, pattern):
            return True
    return False


def filter_paths(pathnames, patterns=["*"], ignore_patterns=[]):
    """Filters from a set of paths based on acceptable patterns and
    ignorable patterns."""
    result = []
    if patterns is None:
        patterns = []
    if ignore_patterns is None:
        ignore_patterns = []
    for path in pathnames:
        if match_patterns(path, patterns) and not match_patterns(path, ignore_patterns):
            result.append(path)
    return result


def absolute_walker(path, recursive):
    if recursive:
        walk = os.walk
    else:
        def walk(path):
            return os.walk(path).next()
    for root, directories, filenames in walk(path):
        yield root
        for directory in directories:
            yield os.path.abspath(os.path.join(root, directory))
        for filename in filenames:
            yield os.path.abspath(os.path.join(root, filename))


def glob_recursive(path, patterns=["*"], ignore_patterns=[]):
    full_paths = []
    for root, directories, filenames in os.walk(path):
        for filename in filenames:
            full_path = os.path.abspath(os.path.join(root, filename))
            full_paths.append(full_path)
    filepaths = filter_paths(full_paths, patterns, ignore_patterns)
    return filepaths


def check_sum(path='.', patterns=["*"], ignore_patterns=[]):
    sum = 0
    for f in glob_recursive(path, patterns, ignore_patterns):
        stats = os.stat(f)
        sum += stats[stat.ST_SIZE] + stats[stat.ST_MTIME]
    return sum


if __name__ == "__main__":
    if len(sys.argv) > 1:
        path = sys.argv[1]
    else:
        path = '.'

    if len(sys.argv) > 2:
        command = sys.argv[2]
    else:
        command = "make -C docs html; bin/python tests/run_tests.py"

    previous_checksum = 0
    while True:
        calculated_checksum = check_sum(path, patterns=['*.py', '*.rst', '*.rst.inc'])
        if calculated_checksum != previous_checksum:
            previous_checksum = calculated_checksum
            subprocess.Popen(command, Shell=True)
            time.sleep(2)

お役に立てれば。

=)

0
GoraKhargosh