openwisp / netengine

Python abstraction layer for extracting information from network devices.
http://netengine.rtfd.org
Other
38 stars 17 forks source link

[qa] Add mocks to unit tests #48

Closed purhan closed 3 years ago

purhan commented 3 years ago

Replaced calls with mocks for the following unit tests:

Closes #46

purhan commented 3 years ago

@purhan since we are mocking tests, can we remove the need to defined test-settings.json? What will we have to achieve to be able to do that?

We can hard-code some fake credentials in the tests, what do you think?

purhan commented 3 years ago

@pandafy Done, all tests should now run without test-settings.json. Just run

nosetests

PS: I noticed that tests for HTTP backend are not included when you run this command.

purhan commented 3 years ago

On executing above command actual network calls should be executed in tests instead of mocks. This will ensure that along with the test suite, our mocks are also correct.

What do you think about this?

I have a couple of queries related to this:

  1. What if we want to run a test separately? eg: nosetests tests.snmp.openwrt Then we lost this ability

Possible solution: we can make use of environment variables in settings.py which will be used in each test file.

  1. We use patches in context managers, and I could not find an inbuilt solution to disable/unpatch those patches

Possible solution: we can define a class like this:

class DisableMock(object):
        ...
        def start(self):
            pass

        def stop(self):
            pass

        def __enter__(self, *args, **kwargs):
            return self

        def __exit__(self, *args, **kwargs):
            pass

We can then use this class to disable any patch:

if settings['disable_mocks']:
        self.ssh_patcher = DisableMock()

Edit: Done in https://github.com/openwisp/netengine/pull/48/commits/f6f4eb538f051f4ca1fa05f30adb905e2ee84c54

nemesifier commented 3 years ago

@purhan do you think you can write a custom patch decorator or context manager which works conditionally? The environment variable sounds like a good solution to me, it's quite flexible and we already use it for the sample app tests (eg: SAMPLE_APP=1).

So if you can write this custom patch method, it would trigger the mocking only if the env variable is not set. Do you think you can do that?

purhan commented 3 years ago

:warning::warning::warning: @nemesisdesign @pandafy I've made an important change in https://github.com/openwisp/netengine/pull/48/commits/4e240ecdeae6613a3444257c065a47d1511158d9 that could've been a blunder.:warning::warning::warning:

Earlier, I was patching internal functions of netengine, eg:

# This will not detect if `next` breaks, which is an internal function of netengine
'netengine.backends.snmp.openwrt.SNMP.next'

Now:

# `nextCmd` comes from pysnmp and is not a part of netengine
'netengine.backends.snmp.base.cmdgen.CommandGenerator.nextCmd'

Now all the patched functions are from external libraries only

nemesifier commented 3 years ago

@nemesisdesign @pandafy I've made an important change in 4e240ec that could've been a blunder.

Earlier, I was patching internal functions of netengine, eg:

# This will not detect if `next` breaks, which is an internal function of netengine
'netengine.backends.snmp.openwrt.SNMP.next'

Now:

# `nextCmd` comes from pysnmp and is not a part of netengine
'netengine.backends.snmp.base.cmdgen.CommandGenerator.nextCmd'

Now all the patched functions are from external libraries only

Yes, It may have caused issues.