Непрерывное модульное тестирование с Pydev (Python и Eclipse) - PullRequest
43 голосов
/ 19 июня 2009

Есть ли способ интегрировать фоновые юнит-тесты в среду Pydev Eclipse?

Мои модульные тесты работают хорошо, но я хотел бы интегрировать их для запуска в фоновом режиме на основе изменений исходного файла (например, с носом) и интегрировать результат обратно в Eclipse (я думаю, большой красный X, когда тесты не пройдены с консолью и просмотром журнала трассировки).

Нет, командная строка с носом сбоку не в счет.

У меня была эта интеграция с Eclipse при разработке RoR.

Спасибо

Tal.

РЕДАКТИРОВАТЬ: Проверьте новый Pydev (1.6.4) http://pydev.org/manual_adv_pyunit.html

Ответы [ 6 ]

35 голосов
/ 13 апреля 2011

Эта функция была добавлена ​​в PyDev 2.0.1 с возможностью перезапуска тестов при последнем запуске теста при каждом изменении файла Python, с дополнительной опцией для повторного запуска только ошибок - хотя он будет запускать полный тест комплект, если ошибок не было найдено, так как идея состоит в том, что вы работаете над своими ошибками, и когда все проходят, завершается окончательный запуск всего комплекта (тогда вы можете перейти к другой задаче).

В текущую ночную сборку включена эта функция.

Picture with new action

9 голосов
/ 24 июня 2009

Pydev имеет некоторую интеграцию с модульным тестом, но это только в качестве конфигурации запуска ... так что ...

Это не очень элегантный способ, но если вы:

  1. Включить проект-> Автоматическая сборка
  2. В свойствах вашего проекта добавьте новый компоновщик типа Program
  3. Настройте его для запуска тестов и выберите «во время автоматической сборки»

Тогда, по крайней мере, вы получите что-то, что выводит результаты теста на консоль при сохранении ресурсов.

5 голосов
/ 24 июня 2009

Я только что понял, что 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)

и настройте Preferences-> PyDev-> Scripting Pydev, чтобы он указывал на этот каталог, вы получите все проекты в вашей рабочей области, отмеченные ошибкой при каждом сохранении файла.

Выполнив скрипт, который возвращает результаты теста в каком-то простом для анализа формате, а не ls и проанализировав вывод, вы сможете поместить свои маркеры в правильные места.

См. Это для некоторых отправных точек:

  • Jython Scripting в Pydev
  • IMarker - это то, что представляет маркер.
  • IResource - это то, к чему вы прикрепляете свои маркеры. Это могут быть рабочие области, проекты, файлы, каталоги и т. Д. resource.createMarker(IMarker.PROBLEM) создает маркер проблемы.
  • IProject - это тип IResource, представляющий проект. Используйте метод members() для получения содержимого.
1 голос
/ 22 февраля 2011

Я запускаю тест вручную в первый раз ( Выполнить> Выполнить от имени> Юнит-тест Python ). После этого я использую Ctrl+Shift+F9 для сохранения файлов и выполнения тестов вместо сохранения с помощью Ctrl+S и ожидания некоторой магии.

Сочетание клавиш Ctrl+Shift+F9 перезапускает конфигурацию последнего запуска.

Отказ от ответственности : Я новичок в Eclipse и PyDev, поэтому я могу предложить что-то глупое / очевидное / неправильное

0 голосов
/ 02 декабря 2010

Я улучшил «любопытный» скрипт для автоматической сборки документации и запуска тестов непрерывно. Ничего звездного, но работа сделана. Размещение здесь, потому что оригинал ссылка пошла вниз. В отличие от оригинального любопытного скрипта, этот рекурсивно сканирует каталог и позволяет искать несколько шаблонов.

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 голосов
/ 08 апреля 2010

Я использую Любопытный (доступно на pypi):

Запускайте инструмент обнаружения и выполнения теста на нос, когда исходный файл изменено.

...