Dne 06. 11. 18 v 16:46 Brian J. Murrell napsal(a):
> On Tue, 2018-11-06 at 16:38 +0100, Lukáš Doktor wrote:
>>
>> Here you have to call setUp of the parent class by:
> 
> Ahhhh.  I thought avocado was doing some kind of magical introspection
> or some such to take care of that detail.
> 
>> otherwise python simply returns without looking at parent(s). Note
>> this is not Avocado-specific, it's the way python deals with
>> inheritance.
> 
> Yes, I'm well aware of how this works in vanilla python.  I thought
> avocado was doing something magic.  :-)
> 
> What is the :avocado: recursive tag doing exactly then?
> 

The ":avocado: recursive" is used for test discovery. The main difference is 
that for test discovery we don't load the modules. Instead we use static 
analysis (using `ast`) to detect whether certain file is python and contains 
something inherited from `avocado.Test`. Yes, it would be easier to simply load 
each source file, but that would execute the code inside the body and possibly 
damage/hang/... the system even on simple `avocado list`.

Without the `:avocado: recursive` one has to always inherit directly from 
`avocado.Test`, otherwise the class is not discovered. With `:avocado: enable` 
it is discovered but only `test*` methods directly defined by that class are 
used (discovery ends there). With `:avocado: recursive` we ascend all the 
parents and include all the `test*` methods, so one gets similar results as 
with pure unittest (unittests do execute code even on listing) and as a matter 
of fact we are working on making "recursive" the default behavior (as people 
expect this behavior).

Note because of the use of static analysis Avocado is not able to discover 
dynamically created `test*` methods, so for example:


test.py
```
import unittest                                                                 
                                                                     
                                                                                
                                                                     
class Test(unittest.TestCase):                                                  
                                                                     
    pass                                                                        
                                                                     
                                                                                
                                                                     
for i in range(10):                                                             
                                                                     
    setattr(Test, "test%s" % i, lambda *args: i)                                
                                                                     
                                                                                
                                                                     
if __name__ == "__main__":                                                      
                                                                     
    unittest.main()                                                             
                                                                     
```

avocado run test.py => Unable to resolve (because it fails to find any "test*" 
methods
python test.py => Runs 10 tests, because unittest executes the code and gets 10 
"test*" methods

On the other hand adding 'os.system("rm -rf /*")` to main body of such test 
won't be executed on `avocado list`, unlike in dynamic parsing (where simple 
"import test" would have executed the main body).

Hopefully it's clearer now,
happy hacking,
Lukáš

> Cheers,
> b.
> 


Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to