Prev: Hi, friends. I wanna ask if there is a function which is able totake a list as argument and then return its top-k maximums?
Next: Smtpd module
From: Cameron Simpson on 23 Apr 2010 01:37 I've run into a problem unittesting something I'm writing. I have a little node tracking class I'm using to track items and attributes. An item is a "Node" object, and the collection is a "NodeDB". So I'm writing some unittests, thus: class Node(dict): [...] class NodeDB(dic): [...] class Backend(object): def serialise(self, value): ''' Convert a value for external string storage. ''' if isinstance(value, Node): [...] return ":%s:%s" % (value.type, value.name) t = type(value) assert t in (str,int), repr(t)+" "+repr(value)+" "+repr(Node) [...] class TestAll(unittest.TestCase): def setUp(self): from cs.nodedb.sqla import Backend_SQLAlchemy self.backend=Backend_SQLAlchemy('sqlite:///:memory:') self.db=NodeDB(backend=self.backend) def test01serialise(self): H = self.db.newNode('HOST', 'foo') for value in 1, 'str1', ':str2', '::', H: s = self.backend.serialise(value) assert type(s) is str self.assert_(value == self.backend.deserialise(s)) [...] if __name__ == '__main__': import sqlalchemy print 'SQLAlchemy version =', sqlalchemy.__version__ unittest.main() and it's failing. I've traced the failure cause, ending up with this assertion message from the end of serialise() above: AssertionError: <class '__main__.Node'> HOST:foo:{} <class 'cs.nodedb.node.Node'> Experienced users will see at once what's happened: I've made a Node myself in the test using the local class, and the Node class is thus __main__.Node. However, my sql Backend class has independently imported the "Node" and "Backend" classes from "cs.nodedb.node". So when _it_ calls serialise(), "Node" is "cs.nodedb.node.Node". And lo, the: if isinstance(value, Node): test at the top of serialise() fails. What's a sensible way of doing this correctly? I _don't_ want to duck-type the Node and merely test for "type" and "name" values, because I want to be rather picky about what gets into the backend database - the wrong types indicate bad app code, and should not be allowed to introduce corrupt database values. Cheers, -- Cameron Simpson <cs(a)zip.com.au> DoD#743 http://www.cskk.ezoshosting.com/cs/ That particular mistake will not be repeated. There are plenty of mistakes left that have not yet been used. - Andy Tanenbaum <ast(a)cs.vu.nl>
From: Peter Otten on 23 Apr 2010 07:25
Cameron Simpson wrote: > and it's failing. I've traced the failure cause, ending up with this > assertion message from the end of serialise() above: > > AssertionError: <class '__main__.Node'> HOST:foo:{} <class > 'cs.nodedb.node.Node'> > > Experienced users will see at once what's happened: I've made a Node > myself in the test using the local class, and the Node class is thus > __main__.Node. However, my sql Backend class has independently imported > the "Node" and "Backend" classes from "cs.nodedb.node". So when _it_ > calls serialise(), "Node" is "cs.nodedb.node.Node". > > And lo, the: > > if isinstance(value, Node): > > test at the top of serialise() fails. > > What's a sensible way of doing this correctly? Move the unit tests into a separate script and have that import the module cs.nodedb.node. In general, avoid importing a module and at the same time using it as the main script. When persistent objects are involved "the same time" can even spread over distinct runs of separate scripts accessing the same data. Obvious? But you asked for a /sensible/ way. Peter |