index.lxp@lxpwrap=x5255_252ehtm.htm

来自「GUI Programming with Python」· HTM 代码 · 共 384 行

HTM
384
字号
    <table border="0" cellspacing="0" cellpadding="3" width="100%"><tr><td>    <div align="center" id="bldcontent">      <a href="../default.htm"><img src="../images/opendocs.png" width="63" height="76" border="0"></a>      <br>      <div class="symbol">Your OpenSource Publisher&#153;</div>    </div>      </td></tr></table>    <div align="center" class="author">      	<a href="../products.lxp">Products</a>	&nbsp;|&nbsp;	<a href="../wheretobuy.lxp">Where to buy</a>	&nbsp;|&nbsp;	<a href="../bookstore.lxp">Retailers</a>	&nbsp;|&nbsp;	<a href="../faq.lxp">FAQ</a>	&nbsp;|&nbsp;        <a href="../writeforus.lxp">Write for Us.</a>        &nbsp;|&nbsp;        <a href="#contact">Contact Us.</a>  </div>    <table border="0" cellspacing="3" cellpadding="0" width="100%"><tr><td width="100%">      <div class="content">        <table border="0" cellspacing="2" cellpadding="0" width="100%"><tr><td width="100%">          <div align="center"><H4 CLASS="AUTHOR"><A NAME="AEN5">Boudewijn Rempt</A><br><a href="../../https@secure.linuxports.com/opendocs/default.htm"><img src=odpyqt125.png></a><br>ISBN: 0-97003300-4-4<br><a href="../../https@secure.linuxports.com/opendocs/default.htm">Available from bookstores everywhere or you can order it here.</a><p>You can download the source files for the book <a href="pyqtsrc.tgz">(code / eps) here.</a><hr></div>                    <HTML><HEAD><TITLE>Testing signals and slots</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.72"><LINKREL="HOME"TITLE="GUI Programming with Python: QT Edition"HREF="book1.htm"><LINKREL="UP"TITLE="Automatic testing with PyUnit"HREF="c5064.htm"><LINKREL="PREVIOUS"TITLE="Large projects"HREF="x5234.htm"><LINKREL="NEXT"TITLE="Conclusion"HREF="x5285.htm"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GUI Programming with Python: QT Edition</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><A accesskey="P" href="index.lxp@lxpwrap=x5234_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 14. Automatic testing with PyUnit</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x5285_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">Testing signals and slots</A></H1><P>It's quite difficult to work the signals      and slots mechanism into the unittest framework. This is not      surprising, since signals and slots quintessentially join      components together, and the unittests are meant to test each      component separately.</P><P>However, you might want to test whether      calling a method on a certain object causes it to emit the right      signals. We need a bit of a custom framework for that purpose, a      kind of signal test.</P><P>You can use the      <TTCLASS="CLASSNAME">ConnectionBox</TT> from the following script      for that purpose. It is a simple class, derived from      <TTCLASS="CLASSNAME">QObject</TT>, which has one slot,      <TTCLASS="FUNCTION">slotSlot()</TT>, that can be connected to a      signal with any number of arguments.</P><P>The arguments to the signal are stored in      the <TTCLASS="CLASSNAME">ConnectionBox</TT>, so they can be checked      later using the various assertion functions.</P><P>I have provided three assertion functions,      one to check whether the signal did arrive      (<TTCLASS="FUNCTION">assertSignalArrived</TT>), one to check whether      the number of arguments was right,      (<TTCLASS="FUNCTION">assertNumberOfArguments</TT>), and one to check      the types of the arguments using the Python      <TTCLASS="FILENAME">types</TT>      (<TTCLASS="FUNCTION">assertArgumentTypes</TT>). This provides      typenames for all built-in types, but objects created from all      user-defined classes (including PyQt classes), belong to the      <TTCLASS="VARNAME">InstanceType</TT>. This means that you cannot      check whether you got a <TTCLASS="CLASSNAME">QListViewItem</TT> or      a <TTCLASS="CLASSNAME">QListView</TT> from a PyQt signal using this      function.</P><P>It would be a nice exercise to extend this      assert with checking objects using the      <TTCLASS="CLASSNAME">QObject</TT>.<TTCLASS="FUNCTION">className()</TT>      method. Feel free...</P><PRECLASS="PROGRAMLISTING">## signals.py - unit-testing signals#import sysimport unittestimport typesfrom docviewdoc import DocviewDocfrom qt import *class ConnectionBox(QObject):    def __init__(self, *args):        apply(QObject.__init__,(self,)+args)        self.signalArrived=0        self.args=[]    def slotSlot(self, *args):        self.signalArrived=1        self.args=args    def assertSignalArrived(self, signal=None):        if  not self.signalArrived:            raise AssertionError, ("signal %s did not arrive" % signal)    def assertNumberOfArguments(self, number):        if number &#60;&#62; len(self.args):            raise AssertionError, \                  ("Signal generated %i arguments, but %i were expected" %                                    (len(self.args), number))    def assertArgumentTypes(self, *args):        if len(args) &#60;&#62; len(self.args):            raise AssertionError, \         ("Signal generated %i arguments, but %i were given to this function" %                                 (len(self.args), len(args)))        for i in range(len(args)):            if type(self.args[i]) != args[i]:                raise AssertionError, \                      ( "Arguments don't match: %s received, should be %s." %                                      (type(self.args[i]), args[i]))class SignalsTestCase(unittest.TestCase):    """This testcase tests the testing of signals    """    def setUp(self):        self.doc=DocviewDoc()        self.connectionBox=ConnectionBox()            def tearaDown(self):        self.doc.disConnect()        self.doc=None        self.connectionBox=None            def checkSignalDoesArrive(self):        """Check whether the sigDocModified signal arrives"""        self.connectionBox.connect(self.doc, PYSIGNAL("sigDocModified"),                              self.connectionBox.slotSlot)        self.doc.slotModify()        self.connectionBox.assertSignalArrived("sigDocModified")    def checkSignalDoesNotArrive(self):        """Check whether the sigDocModifiedXXX signal does not arrive"""        self.connectionBox.connect(self.doc, PYSIGNAL("sigDocModifiedXXX"),                                   self.connectionBox.slotSlot)        self.doc.slotModify()        try:            self.connectionBox.assertSignalArrived("sigDocModifiedXXX")        except AssertionError:            pass        else:            fail("The signal _did_ arrive")    def checkArgumentToSignal(self):        """Check whether the sigDocModified signal has the right           number of arguments        """        self.connectionBox.connect(self.doc, PYSIGNAL("sigDocModified"),                                   self.connectionBox.slotSlot)        self.doc.slotModify()        self.connectionBox.assertNumberOfArguments(1)    def checkArgumentTypes(self):        """Check whether the sigDocModified signal has the right            type of arguments.        """        self.connectionBox.connect(self.doc, PYSIGNAL("sigDocModified"),                                   self.connectionBox.slotSlot)        self.doc.slotModify()        self.connectionBox.assertArgumentTypes(types.IntType)def suite():    testSuite=unittest.makeSuite(SignalsTestCase, "check")    return testSuitedef main():    runner = unittest.TextTestRunner()    runner.run(suite())if __name__=="__main__":    main()    </PRE><P>Using this      <TTCLASS="CLASSNAME">ConnectionBox</TT>, you can test your      signals:</P><PRECLASS="SCREEN">boud@calcifer:~/doc/pyqt/ch9 &#62; python signals.pyCheck whether the sigDocModified signal has the right number arguments ... okCheck whether the sigDocModified signal has the right type of arguments ... okCheck whether the sigDocModified signal arrives ... okCheck whether the sigDocModifiedXXX signal does not arrive ... ok------------------------------------------------------------------------------Ran 4 tests in 0.003sOK    </PRE></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><A accesskey="P" href="index.lxp@lxpwrap=x5234_252ehtm.htm">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="H" href="index.lxp@lxpwrap=book1_252ehtm">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><A accesskey="N" href="index.lxp@lxpwrap=x5285_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Large projects</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c5064_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Conclusion</TD></TR></TABLE></DIV></BODY></HTML>      </td>      </tr>      </table>      </td>    </tr>  </table>      

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?