Giter VIP home page Giter VIP logo

Comments (9)

arnm avatar arnm commented on September 26, 2024 1

I believe this could be enhanced further. TestNG's @DataProvider is what this really should be.

I really would like to do somethings like this:

def get_data():
    return ( (1, 2), (2, 3,), )

@ddt
class TestMe(unittest.TestCase):
    @unpack
    @data(get_data())
    def test_func(self, first, second):
        # each tuple in the returned tuple is unpacked
        pass

I want more control of what data is passed into the test. Being able to generate all inputs for a test programmatically from a function, like TestNG does, would be a great way to go.

from ddt.

santtu avatar santtu commented on September 26, 2024

I think that is more useful, since it removes need for one (extra) unpack. Alternatively it might be possible to pass a dict, which then would be used to match based on argument name (e.g. kwargs-like).

However this probably would lead to three different cases:

  • is data list or tuple (or subclass)? use as *args
  • is data dict (or subclass)? use as **kwargs
  • otherwise, assume a single argument to function

This would mean that @data(1,2,3) is interpreted as call to testfunc three times with one argument, @data((1,2),(3,4)) would be two calls, each with two arguments, @data({'a':1},{'b':2}) calls testfunc twice, once as testfunc(a=1) and second time as testfunc(b=1).

On the other hand, if you really wanted to pass a tuple, it would need to be wrapped in a tuple like @data(((1,),),(2,),)) would call testfunc((1,)) and testfunc((2,)). With the same logic to pass a dict would need @data(({...},), ...).

This would leave case of needing to pass both _args and *_kwargs at the same time unsolved, requiring a custom wrapper, but other cases would be covered by argument unboxing as above.

An alternative way would be to provide decorators that would do this and leave @DaTa itself to pass only single value, always. Developer could then choose the correct underlying decorator to unbox data. Like this:

  @data(1,2,3)
  def test_single_value(self, value):
    ...

  @data((1,2), (2,3))
  @args
  def test_two_values(self, value_1, value_2):
    ...

  @data({'a':2}, {'b':3})
  @kwargs 
  def test_named_args(self, a=None, b=None):
    ...

Or perhaps provide @data in different flavors, e.g. @data, @data_args, @data_kwargs and make these pre-format data to fill a single form (maybe (args, kwargs) tuple)?

from ddt.

txels avatar txels commented on September 26, 2024

I like the idea of the extra decorator. Why not this?:

  @unpack
  @data((1,2), (2,3))
  def test_two_values(self, value_1, value_2):
     ...

  @unpack
  @data({'a':2, 'b':3}, {'a':6})
  def test_named_args(self, a=None, b=None):
    ...

A single unpack decorator that unpacks dicts as positional arguments and tuples as keyword arguments.
Although in the context of tests I am not sure about the value of keyword arguments, so I would implement a simple tuple unpacker first.

from ddt.

santtu avatar santtu commented on September 26, 2024

+1 for @unpack, I think it is a clean and simple and covers at least for now what I think is a majority of cases where the simple single-value (e.g. current behavior) test caller isn't enough.

OTOH; I think the order has to be

  @data(...)
  @unpack 
  def abc(...): ...

as it is turned into abc = data(unpack(...)) and the @ddtdecorator needs to see the @data decorator('s result) first.

from ddt.

txels avatar txels commented on September 26, 2024

I do not think the order matters, as the method decorators are just adding information to the method that will later get processed by the class decorator. For some reason having unpack first looks more natural to me.

from ddt.

santtu avatar santtu commented on September 26, 2024

I trust you, I didn't check how @data works :-) A lot of decorators do wrap the function in a new function, which effectively is a delegate for the original one... on the other hand, it is all coming back to be now.. @data uses setattr on the original method, and doesn't delegate... so in that case, of course, it doesn't matter.

@unpack itself would have to be a delegate decorator, and would have to pass __name__ upwards to let @ddtpick up the correct name (in case the data __name__ wasn't there).

What would happen if @unpack is used multiple times?

    @unpack 
    @unpack 
    @data(a, b)
    def test_func(...): ...

This would turn by @ddt into:

    test_func_a = unpack(unpack(a))
    test_func_b = unpack(unpack(b))

Perhaps it is easiest to just concluce that @unpack will work only with a single argument to unbox, in which case unpack(unpack(..)) wouldn't be legal.

from ddt.

txels avatar txels commented on September 26, 2024

Well, you have seen that I am using decorators in a non-typical way. I was planning for unpack to work the same way, which means it will just add an additional attribute to the original method (say %unpack=True) that would be used by the ddt decorator to call feed_data in a special way.

If I do it this way, no matter how many unpacks you use it won't make a difference.

from ddt.

txels avatar txels commented on September 26, 2024

Solved in #16

from ddt.

viswagb avatar viswagb commented on September 26, 2024

@arnm is your above comments any progress, im too looking same..in ddt

from ddt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.