[Avocado-devel] [RFC] Recursive Test Discovery [V2]

Amador Pahim apahim at redhat.com
Wed Jun 7 10:27:51 UTC 2017


On Wed, Jun 7, 2017 at 9:15 AM, Lukáš Doktor <ldoktor at redhat.com> wrote:
> Dne 7.6.2017 v 00:35 Jeff Nelson napsal(a):
>
>> On Fri, 2 Jun 2017 09:26:32 +0200
>> Amador Pahim <apahim at redhat.com> wrote:
>>
>>> Motivation
>>> ==========
>>>
>>> Currently we can discover test classes that does not inherit directly
>>> from `avocado.Test`. To do so, we rely on the inclusion of a docstring
>>> (`:avocado: enable`) in the mentioned class. Example below.
>>>
>>> File `/usr/share/avocado/tests/test_base_class.py`::
>>>
>>>      from avocado import Test
>>>
>>>
>>>      class BaseClass(Test):
>>>
>>>          def test_basic(self):
>>>              pass
>>>
>>> File `/usr/share/avocado/tests/test_first_child.py`::
>>>
>>>      from test_base_class import BaseClass
>>>
>>>
>>>      class FirstChild(BaseClass):
>>>          """
>>>          :avocado: enable
>>>          """
>>>
>>>          def test_first_child(self):
>>>              pass
>>>
>>> In the example above, if we ask Avocado to list the tests from
>>> `test_first_child.py`, `FirstChild.test_first_child` will be listed and
>>> the `BaseClass.test_basic` won't::
>>>
>>>      $ avocado list test_first_child.py
>>>      INSTRUMENTED test_first_child.py:FirstChild.test_first_child
>>>
>>> The request is that, in such cases, we have a way to include the
>>> `BaseClass.test_basic` into the results.
>>>
>>> Proposal
>>> ========
>>>
>>> To include the parent classes into the discovery results, we have three
>>> main aspects to consider:
>>>
>>> - How to flag that we want that behaviour?
>>>    The proposal is the creation of a new docstring `recursive`. Example::
>>>
>>>      class FirstChild(BaseClass):
>>>          """
>>>          :avocado: recursive
>>>          """
>>>          ...
>>
>>
>> I like everything about this RFC except for the word "recursive,"
>> because I don't think what is being described is a recursive process.
>> Recursion is a technique to "divide a problem into smaller subproblems
>> of the same type." [1] I don't think that's what is happening here.
>> Instead, I imagine this as discovering the class hierarchy in an
>> iterative fashion, from the starting class to the base class.
>>
>> So if I'm not fond of "recursive" what do I think should be used
>> instead? Here is a list of words that I put together, some better than
>> others:
>>
>> * discovery
>> * discover
>> * ancestors
>> * ancestor-discovery
>> * hierarchy
>> * include-hierarchy
>> * inheritance
>> * inheritance-walk
>> * ancestry
>>
> Well out of those I'd still go with recursive, anyway I'm not native.
> Recursive to me means do the same process with some data till the end
> (condition) which is exactly what are we doing. We consider this class
> avocado and recurs into all ancestors. Basically it's recursive discovery so
> the word recursive IMO fits.

I have the same feeling. Considering this list and the word
'recursive', 'recursive' is the only word that would make me to figure
out the feature without extra thoughts on it.
The only suggestion I have would be 'discover-parents'. But yes, the
discovery method is calling itself until the end of the chain, so it's
indeed a software recursion. That's internal implementation detail
though.

>
> Lukáš
>
> PS: The implementation actually is recursive as it calls the same method to
> discover the parent classes ;-)
>
>
>> It's hard coming up with a descriptive word that describes the process
>> of discovering the classes in the inheritance hierarchy. The word
>> "ancestry" is the term I favor the most.
>>
>> This is not a NACK; maybe it will spark some ideas. If not, that's
>> OK too.
>>
>> -Jeff
>>
>>
>> [1] https://en.wikipedia.org/wiki/Recursion#In_computer_science
>>
>>
>>>
>>> - How deep is the recursion?
>>>    The proposal is that the recursion goes all the way up to the class
>>>    inheriting from `avocado.Test`.
>>>
>>> - Will the recursion respect the parents docstrings?
>>>    The proposal is that the docstrings in the parents are ignored when
>>>    recursively discovering. Example:
>>>
>>>    File `/usr/share/avocado/tests/test_base_class.py`::
>>>
>>>      from avocado import Test
>>>
>>>
>>>      class BaseClass(Test):
>>>          """
>>>          :avocado: disable
>>>          """
>>>
>>>          def test_basic(self):
>>>              pass
>>>
>>>    File `/usr/share/avocado/tests/test_first_child.py`::
>>>
>>>      from test_base_class import BaseClass
>>>
>>>
>>>      class FirstChild(BaseClass):
>>>          """
>>>          :avocado: recursive
>>>          """
>>>
>>>          def test_first_child(self):
>>>              pass
>>>
>>>    Will result in::
>>>
>>>      $ avocado list test_first_child.py
>>>      INSTRUMENTED test_first_child.py:FirstChild.test_first_child
>>>      INSTRUMENTED test_first_child.py:BaseClass.test_basic
>>>
>>>
>>> Expected Results
>>> ================
>>>
>>> The expected result is to provide users more flexibility when creating
>>> the Avocado tests, being ablr to create a chain of test classes and
>>> providing only the module containing the last one as a test reference.
>>>
>>> Additional Information
>>> ======================
>>>
>>> Avocado uses only static analysis to examine the files and this
>>> feature should stick to this principle in its implementation.
>>>
>>
>
>




More information about the Avocado-devel mailing list