HelloThisIsFlo/Appdaemon-Test-Framework

args not available within `initialize`

nickw444 opened this issue · 1 comments

The documentation seems to imply when configuring a fixture I can provide arguments that will be accessible during initialize:

# Single Class w/ params:
@automation_fixture((upstairs.Bedroom, {'motion': 'binary_sensor.bedroom_motion'}))

However, my test failed when trying to access this.args within initialize:

self = <apps.alarm_auto_arm.MyAutomation object at 0x108216820>

    def initialize(self):
>       print(self.args['foo'])
E       KeyError: 'foo'

apps/alarm_auto_arm.py:14: KeyError

Example Code:

class MyAutomation(hass.Hass):
    def initialize(self):
        print(self.args['foo'])


def test_my_automation(given_that, my_automation, assert_that):
    pass


@automation_fixture((MyAutomation, {
   'foo': 'bar'
}))
def my_automation():
    pass

My workaround is currently to do the following, but wondering if there was a more "blessed" way to achieve this:

@pytest.fixture
def my_automation(given_that):
    my_automation = MyAutomation(None, None, None, None, None, None, None)
    my_automation.args = {
        'foo': 'bar',
    }
    my_automation.initialize()
    given_that.mock_functions_are_cleared()
    return my_automation

Hey @nickw444

Thanks for the issue, and sorry for the late response.

It is possible to simulate arguments that would be passed via the apps.yaml config, but using @automation_fixture is not the way to go. Passing arguments to @automation_fixture allows for parametrised tests.

To pass arguments to apps just like apps.yaml would do, use given_that.passed_arg(ARG_KEY).is_set_to(ARG_VAL)
See:

Maybe the documentation could benefit from some readability upgrade. Once you understand how everything work, and once it's working for you, maybe you could submit a PR with your suggestions on how to make the documentation more readable? 🙂
But don't feel like you have to, I'm already happy when anyone is using our tool 😊

Best,
Florian


Explanation of what passing args to @automation_fixture does

In that example

@automation_fixture((MyAutomation, {
   'foo': 'bar'
}))
def my_automation():
    pass

my_automation would not actually represent your automation, a better name for this fixture would be my_automation_with_arguments. Indeed when adding arguments to @automation_fixture the fixture returned is not just the automation, but the automation with the arguments. This is useful for parameterized testing, but has nothing to do with the arguments passed via apps.yaml
To see an example of how it work, you can check this test where it showcases the feature: https://github.com/FlorianKempenich/Appdaemon-Test-Framework/blob/master/test/test_automation_fixture.py#L264-L322