Среда тестирования Python с поддержкой нефатальных отказов

Вы могли использовать этот метод 1 глоток>, который использует ClassLoader.

/**
 * Scans all classes accessible from the context class loader which belong to the given package and subpackages.
 *
 * @param packageName The base package
 * @return The classes
 * @throws ClassNotFoundException
 * @throws IOException
 */
private static Class[] getClasses(String packageName)
        throws ClassNotFoundException, IOException {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    assert classLoader != null;
    String path = packageName.replace('.', '/');
    Enumeration resources = classLoader.getResources(path);
    List dirs = new ArrayList();
    while (resources.hasMoreElements()) {
        URL resource = resources.nextElement();
        dirs.add(new File(resource.getFile()));
    }
    ArrayList classes = new ArrayList();
    for (File directory : dirs) {
        classes.addAll(findClasses(directory, packageName));
    }
    return classes.toArray(new Class[classes.size()]);
}

/**
 * Recursive method used to find all classes in a given directory and subdirs.
 *
 * @param directory   The base directory
 * @param packageName The package name for classes found inside the base directory
 * @return The classes
 * @throws ClassNotFoundException
 */
private static List findClasses(File directory, String packageName) throws ClassNotFoundException {
    List classes = new ArrayList();
    if (!directory.exists()) {
        return classes;
    }
    File[] files = directory.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            assert !file.getName().contains(".");
            classes.addAll(findClasses(file, packageName + "." + file.getName()));
        } else if (file.getName().endsWith(".class")) {
            classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
        }
    }
    return classes;
}

__________
1 глоток> Этот метод был взят первоначально от http://snippets.dzone.com/posts/show/4831 , который был , заархивировал интернет-Архивом, как связано с теперь. Отрывок также доступен в https://dzone.com/articles/get-all-classes-within-package.

5
задан housemaister 20 August 2009 в 16:28
поделиться

5 ответов

Мне нужно было что-то подобное для функционального тестирования, которое я выполняю с помощью носа. В конце концов я пришел к такому выводу:

def raw_print(str, *args):
    out_str = str % args
    sys.stdout.write(out_str)

class DeferredAsserter(object):
    def __init__(self):
        self.broken = False
    def assert_equal(self, expected, actual):
        outstr = '%s == %s...' % (expected, actual)
        raw_print(outstr)
        try:
            assert expected == actual
        except AssertionError:
            raw_print('FAILED\n\n')
            self.broken = True
        except Exception, e:
            raw_print('ERROR\n')
            traceback.print_exc()
            self.broken = True
        else:
            raw_print('PASSED\n\n')

    def invoke(self):
        assert not self.broken

Другими словами, он распечатывает строки, указывающие, прошел ли тест или нет. В конце теста вы вызываете метод invoke, который фактически выполняет реальное утверждение. Это определенно нежелательно, но я не видел фреймворка для тестирования Python, который мог бы обрабатывать такого рода тестирование. Я также не придумал, как написать плагин для носа, чтобы делать такие вещи. : - /

2
ответ дан 15 December 2019 в 06:31
поделиться

Как ни странно, похоже, что вы ищете что-то вроде моего claft (командная строка и тестер фильтров). Что-то вроде этого, но гораздо более зрелое.

claft - это (пока) просто игрушка, которую я написал, чтобы помочь студентам с упражнениями по программированию. Идея состоит в том, чтобы предоставить упражнениям простые файлы конфигурации, которые представляют требования программы в терминах, которые достаточно удобочитаемы (и декларативны, а не программны), а также подходят для автоматического тестирования.

claft запускает все определенные тесты. , предоставление аргументов и входных данных каждому, проверка кодов возврата и сопоставление выходных данных ( stdout ) и сообщений об ошибках ( stderr ) по шаблонам регулярных выражений. Он собирает все ошибки в списке и печатает весь список в конце каждого набора.

Он еще НЕ выполняет произвольные диалоги последовательностей ввода / вывода. Пока он просто загружает данные, а затем считывает все данные / ошибки. Он также не реализует тайм-ауты и, по сути, даже не фиксирует неудачные попытки выполнения. (Я ведь говорил, что это просто игрушка, не так ли?). Я также еще не реализовал поддержку скриптов Setup, Teardown и External Check (хотя у меня есть планы сделать это).

