Python Метапрограммирование. Генерация огромного количества похожих тестов, где значение переменной изменяется

У нас есть огромное количество классов тестовых случаев для выполнения некоторых проверок. Мне нужно сгенерировать все те же тесты, но изменить значение переменной. Например:

class DynamicPivotSeriesTestCase(AuthenticatedApiTestCase):
    '''
    Test all series against a fixed category trying every format
    '''
    #binding
    ftn = utils.format_test_name

    # Test Params
    base_url, formats = API_FORMATS['pivot']
    base_test_name = 'test_pivot_series_{series}'

    # Test vars
    series = VARS

    for srs in series:
        params = {'series': srs, 'cats': 'campaign', 'from': '2013-07-31', 'to': '2013-07-31'}
        test_name = ftn(base_test_name, params)
        locals()[test_name] = utils.make_check_code(200, base_url, params, formats)

class DynamicPivotDerivedSeriesTestCase(AuthenticatedApiTestCase):
    #binding
    ftn = utils.format_test_name

    # Test Params
    base_url, formats = API_FORMATS['pivot']
    base_test_name = 'test_pivot_derived_series_{series}'

    # Test vars
    series = DERIVED_VARS

    for srs in series:
        params = {'series': srs, 'cats': 'campaign', 'from': '2013-07-31', 'to': '2013-07-31'}
        test_name = ftn(base_test_name, params)
        locals()[test_name] = utils.make_check_code(200, base_url, params, formats)

Примерно 150 таких тестов, я не могу скопировать код. Мне нужно перебрать глобальные переменные, получить доступ к каждому (имя_класса, объект класса), проверить, является ли класс тестовым классом, и если это так, мне нужно создать экземпляр нового тестового класса, который имеет то же тело, что и тест класса, доступный в данный момент, но мне нужно установить другое значение для переменной base_url. Это то, чего я не понимаю, как достичь.

1 ответ

Решение

Простое обновление атрибута объекта:

if __name__ == '__main__':
    for name, thing in globals().iteritems():
        if issubclass(thing, AuthenticatedApiTestCase):
            obj = thing()
            obj.base_url = something_new

если вы не можете создать экземпляр, тогда вы можете сделать

new_classes = []
if issubclass(thing, AuthenticatedApiTestCase):
    class NewClasS(thing):
        base_url = something_new

    new_classes.append(NewClass)

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

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

Другие вопросы по тегам