<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>El Tramo | Unit Testing</title>
  <subtitle>Remko Tronçon's Homepage</subtitle>
  <link href="http://el-tramo.be/blog/tag/unit-testing/feed/" rel="self" type="application/rss+xml"/>
  <link href="http://el-tramo.be/"/>
  <updated>2012-05-19T12:29:42+02:00</updated>
  <id>http://el-tramo.be/</id>
  <author>
    <name>Remko Tronçon</name>
    <uri>http://el-tramo.be/about/</uri>
  </author>
  
  <entry>
    <title>Beautiful (XMPP) Testing</title>
    <author>
      <name>Remko Tronçon</name>
      <uri>http://el-tramo.be/about/</uri>
    </author>
    <link href="http://el-tramo.be/blog/beautiful-xmpp-testing"/>
    <updated>2009-11-02T00:00:00+01:00</updated>
    <id>http://el-tramo.be/blog/beautiful-xmpp-testing</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596159825&quot;&gt;&lt;img class=&quot;alignright&quot; style=&quot;float: right;&quot; src=&quot;http://covers.oreilly.com/images/9780596159825/cat.gif&quot; alt=&quot;&quot; width=&quot;144&quot; height=&quot;189&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;O’Reilly recently released the book &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596159825&quot;&gt;Beautiful Testing&lt;/a&gt;&lt;/em&gt;, a collection of essays about testing and QA in general. As I &lt;a href=&quot;/blog/beautiful-xmpp-testing-intro&quot;&gt;mentioned earlier&lt;/a&gt;, I wrote an article in that book on (unit) testing XMPP protocols, using &lt;a href=&quot;http://swift.im&quot;&gt;Swift&lt;/a&gt; as a motivating example. Since the book’s scope may (oddly enough) not always be as interesting for developers in general, I released my article under a &lt;a href=&quot;http://creativecommons.org/licenses/by/3.0/&quot;&gt;Creative Commons Attribution&lt;/a&gt; license (thanks to the good folks from O’Reilly for encouraging us to do this), which you can find &lt;a href=&quot;/documents/beautiful-xmpp-testing&quot;&gt;here&lt;/a&gt; (or directly from my &lt;a href=&quot;/git/beautiful-xmpp-testing/&quot;&gt;Git repository&lt;/a&gt;). The original excerpt from the book (including the index, list of biographies, and all the fancy artwork) is also &lt;a href=&quot;/documents/beautiful-xmpp-testing/BeautifulXMPPTesting-OReilly.pdf&quot;&gt;available for download&lt;/a&gt; under the same license.&lt;/p&gt;

&lt;p&gt;I of course encourage you to buy either the PDF or dead tree version of the book, as all the proceeds of the book go to &lt;a href=&quot;http://www.nothingbutnets.net/&quot;&gt;charity&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>“Beautiful Testing” XMPP Chapter</title>
    <author>
      <name>Remko Tronçon</name>
      <uri>http://el-tramo.be/about/</uri>
    </author>
    <link href="http://el-tramo.be/blog/beautiful-xmpp-testing-intro"/>
    <updated>2009-05-03T00:00:00+02:00</updated>
    <id>http://el-tramo.be/blog/beautiful-xmpp-testing-intro</id>
    <content type="html">&lt;p&gt;&lt;a href=&quot;http://adam.goucher.ca/&quot;&gt;Adam Goucher&lt;/a&gt; and Tim Riley (Director of QA at Mozilla) &lt;a href=&quot;http://adam.goucher.ca/?p=684&quot;&gt;announced&lt;/a&gt; a few months ago that they are putting together a &lt;a href=&quot;http://oreilly.com/catalog/9780596159818&quot;&gt;&lt;em&gt;Beautiful Testing&lt;/em&gt;&lt;/a&gt; book for O’Reilly. I took the opportunity to write a chapter about testing in the context of XMPP (more specifically, about testing protocol implementations in &lt;a href=&quot;http://swift.im&quot;&gt;Swift&lt;/a&gt;),  and just submitted the final draft for technical review. The book is expected to be released this August.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Although there are many types of testing being done in the XMPP world, the chapter focuses on the beauty of testing the functionality of XMPP protocol implementations. After a brief introduction on XMPP, it starts out with a description of unit testing simple IQ request/response protocols, and  then gradually moves on to higher-level testing of more complex, multi-stage protocols such as session initialization. As you might expect from a developer like me, the chapter is quite heavy on the (C++) code, but I’m told it compensates for the rest of the book ;&amp;ndash;)&lt;/p&gt;

&lt;p&gt;As with all other books in the O’Reilly “Beautiful” series (which started with &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596510046/&quot;&gt;Beautiful Code&lt;/a&gt;&lt;/em&gt;, but has since been followed up by &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596517984/&quot;&gt;Beautiful Architecture&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596518028/&quot;&gt;Beautiful Teams&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596527488/&quot;&gt;Beautiful Security&lt;/a&gt;&lt;/em&gt;, and &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596157111/&quot;&gt;Beautiful Data&lt;/a&gt;&lt;/em&gt;), all proceeds of the book go to charity, in this case &lt;a href=&quot;http://www.nothingbutnets.net/&quot;&gt;“Nothing But Nets”&lt;/a&gt; (which provides mosquito netting to malaria infested areas of Africa). This means that I can plug this book as much as I want, and still have the feeling I’m actually doing a noble, unselfish thing. (contrary to when I casually mention that you can buy our book &lt;em&gt;&lt;a href=&quot;http://oreilly.com/catalog/9780596521264/&quot;&gt;XMPP: The Definitive Guide&lt;/a&gt;&lt;/em&gt; at very sharp prices these days). Some time after the book’s release this summer, I will even make a free version of the chapter available here, so check back soon!&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Improving QtTest usability with QtTestUtil</title>
    <author>
      <name>Remko Tronçon</name>
      <uri>http://el-tramo.be/about/</uri>
    </author>
    <link href="http://el-tramo.be/blog/qttestutil"/>
    <updated>2008-11-06T00:00:00+01:00</updated>
    <id>http://el-tramo.be/blog/qttestutil</id>
    <content type="html">&lt;p&gt;As much as I like &lt;a href=&quot;http://cppunit.sourceforge.net&quot;&gt;CppUnit&lt;/a&gt; for writing C++ unit tests, I still prefer using Qt&amp;rsquo;s built-in &lt;a href=&quot;http://doc.trolltech.com/4.4/qttest.html&quot;&gt;QtTest&lt;/a&gt; module for Qt-based projects. This avoids a dependency on an external library, lowering the threshold for running and writing unit tests. Unfortunately, QtTest is very basic, and lacks some useful features such as automatic test registration and running multiple test suites in one test binary. In order to improve QtTest&amp;rsquo;s usability, I started creating some macros and classes that fill in some of the gaps, and bundled them into &lt;a href=&quot;/git/qttestutil/snapshot/qttestutil-master.zip&quot;&gt;QtTestUtil&lt;/a&gt;.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;QtTest&amp;rsquo;s recommended way to write unit tests is to compile and link one test suite per class separately, and using the &lt;code&gt;QTEST_MAIN&lt;/code&gt; macro to generate a &lt;code&gt;main()&lt;/code&gt; that runs this particular test suite. However, this introduces quite a bit of overhead in writing (creating a project file for every test/class), building (linking a binary for every test/class), and running (running a separate binary for every test/class, usually using a custom script) all unit tests. This overhead is especially painful in a project with many classes. All this conflicts with the general rule that both creating and running unit tests should be very efficient, and makes QtTest not well suited for unit testing as it is.&lt;/p&gt;

&lt;p&gt;A first attempt at solving this problem is by manually creating a &lt;code&gt;main()&lt;/code&gt; function that runs all tests. For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;pre&gt;#include &quot;MyFirstTest.h&quot;
#include &quot;MySecondTest.h&quot;

int main(int argc, char* argv) {
  int result = 0;
  MyFirstTest test1;
  result |= QTest::qExec(&amp;amp;test1, argc, argv);
  MySecondTest test2;
  result |= QTest::qExec(&amp;amp;test2, argc, argv);
  return result;
}&lt;/pre&gt;
&lt;/blockquote&gt;


&lt;p&gt;The resulting binary runs all listed test suites. The downside of this approach is that you have to write quite a bit of boilerplate code: every test binary needs to have its own &lt;code&gt;main()&lt;/code&gt; function that explicitly runs all the tests in that test suite, and which needs to be put in a file that has to include all the tests separately. In order remedy this, I took the idea from CppUnit to provide a macro which auto-registers a test suite, and makes it easy to run all registered test suites at once. Creating a test suite is now as simple as creating a &lt;code&gt;.cpp&lt;/code&gt; file for every unit test, adding a call to
&lt;code&gt;QTTESTUTIL_REGISTER_TEST&lt;/code&gt; to that file, and compiling that together with a shared &lt;code&gt;main()&lt;/code&gt; that does nothing but call &lt;code&gt;runTests()&lt;/code&gt; on the test registry. Since this &lt;code&gt;main()&lt;/code&gt; does not explicitly depend on any test, QtTestUtil comes with a &lt;a href=&quot;/git/qttestutil/tree/QtTestUtil/SimpleChecker.cpp&quot;&gt;&lt;code&gt;SimpleChecker.cpp&lt;/code&gt;&lt;/a&gt; containing this call, and which can be used by all unit test modules. As a result, no module needs to provide its own &lt;code&gt;main()&lt;/code&gt; anymore.&lt;/p&gt;

&lt;p&gt;An example of a unit test module using the macro and the shared checker described above can be found in the &lt;a href=&quot;/git/qttestutil/tree/Example&quot;&gt;Example&lt;/a&gt; subdir of the &lt;a href=&quot;/git/qttestutil&quot;&gt;QtTestUtil repository&lt;/a&gt;. It is worth noticing that these QtTest-based unit tests are more compact than the same unit test written in CppUnit (because the latter requires you to call a macro for every test in a fixture).&lt;/p&gt;

&lt;p&gt;This is just a first set of utilities that QtTestUtil provides on top of QtTest. More utility classes and macros will be added as they are needed.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Going Agile with Google Summer of Code</title>
    <author>
      <name>Remko Tronçon</name>
      <uri>http://el-tramo.be/about/</uri>
    </author>
    <link href="http://el-tramo.be/blog/gsoc-agile"/>
    <updated>2008-06-26T00:00:00+02:00</updated>
    <id>http://el-tramo.be/blog/gsoc-agile</id>
    <content type="html">&lt;p&gt;Although &lt;a href=&quot;http://psi-im.org&quot;&gt;Psi&lt;/a&gt; has had a fair number of succesful &lt;a href=&quot;http://code.google.com/soc/&quot;&gt;Google Summer of Code&lt;/a&gt; projects so far, we have experienced some failures as well: the summer before last, 3 out of 6 projects didn&amp;rsquo;t make the final deadline. A project&amp;rsquo;s failure was typically due to not having anything really usable at the end of the summer, regardless of the good work that &lt;em&gt;was&lt;/em&gt; done during the past months. To reduce the risk of such surprises, I decided to take an Agile Development approach for this year's ‘&lt;a href=&quot;http://psi-im.org/wiki/index.php?title=GSoC08_Roster_Improvements&quot;&gt;Roster improvement&lt;/a&gt;’ project.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Here are some of the principles of &lt;a href=&quot;http://en.wikipedia.org/wiki/Agile_software_development&quot;&gt;Agile software development&lt;/a&gt; (as written down in the &lt;a href=&quot;http://agilemanifesto.org/&quot;&gt;Agile Manifesto&lt;/a&gt;), and how we apply them to &lt;a href=&quot;http://gislan.utumno.pl/&quot;&gt;Adam&lt;/a&gt;&amp;rsquo;s GSoC project:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;The developer &lt;strong&gt;frequently delivers working software&lt;/strong&gt; to the customer. In our case, Adam sends me a working roster every monday, which I can play around with. I then tell him what I do and don't like about it, and he processes my feedback during the next iteration (i.e. the next week). Of course, since the roster is made from scratch, the backend of the roster is completely mocked up during the first weeks. As the project progresses, the backend will become more 'real'. &lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Working software&lt;/strong&gt; is the primary &lt;strong&gt;measure of progress&lt;/strong&gt;. This avoids the kind of surprises we had before, where both student and mentor believed everything was going fine during the project, but where nothing could be delivered at the end of the project. &lt;/li&gt;
    &lt;li&gt;Code is kept as &lt;strong&gt;simple&lt;/strong&gt; as possible: if you don't need something, leave it out. By initially focusing on the roster frontend (while keeping the backend framework mocked up), we ensure that our backend will only be as complex as we actually need it to be. Moreover, we can &lt;strong&gt;constantly change&lt;/strong&gt; our mind about the &lt;strong&gt;requirements&lt;/strong&gt; throughout the whole project without having to throw away the complete backend. This contrasts with the previous attempts we had at reworking the Psi roster, where we started by working out a complex roster backend, but never got to the point where we had something working with this (over-)designed framework, and had to start over all again.&lt;/li&gt;
    &lt;li&gt;Code is written with &lt;strong&gt;testability&lt;/strong&gt; in mind. In principle, all new code needs to be tested (and preferably even unit tested before it's written), which allows you to quickly refactor while remaining sure that your code still works as before. However, given the very strict time constraints, I'm not sure yet that we're going to apply this &lt;a href=&quot;http://en.wikipedia.org/wiki/Test-driven_development&quot;&gt;Test-driven Development&lt;/a&gt; approach (although some claim that the extra time you spend in tests will even pay off in the short term).&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;Good designs&lt;/strong&gt; make sure that you can easily adapt your code to changing requirements. For example, a &lt;a href=&quot;http://en.wikipedia.org/wiki/Model-view-controller&quot;&gt;Model-View-Controller&lt;/a&gt;-based design seems to lend itself well to the roster, making the (rather complex) roster logic both testable, extensible, and easy to understand.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I&amp;rsquo;m convinced that these principles will ensure that both Adam and I (and of course all Psi users) will get a succesful result at the end of the project, and that we&amp;rsquo;ll have had a fun time during these 3 months.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Improving Psi's roster</title>
    <author>
      <name>Remko Tronçon</name>
      <uri>http://el-tramo.be/about/</uri>
    </author>
    <link href="http://el-tramo.be/blog/psi-roster-improvements"/>
    <updated>2008-05-01T00:00:00+02:00</updated>
    <id>http://el-tramo.be/blog/psi-roster-improvements</id>
    <content type="html">&lt;p&gt;For a while now, Psi users have been requesting several changes and additions to the roster (or `&lt;em&gt;contact list&lt;/em&gt;&amp;lsquo;). These requests include grouping contacts into meta-contacts, nested roster groups, and displaying user avatars in the roster. We have been postponing all these changes to the roster as much as possible, because none of us wanted to touch the roster code, for reasons I&amp;rsquo;ll explain below. This year, Psi is fortunate enough to have &lt;a href=&quot;http://gislan.utumno.pl&quot;&gt;Adam Czachorowski&lt;/a&gt; (aka Gislan), a student from the &lt;a href=&quot;http://code.google.com/soc/&quot;&gt;Google Summer of Code&lt;/a&gt;, to work on roster improvements.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;So far, the major cause of all Psi developers staying clear from doing substantial roster changes is probably the fact that all roster-related classes are very &lt;strong&gt;tightly coupled&lt;/strong&gt; to each other. This has several consequences: &lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;It's hard to get a good &lt;strong&gt;understanding&lt;/strong&gt; of which piece of code does what, since there is no separation of logic between the different classes, and none of them work without the other one.&lt;/li&gt;
    &lt;li&gt;The code is very &lt;strong&gt;fragile&lt;/strong&gt;: if you change one tiny piece, you might break something completely different. Moreover, it's hard to tell what you broke, since the functionality is spread out across the different classes.&lt;/li&gt;
    &lt;li&gt;The code is &lt;strong&gt;untestable&lt;/strong&gt;: Since there is no decent separation of the roster logic (i.e. the structure of the roster) and the roster user interface (i.e. how it is shown), it has been impossible so far to create some form of automated tests for the roster code. Because of the tight coupling between the various classes, it is impossible to test each part of the roster functionality in isolation, making unit testing impossible. Given that the roster is the most central part of the Psi user interface, it is actually unacceptable that we have no form of testing whether it (still) functions correctly.&lt;/li&gt;
    &lt;li&gt;There can be &lt;strong&gt;no reuse&lt;/strong&gt; of any of the roster code in other parts of the UI (such as the list of participants in the MUC dialog), or even for other IM clients that are based on the back-end of Psi.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Because of these fundamental issues, a complete makeover of the roster code is in order. More specifically, we want to have a clear separation of anything that has to do with UI, and the actual logic of the roster. Additionally, we want the (untestable) UI layer to be as thin as possible, pushing as much down to the logic layer as we can. Finally, we want to achieve a full coverage of the logic layer using only unit tests.&lt;/p&gt;

&lt;p&gt;What Gislan will exactly do in his Google Summer of Code project still has to be worked out in detail. He will be responsible for a major part (if not all) of the roster rewrite, and get some new functionality in there as well (since that will be a breeze with the new code). You can follow his progress on &lt;a href=&quot;http://gislan.utumno.pl&quot;&gt;his blog&lt;/a&gt;, and get more detailed technical information on the &lt;a href=&quot;http://psi-im.org/wiki/index.php?title=GSoC08_Roster_Improvements&quot;&gt;project page&lt;/a&gt; for his GSoC project.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Unit testing method overrides</title>
    <author>
      <name>Remko Tronçon</name>
      <uri>http://el-tramo.be/about/</uri>
    </author>
    <link href="http://el-tramo.be/blog/unit-testing-overrides"/>
    <updated>2008-03-07T00:00:00+01:00</updated>
    <id>http://el-tramo.be/blog/unit-testing-overrides</id>
    <content type="html">&lt;p&gt;It probably happened to most of us developers before: while refactoring, you change the name of a virtual method, but forget to change the name of the overriding method in one of your derived classes. Compilation works fine, all unit tests pass, but your program doesn&amp;rsquo;t work: the overriding method is never called. Java (and C#) programmers can avoid this problem by putting &lt;code&gt;@Override&lt;/code&gt; (and &lt;code&gt;override&lt;/code&gt;) in front of their methods, which causes the compiler to print out an error message if the method is not overriding anything. However, most other languages leave you hanging with this problem. Luckily, with statically typed languages like C++, you can avoid these bugs by slightly adapting your unit tests.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;Suppose you have a base class &lt;code&gt;Oracle&lt;/code&gt;, and a derived class &lt;code&gt;GeekyOracle&lt;/code&gt;, defined as follows:
&lt;code&gt;&lt;/p&gt;

&lt;pre&gt;  class Oracle {
    virtual int getLckyNmbr() {
      return 13;
    }
  };

  class GeekyOracle : public Oracle {
    virtual int getLckyNmbr() {
      return 42;
    }
  };&lt;/pre&gt;


&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Being a good developer, you unit test &lt;code&gt;GeekyOracle&lt;/code&gt;&amp;rsquo;s &lt;code&gt;getLckyNmbr()&lt;/code&gt;:
&lt;code&gt;&lt;/p&gt;

&lt;pre&gt;  void GeekyOracleTest::testGetLckyNmbr() {
    GeekyOracle* oracle = createGeekyOracle();
    assertEquals(42, oracle-&amp;gt;getLckyNmbr());
  }&lt;/pre&gt;


&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;After a while, you realize that using abbreviations in method names is actually not very good practice, so you change your method name to something more readable:
&lt;code&gt;&lt;/p&gt;

&lt;pre&gt;  class Oracle {
    virtual int getLuckyNumber() {
      return 13;
    }
  };&lt;/pre&gt;


&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;However, when you compile your program now, it is behaving completely different than before, although all unit tests passed. It requires manual debugging to find out that you forgot to rename &lt;code&gt;GeekyOracle&lt;/code&gt;&amp;rsquo;s method as well, causing &lt;code&gt;Oracle&lt;/code&gt;&amp;rsquo;s &lt;code&gt;getLuckyNumber()&lt;/code&gt; to be executed, no matter what oracle you instantiate. Your unit tests didn&amp;rsquo;t catch this, because they test every method of a class separately, but don&amp;rsquo;t test the class being used in your application.&lt;/p&gt;

&lt;p&gt;A way to check for this in your unit tests is to make sure that, when testing a virtual method, you always call it on an object that is &lt;strong&gt;statically typed with its base class&lt;/strong&gt;. In our example, our unit test would call &lt;code&gt;getLckyNmbr()&lt;/code&gt; on an &lt;code&gt;Oracle&lt;/code&gt; instead of on a &lt;code&gt;GeekyOracle&lt;/code&gt;:
&lt;code&gt;&lt;/p&gt;

&lt;pre&gt;  void GeekyOracleTest::testGetLckyNmbr() {
    Oracle* oracle = createGeekyOracle();
    assertEquals(42, oracle-&amp;gt;getLckyNmbr());
  }&lt;/pre&gt;


&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;This unit test will fail to compile when you change the method name of the base class, which avoids you end up with the silly bug in your program.&lt;/p&gt;

&lt;p&gt;If your test allocates your object under test on the stack (e.g. for simplicity), you could use the following alternative:
&lt;code&gt;&lt;/p&gt;

&lt;pre&gt;  void GeekyOracleTest::testGetLckyNmbr() {
    GeekyOracle oracle;
    assertEquals(42, ((Oracle*) &amp;amp;oracle)-&amp;gt;getLckyNmbr());
  }&lt;/pre&gt;


&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;However, since this degrades the readability of the test, I prefer to add a static helper method to my unit test, and write the test as follows:
&lt;code&gt;&lt;/p&gt;

&lt;pre&gt;  static inline Oracle* p(Oracle&amp;amp; foo) {
    return &amp;amp;foo;
  }

  void GeekyOracleTest::testGetLckyNmbr() {
    GeekyOracle oracle;
    assertEquals(42, p(oracle)-&amp;gt;getLckyNmbr());
  }&lt;/pre&gt;


&lt;p&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Although I used C++ in my example, this technique should work for all statically typed languages. Advocates of dynamically typed languages claim they can compensate the lack of types by unit testing their classes properly; I wonder how they avoid this kind of problems, though.&lt;/p&gt;
</content>
  </entry>
  
  <entry>
    <title>Testing Psi</title>
    <author>
      <name>Remko Tronçon</name>
      <uri>http://el-tramo.be/about/</uri>
    </author>
    <link href="http://el-tramo.be/blog/psi-testing"/>
    <updated>2007-10-01T00:00:00+02:00</updated>
    <id>http://el-tramo.be/blog/psi-testing</id>
    <content type="html">&lt;p&gt;While the last bugs are being squeezed out of &lt;a href=&quot;http://www.kismith.co.uk/wordpress/index.php/2007/09/25/psi-011-rc3/&quot;&gt;Psi 0.11&amp;rsquo;s release candidates&lt;/a&gt;, work on 0.12 has already begun. One thing I&amp;rsquo;m excited about as a developer is the fact that we&amp;rsquo;re making the Psi codebase `testable', which has some nice consequences.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt; The first part of our effort to make Psi testable is creating &lt;strong&gt;unit tests&lt;/strong&gt; for most of our classes (using &lt;a href=&quot;http://cppunit.sourceforge.net/&quot;&gt;CppUnit&lt;/a&gt;), which should provide quick checks that our classes behave (and keep behaving) the way they should. However, the fact that Psi was not designed to be testable from the ground up makes this a non-trivial job, requiring quite some refactoring. This is something that will happen incrementally over time. A side effect of this refactoring will be an increase in modularity, allowing us to use different frontends (e.g. Cocoa) for the same code.&lt;/p&gt;

&lt;p&gt;The second part we&amp;rsquo;re working on is creating &lt;strong&gt;UI tests&lt;/strong&gt; for parts that are not automatically testable. For this, we are decoupling all our dialogs from the rest of the application, such that we can create a standalone application that allows you to toy with the dialog. This decoupling not only means that it becomes very easy to test dialogs with your own scenarios (without having to start Psi, connect to a server, &amp;hellip;), but also means that the dialogs become completely reusable for other applications.&lt;/p&gt;

&lt;p&gt;We still have a long way to go until every part of Psi is testable (either automatically or not), but I am very much looking forward to the day where all of our code is nicely decoupled, and we can run &lt;code&gt;make check&lt;/code&gt; on every commit to ensure that we didn&amp;rsquo;t break anything silly.&lt;/p&gt;
</content>
  </entry>
  
</feed>