Предложение Брайана о «структуре роботов» может быть лучше для ваших нужд; хотя беглый взгляд на него подсказывает, что для моих целей он гораздо сложнее, чем я хочу. (Мне нужно, чтобы все было достаточно простым, чтобы студенты, не знакомые с программированием, могли сосредоточиться на своих упражнениях и не тратить много времени на борьбу с настройкой своего тестового снаряжения).

Вы можете взглянуть на claft и использовать его или получить оттуда собственное решение (оно лицензировано BSD). Очевидно, вы можете внести свой вклад. (Он находится на [bitbucket]: ( http://www.bitbucket.org/ ), так что вы можете использовать Mercurial для клонирования и форка своего собственного репозитория ... и отправить «запрос на перенос», если вы когда-нибудь захочу, чтобы я посмотрел на слияние ваших изменений с моим репо).

С другой стороны, возможно, я неправильно понимаю ваш вопрос.

буду рад внести свой вклад. (Он находится на [bitbucket]: ( http://www.bitbucket.org/ ), так что вы можете использовать Mercurial для клонирования и форка своего собственного репозитория ... и отправить «запрос на перенос», если вы когда-нибудь захочу, чтобы я посмотрел на слияние ваших изменений с моим репо).

С другой стороны, возможно, я неправильно понимаю ваш вопрос.

буду рад внести свой вклад. (Он находится на [bitbucket]: ( http://www.bitbucket.org/ ), так что вы можете использовать Mercurial для клонирования и форка своего собственного репозитория ... и отправить «запрос на перенос», если вы когда-нибудь захочу, чтобы я посмотрел на слияние ваших изменений с моим репо).

С другой стороны, возможно, я неправильно понимаю ваш вопрос.

1
ответ дан 15 December 2019 в 06:31
поделиться

Вы просили совета, поэтому я предлагаю каркас робота .

1
ответ дан 15 December 2019 в 06:31
поделиться

Обновление:

Судя по комментариев, похоже, что у многих людей проблемы с XML. Я знаю, что сейчас это круто, и у него есть свои проблемы, но в данном случае я думаю, что это работает. Одна из других причин, по которой я выбрал его, заключается в том, что существует множество библиотек для его анализа, что может облегчить жизнь.

Другая ключевая концепция заключается в том, что информация действительно нереляционная . Так что да, вы можете хранить данные в любом конкретном примере в кучу разных таблиц с большим количеством объединений, но это больно. Но если бы я продолжал приводить вам несколько другие примеры, держу пари, вам придется до бесконечности изменять свой дизайн. Я не думаю, что добавление таблиц и изменение сложных операторов SQL - это очень весело. Так что немного расстраивает то, что за комментарий @ scheibk проголосовали.

Исходное сообщение:

Я думаю, что проблема, с которой вы можете столкнуться с хранением информации о квестах в базе данных, заключается в том, что она не совсем реляционная (то есть не очень легко помещается в таблицу). Возможно, именно поэтому у вас возникли проблемы с созданием таблиц для данных.

С другой стороны, если вы поместите информацию о вашем задании непосредственно в код, это означает, что вам придется редактировать код и перекомпилировать каждый раз, когда вы хотите добавить квест. Хромой.

Так что, если бы я был на вашем месте, я мог бы подумать о сохранении информации о моих квестах в XML-файле или в чем-то подобном. Я знаю, что это универсальное решение для чего угодно, но в данном случае оно мне подходит. XML действительно создан для хранения не связанных и / или иерархических данных, точно так же, как материал, который вам нужно хранить для вашего квеста.

Резюме: вы можете придумать свою собственную схему, создать свой XML-файл, а затем загрузить его каким-то образом во время выполнения (или даже сохранить XML в базе данных).

Пример XML:

-1
ответ дан 15 December 2019 в 06:31
поделиться

Почему бы и нет (в unittest , но это должно работать в любой структуре):

class multiTests(MyTestCase):
    def testMulti(self, tests):
        tests( a == b )
        tests( frobnicate())
        ...

предполагая, что ваш реализованный MyTestCase, так что функция заключена в

testlist = []
x.testMulti(testlist.append)
assert all(testlist)
0
ответ дан 15 December 2019 в 06:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: