0

We have a massive amount of test cases classes to perform some checks. I need to generate all those same tests but change the value of a variable. For example:

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)

There are like 150 tests like that, I can't copy paste the code. I need to iterate over globals, access to every (class_name, class object), check if the class is a test class, and if so I need to instantiate a new test class that has the same body as the class test currently in access, but I need to set a different value to base_url variable. This is what I don' t understand how to achieve.

FranGoitia
  • 1,965
  • 3
  • 30
  • 49
  • have you tried iterating over `globals()`? does it not work? do you know how to instantiate a class? – scytale Aug 21 '15 at 13:41
  • I don't understand how I can instantiate the needed classes to solve the problem. – FranGoitia Aug 21 '15 at 13:46
  • you don't understand how to instantiate a class? or how to go about it in this case. what about iterating over `globals()` ? – scytale Aug 21 '15 at 13:49
  • I can't copy paste the code. I iterate over globals, access to every (class_name, class object), check if the class is a test class, and if so I need to instantiate a new test class that has the same body as the class test currently in access, but I need to set a different value to base_url variable. This is what I don' t understand how to achieve. – FranGoitia Aug 21 '15 at 13:53
  • you're not going to get clear answers if you omit essential information like that from your question – scytale Aug 21 '15 at 13:55
  • and what on earth has copy/pasting got to do with it? – scytale Aug 21 '15 at 14:00

1 Answers1

1

simple update of object attribute:

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

if you can't instantiate then you can do

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

    new_classes.append(NewClass)

ok that's probably not exactly what you want - you'll want to dynamically assign the class name etc... but maybe this solves your initial problem of dynamically generating new classes with modified class vars

there are other ways - class decorators, metaclasses - it really depends on other details about what you are trying to do

scytale
  • 12,346
  • 3
  • 32
  • 46
  • I can't modify those classes. I need to create new ones that test the same thing, but base_url has a different value. – FranGoitia Aug 21 '15 at 14:19
  • you can modify the instance of the class. try it. – scytale Aug 21 '15 at 14:22
  • you said originally you need to instantiate a new test class... now you say you need to create new classes - it's not really clear what you're trying to do. you realise you can modify class attributes (`base_url`) and that you can create instances with modified class attributes? alternatively you could use a metaclass... it's hard to know what to say with out you making things more clear – scytale Aug 21 '15 at 14:29
  • You are right. I'm sorry, english is not my natural language and it can be hard sometimes to express myself correctly and I'm new to this kind of metaprogramming. I need to create new classes in which base_url has a different value. Apart from that the environment should be the same. – FranGoitia Aug 21 '15 at 14:39
  • and it's not enough to instantiate a new object and change `base_url` ? – scytale Aug 21 '15 at 14:40
  • I can't instantiate objects from those classes, so thing() doesn' t work. – FranGoitia Aug 21 '15 at 14:41
  • Thanks ! I edited class names with __name__ attribute – FranGoitia Aug 21 '15 at 15:03