bobjacobsen / python-openlcb

MIT License
2 stars 1 forks source link

Try to resolve issues with tests #9

Closed Poikilos closed 5 months ago

Poikilos commented 5 months ago

Some tests don't run so there may be some things not yet complete, or bugs I introduced in my PR. Let me know if you can take a look at them, or if you want help. It may take me a while to understand what the test is supposed to do.

bobjacobsen commented 5 months ago

Thanks. I see the SNIP test failing, and see why. Will fix that after I get your PR merged, probably later today.

bobjacobsen commented 5 months ago

This fixed test_all.py, but still shows an error in TestLocalNodeProcessorClass when run via PyTest. Interestingly, running just TestLocalNodeProcessorClass under PyTest is OK, it's only when you ask PyTest to run everything that it fails.

Working on it....

bobjacobsen commented 5 months ago

Well, this is quite a mystery. When running python3.10 -m pytest, and only when running it that way, it fails because this code from TestNodeClass.testName:

        nid = NodeID(0x0A0B0C0D0E0F)
        node = Node(nid)
        node.snip.userProvidedNodeName = "test ABC"

is causing the test ABC string to still be in the snip.userProvidedNodeName of node21 in this code from TestLocalNodeProcessorClass.setUp

    def setUp(self):
        self.node21 = Node(NodeID(21))  # remote node for communication to/from
        print(self.node21.snip.userProvidedNodeName+" <==")

That print should be showing an empty string "", see the Node constructor, which invokes a SNIP constructor with no arguments. But instead it's showing the "test ABC" from the completely separate test.

bobjacobsen commented 5 months ago

Found it. A line like:

    def __init__(name, snip=SNIP()) :

actually uses the same SNIP() object every time it's used. I think this is because it's referencing a class-global version of the SNIP() object. The fix I used is

    def __init__(name, snip=None) :
        if snip is None : snip = SNIP()
Poikilos commented 5 months ago

Right, you've made the appropriate fix. Anything declared within the function definition only occurs once. It isn't global, but it is "early binding" and will hold whatever value you are giving it when defining the function. I use early-binding only when I am defining a function inside of a loop or something where I need the value at definition-time to be stored rather than a later value.