<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Object Mentor Blog: Tag testing</title>
    <link>http://blog.objectmentor.com/articles/tag/testing</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description></description>
    <item>
      <title>TDD on Three Index Cards</title>
      <description>&lt;p&gt;I had the opportunity to talk to a fellow who missed part of a class on &lt;span class="caps"&gt;TDD&lt;/span&gt;. I told him that I could give him a 15-minute overview, and give him all the essentials of &lt;span class="caps"&gt;TDD&lt;/span&gt; on three index cards.&lt;/p&gt;


	&lt;p&gt;Yes, I know that volumes have been written about &lt;span class="caps"&gt;TDD&lt;/span&gt; and &lt;span class="caps"&gt;BDD&lt;/span&gt;, and that it&amp;#8217;s a large topic with many many branches of application, but I didn&amp;#8217;t have time for that. I had time for three index cards.  I figure that an index card is a token, and it represents a conversation, and that one can always dig deeper later.&lt;/p&gt;


	&lt;p&gt;They looked more or less like this:&lt;/p&gt;


&lt;hr&gt;
Card 1: Uncle Bob&amp;#8217;s Three Laws (Object Mentor)
&lt;ol&gt;
&lt;li&gt;Write no production code except to pass a failing test.&lt;/li&gt;
&lt;li&gt;Write only enough of a test to demonstrate a failure.&lt;/li&gt;
&lt;li&gt;Write only enough production code to pass the test.&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;
Card 2: &lt;span class="caps"&gt;FIRST&lt;/span&gt; Principles (Brett and Tim at Object Mentor)
&lt;ul&gt;
&lt;li&gt;&lt;i&gt;F&lt;/i&gt;ast: Mind-numbingly fast, as in hundreds or thousands per second.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;I&lt;/i&gt;solated: The test isolates a fault clearly.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;R&lt;/i&gt;epeatable: I can run it repeatedly and it will pass or fail the same way each time.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;S&lt;/i&gt;elf-verifying: The test is unambiguously pass-fail.&lt;/li&gt;
&lt;li&gt;&lt;i&gt;T&lt;/i&gt;imely: Produced in lockstep with tiny code changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;
Card 3: Flow (using the famous three-node circle diagram) &amp;#8211; origin unknown.
&lt;ul&gt;
&lt;li&gt;Red: test fails&lt;/li&gt;
&lt;li&gt;Green: test passes&lt;/li&gt;
&lt;li&gt;Refactor: clean code and tests&lt;/li&gt;
&lt;/ul&gt;

	&lt;p&gt;Sure there is plenty more, but I didn&amp;#8217;t know how I could provide significantly less. As is, I&amp;#8217;m pretty happy with the exercise. Now I am wondering if I couldn&amp;#8217;t produce most of the important information I wish to convey as a series of index cards. Would that be cool or what?&lt;/p&gt;</description>
      <pubDate>Thu, 06 Mar 2008 19:39:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:a7002e7d-5f30-481f-8792-20f01b2e731f</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2008/03/06/tdd-on-three-index-cards</link>
      <category>Tim's Tepid Torrent</category>
      <category>testing</category>
      <category>TDD</category>
      <category>three</category>
      <category>index</category>
      <category>cards</category>
      <category>reminders</category>
      <category>simplified</category>
    </item>
    <item>
      <title>Unit Testing C and C++ ... with Ruby and RSpec!</title>
      <description>&lt;p&gt;If you&amp;#8217;re writing C/C&amp;#043;&amp;#043; code, it&amp;#8217;s natural to write your unit tests in the same language (or use C&amp;#043;&amp;#043; for your C test code). All the well-known unit testing tools take this approach.&lt;/p&gt;


	&lt;p&gt;I think we can agree that neither language offers the best developer productivity among all the language choices out there. Most of us use either language because of perceived performance requirements, institutional and industry tradition, &lt;em&gt;etc.&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;There&amp;#8217;s growing interest, however, in mixing languages, tools, and &lt;em&gt;paradigms&lt;/em&gt; to get the best tool for a particular job. &amp;lt;shameless-plug&amp;gt;I&amp;#8217;m giving a talk March 7&lt;sup&gt;th&lt;/sup&gt; at &lt;a href="https://www.cmpevents.com/SDw8/a.asp?option=C&amp;#38;V=11&amp;#38;SessID=6102"&gt;SD West&lt;/a&gt; on this very topic, called &lt;a href="https://www.cmpevents.com/SDw8/a.asp?option=C&amp;#38;V=11&amp;#38;SessID=6102"&gt;Polyglot and Poly-Paradigm Programming&lt;/a&gt; &amp;lt;/shameless-plug&amp;gt;.&lt;/p&gt;


	&lt;p&gt;So, why not use a more productive language for your C or C&amp;#043;&amp;#043; unit tests? You have more freedom in your development chores than what&amp;#8217;s required for production. Why not use Ruby&amp;#8217;s &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;, a &lt;a href="http://behaviour-driven.org/"&gt;Behavior-Driven Development&lt;/a&gt; tool for acceptance and unit testing? Or, you could use Ruby&amp;#8217;s version of &lt;a href="http://www.junit.org"&gt;JUnit&lt;/a&gt;, called &lt;a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html"&gt;Test::Unit&lt;/a&gt;. The hard part is integrating Ruby and C/C&amp;#043;&amp;#043;. If you&amp;#8217;ve been looking for an excuse to bring Ruby (or Tcl or Python or Java or&amp;#8230;) into your C/C&amp;#043;&amp;#043; environment, starting with development tasks is usually the path of least resistance.&lt;/p&gt;


	&lt;p&gt;I did some experimenting over the last few days to integrate &lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt;  using &lt;a href="http://www.swig.org"&gt;&lt;span class="caps"&gt;SWIG&lt;/span&gt;&lt;/a&gt; (Simplified Wrapper and Interface Generator), a tool for bridging libraries written in C and C&amp;#043;&amp;#043; to other languages, like Ruby. The &lt;a href="http://www.swig.org/Doc1.3/Ruby.html"&gt;Ruby section&lt;/a&gt; of the &lt;span class="caps"&gt;SWIG&lt;/span&gt; manual was very helpful.&lt;/p&gt;


	&lt;h2&gt;My Proof-of-Concept Code&lt;/h2&gt;


	&lt;p&gt;Here is a zip file of my experiment: &lt;a href="http://blog.objectmentor.com/files/rspec_for_cpp.zip" title="rspec_for_cpp.zip"&gt;rspec_for_cpp.zip&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;This is far from a complete and working solution, but I think it shows promise. See the &lt;strong&gt;Current Limitations&lt;/strong&gt; section below for details.&lt;/p&gt;


	&lt;p&gt;Unzip the file into a directory. I&amp;#8217;ll assume you named it &lt;code&gt;rspec_for_cpp&lt;/code&gt;. You need to have &lt;code&gt;gmake&lt;/code&gt;, &lt;code&gt;gcc&lt;/code&gt;, &lt;span class="caps"&gt;SWIG&lt;/span&gt; and Ruby installed, along with the RSpec &amp;#8220;gem&amp;#8221;. Right now, it only builds on &lt;span class="caps"&gt;OS X&lt;/span&gt; and Linux (at least the configurations on my machines running those OS&amp;#8217;s &amp;#8211; see the discussion below). To run the build, use the following commands:&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        $ cd rspec_for_cpp/cpp
        $ make 
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;You should see it finish with the lines&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        ( cd ../spec; spec *_spec.rb )
        .........

        Finished in 0.0***** seconds

        9 examples, 0 failures
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Congratulations, you&amp;#8217;ve just tested some C and C&amp;#043;&amp;#043; code with RSpec! (Or, if you didn&amp;#8217;t succeed, see the notes in the &lt;code&gt;Makefile&lt;/code&gt; and the discussion below.)&lt;/p&gt;


	&lt;h2&gt;The Details&lt;/h2&gt;


	&lt;p&gt;I&amp;#8217;ll briefly walk you through the files in the zip and the key steps required to make it all work.&lt;/p&gt;


	&lt;h3&gt;&lt;code&gt;cexample.h&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is a simple C header file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        /* cexample.h */
        #ifndef CEXAMPLE_H
        #define CEXAMPLE_H
        #ifdef __cplusplus
         extern "C" {
        #endif
        char* returnString(char* input);
        double returnDouble(int input);
        void  doNothing();

        #ifdef __cplusplus
         }
        #endif
        #endif
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Of course, in a pure C shop, you won&amp;#8217;t need the &lt;code&gt;#ifdef __cplusplus&lt;/code&gt; stuff. I found this was essential in my experiment when I mixed C and C&amp;#043;&amp;#043;, as you might expect.&lt;/p&gt;


	&lt;h3&gt;&lt;code&gt;cpp/cexample.c&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is the corresponding C source file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        /* cexample.h */

        char* returnString(char* input) {
            return input;
        }

        double returnDouble(int input) {
            return (double) input;
        }

        void  doNothing() {}
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;&lt;code&gt;cpp/CppExample.h&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is a C&amp;#043;&amp;#043; header file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        #ifndef CPPEXAMPLE_H
        #define CPPEXAMPLE_H

        #include &amp;lt;string&amp;gt;

        class CppExample 
        {
        public:
            CppExample();
            CppExample(const CppExample&amp;#38; foo);
            CppExample(const char* title, int flag);
            virtual ~CppExample();

            const char* title() const;
            void        title(const char* title);
            int         flag() const;
            void        flag(int value);

            static int countOfCppExamples();
        private:
            std::string _title;
            int         _flag;
        };

        #endif
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;&lt;code&gt;cpp/CppExample.cpp&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Here is the corresponding C&amp;#043;&amp;#043; source file.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        #include "CppExample.h" 

        CppExample::CppExample() : _title("") {}
        CppExample::CppExample(const CppExample&amp;#38; foo): _title(foo._title) {}
        CppExample::CppExample(const char* title, int flag) : _title(title), _flag(flag) {}
        CppExample::~CppExample() {}

        const char* CppExample::title() const { return _title.c_str(); }
        void        CppExample::title(const char* name) { _title = name; }

        int  CppExample::flag() const { return _flag; }
        void CppExample::flag(int value) { _flag = value; }

        int CppExample::countOfCppExamples() { return 1; }
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;h3&gt;&lt;code&gt;cpp/example.i&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Typically in &lt;span class="caps"&gt;SWIG&lt;/span&gt;, you specify a &lt;code&gt;.i&lt;/code&gt; file to the &lt;code&gt;swig&lt;/code&gt; command to define the &lt;em&gt;module&lt;/em&gt; that wraps the classes and global functions, which classes and functions to expose to the target language (usually all in our case), and other assorted customization options, which are discussed in the &lt;a href="http://www.swig.org/Doc1.3"&gt;&lt;span class="caps"&gt;SWIG&lt;/span&gt; manual&lt;/a&gt;. I&amp;#8217;ll show the &lt;code&gt;swig&lt;/code&gt; command in a minute. For now, note that I&amp;#8217;m going to generate an &lt;code&gt;example_wrap.cpp&lt;/code&gt; file that will function as the bridge between the languages.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s my &lt;code&gt;example.i&lt;/code&gt;, where I named the module &lt;code&gt;example&lt;/code&gt;.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        %module example
        %{
            #include "cexample.h" 
            #include "CppExample.h"    
        %}
        %include "cexample.h" 
        %include "CppExample.h" 
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;It looks odd to have header files appear twice. The code inside the &lt;code&gt;%{...%}&lt;/code&gt; (with a &amp;#8217;#&amp;#8217; before each &lt;code&gt;include&lt;/code&gt;) are standard C and C&amp;#043;&amp;#043; statements, &lt;em&gt;etc.&lt;/em&gt; that will be inserted verbatim into the generated &amp;#8220;wrapper&amp;#8221; file, &lt;code&gt;example_wrap.cpp&lt;/code&gt;, so that file will compile when it references anything declared in the header files. The second case, with a &amp;#8217;%&amp;#8217; before the &lt;code&gt;include&lt;/code&gt; statements&lt;sup&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;, tells &lt;span class="caps"&gt;SWIG&lt;/span&gt; to make all the declarations in those header files available to the target language. (You can be more selective, if you prefer&amp;#8230;)&lt;/p&gt;


	&lt;p&gt;Following Ruby conventions, the Ruby plugin for &lt;span class="caps"&gt;SWIG&lt;/span&gt; automatically names the module with an upper case first letter (&lt;code&gt;Example&lt;/code&gt;), but you use &lt;code&gt;require 'example'&lt;/code&gt; to include it, as we&amp;#8217;ll see shortly.&lt;/p&gt;


	&lt;h3&gt;Building&lt;/h3&gt;


	&lt;p&gt;See the &lt;code&gt;cpp/Makefile&lt;/code&gt; for the gory details. In a nutshell, you run the &lt;code&gt;swig&lt;/code&gt; command like this.&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        swig -c++ -ruby -Wall -o example_wrap.cpp example.i
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Next, you create a dynamically-linked library, as appropriate for your platform, so the Ruby interpreter can load the module dynamically when required. The &lt;code&gt;Makefile&lt;/code&gt; can do this for Linux and &lt;span class="caps"&gt;OS X&lt;/span&gt; platforms. See the &lt;a href="http://www.swig.org/Doc1.3/Ruby.html"&gt;Ruby section&lt;/a&gt; of the &lt;span class="caps"&gt;SWIG&lt;/span&gt; manual for Windows specifics.&lt;/p&gt;


	&lt;p&gt;If you test-drive your code, which tends to drive you towards minimally-coupled &amp;#8220;modules&amp;#8221;, then you can keep your libraries and build times small, which will make the build and test cycle very fast!&lt;/p&gt;


	&lt;h3&gt;&lt;code&gt;spec/cexample_spec.rb&lt;/code&gt; and &lt;code&gt;spec/cppexample_spec.rb&lt;/code&gt;&lt;/h3&gt;


	&lt;p&gt;Finally, here are the RSpec files that exercise the C and C&amp;#043;&amp;#043; code. (Disclaimer: these aren&amp;#8217;t the best spec files I&amp;#8217;ve ever written. For one thing, they don&amp;#8217;t exercise all the &lt;code&gt;CppExample&lt;/code&gt; methods! So sue me&amp;#8230; :)&lt;/p&gt;


&lt;pre&gt;
    &lt;code&gt;
        require File.dirname(__FILE__) + '/spec_helper'
        require 'example'

        describe "Example (C functions)" do
          it "should be a constant on Module" do
            Module.constants.should include('Example')
          end
          it "should have the methods defined in the C header file" do
            Example.methods.should include('returnString')
            Example.methods.should include('returnDouble')
            Example.methods.should include('doNothing')
          end
        end

        describe Example, ".returnString" do
          it "should return the input char * string as a Ruby string unchanged" do
            Example.returnString("bar!").should == "bar!" 
          end  
        end

        describe Example, ".returnDouble" do
          it "should return the input integer as a double" do
            Example.returnDouble(10).should == 10.0
          end
        end

        describe Example, ".doNothing" do
          it "should exist, but do nothing" do
            lambda { Example.doNothing }.should_not raise_error
          end
        end
    &lt;/code&gt;
&lt;/pre&gt;

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


&lt;pre&gt;
    &lt;code&gt;
    require File.dirname(__FILE__) + '/spec_helper'
    require 'example'

    describe Example::CppExample do
      it "should be a constant on module Example" do
        Example.constants.should include('CppExample')
      end
    end

    describe Example::CppExample, ".new" do
      it "should create a new object of type CppExample" do
        example = Example::CppExample.new("example1", 1)
        example.title.should == "example1" 
        example.flag.should  == 1
      end
    end

    describe Example::CppExample, "#title(value)" do
      it "should set the title" do
        example = Example::CppExample.new("example1", 1)
        example.title("title2")
        example.title.should == "title2" 
      end
    end

    describe Example::CppExample, "#flag(value)" do
      it "should set the flag" do
        example = Example::CppExample.new("example1", 1)
        example.flag(2)
        example.flag.should == 2
      end
    end
    &lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;If you love RSpec like I do, this is a very compelling thing to see!&lt;/p&gt;


	&lt;p&gt;And now for the small print:&lt;/p&gt;


	&lt;h2&gt;Current Limitations&lt;/h2&gt;


	&lt;p&gt;As I said, this is just an experiment at this point. Volunteers to make this &lt;em&gt;battle-ready&lt;/em&gt; would be most welcome!&lt;/p&gt;


	&lt;h3&gt;General&lt;/h3&gt;


	&lt;h4&gt;The Example &lt;code&gt;Makefile&lt;/code&gt; File&lt;/h4&gt;


	&lt;p&gt;&lt;strong&gt;It Must Be Hand Edited for Each New or Renamed Source File&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;You&amp;#8217;ve probably already solved this problem for your own make files. Just merge in the example &lt;code&gt;Makefile&lt;/code&gt; to pick up the &lt;span class="caps"&gt;SWIG&lt;/span&gt;- and RSpec-related targets and rules.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;It Only Knows How to Build Shared Libraries for Mac &lt;span class="caps"&gt;OS X&lt;/span&gt; and Linux (and Not Very Well)&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Some definitions are probably unique to my &lt;span class="caps"&gt;OS X&lt;/span&gt; and Linux machines. Windows is not supported at all. However, this is also easy rectify. Start with the notes in the &lt;code&gt;Makefile&lt;/code&gt; itself.&lt;/p&gt;


	&lt;h4&gt;The &lt;code&gt;module.i&lt;/code&gt; File Must Be Hand Edited for Each File Change&lt;/h4&gt;


	&lt;p&gt;Since the format is simple, a make task could fill a template file with the changed list of source files during the build.&lt;/p&gt;


	&lt;h4&gt;Better Automation&lt;/h4&gt;


	&lt;p&gt;It should be straightforward to provide scripts, &lt;span class="caps"&gt;IDE&lt;/span&gt;/Editor shortcuts, &lt;em&gt;etc&lt;/em&gt;. that automate some of the tasks of adding new methods and classes to your C and C&amp;#043;&amp;#043; code when you introduce them  &lt;i&gt;first&lt;/i&gt; in your &amp;#8220;spec&amp;#8221; files. (The true &lt;span class="caps"&gt;TDD&lt;/span&gt; way, of course.)&lt;/p&gt;


	&lt;h3&gt;Specific Issues for C Code Testing&lt;/h3&gt;


	&lt;p&gt;I don&amp;#8217;t know of any other C-specific issues, so unit testing with Ruby is most viable today for C code. Although I haven&amp;#8217;t experimented extensively, C functions and variables are easily mapped by &lt;span class="caps"&gt;SWIG&lt;/span&gt; to a Ruby module. The &lt;a href="http://www.swig.org/Doc1.3/Ruby.html"&gt;Ruby section&lt;/a&gt; of the &lt;span class="caps"&gt;SWIG&lt;/span&gt; manual discusses this mapping in some detail.&lt;/p&gt;


	&lt;h3&gt;Specific Issues for C&amp;#043;&amp;#043; Code Testing&lt;/h3&gt;


	&lt;p&gt;More work will be required to make this viable. It&amp;#8217;s important to note that &lt;span class="caps"&gt;SWIG&lt;/span&gt; cannot handle all C&amp;#043;&amp;#043; constructs (although there are workarounds for most issues, if you&amp;#8217;re committed to this approach&amp;#8230;). For example, namespaces, nested classes, some template and some method overloading scenarios are not supported. The &lt;a href="http://www.swig.org/Doc1.3"&gt;&lt;span class="caps"&gt;SWIG&lt;/span&gt; manual&lt;/a&gt; has details.&lt;/p&gt;


	&lt;p&gt;Also, during my experiment, &lt;span class="caps"&gt;SWIG&lt;/span&gt; didn&amp;#8217;t seem to map &lt;code&gt;const std::string&amp;#38;&lt;/code&gt; objects in C&amp;#043;&amp;#043; method signatures to Ruby strings, as I would have expected (&lt;code&gt;char*&lt;/code&gt; worked fine).&lt;/p&gt;


	&lt;h2&gt;Is It a Viable Approach?&lt;/h2&gt;


	&lt;p&gt;Once the &lt;strong&gt;General&lt;/strong&gt; issues listed above are handled, I think this approach would work very well for C code. For C&amp;#043;&amp;#043; code, there are more issues that need to be addressed, and programmers who are committed to this strategy will need to tolerate some issues (or just use C&amp;#043;&amp;#043;-language tools for some scenarios).&lt;/p&gt;


	&lt;h2&gt;Conclusions: Making It Development-Team Ready&lt;/h2&gt;


	&lt;p&gt;I&amp;#8217;d like to see this approach pushed to its logical limit. I think it has the potential to really improve the productivity of C and C&amp;#043;&amp;#043; developers and the quality of their test coverage, by leveraging the productivity and power of dynamically-typed languages like Ruby. If you prefer, you could use Tcl, Python, even Java instead.&lt;/p&gt;


	&lt;h3&gt;License&lt;/h3&gt;


	&lt;p&gt;This code is complete open and free to use. Of course, use it at your own risk; I offer it without warranty, &lt;em&gt;etc.&lt;/em&gt;, &lt;em&gt;etc&lt;/em&gt;. When I polish it to the point of making it an &amp;#8220;official&amp;#8221; project, I will probably release under the Apache license.&lt;/p&gt;


	&lt;p id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; I spent a lot of time debugging problems because I had a &amp;#8217;#&amp;#8217; where I should have had a &amp;#8217;%&amp;#8217;! &lt;em&gt;Caveat emptor&lt;/em&gt;!&lt;/p&gt;</description>
      <pubDate>Mon, 04 Feb 2008 22:08:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:cba4dc23-cbce-4173-be6f-14c7847dcfea</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2008/02/04/unit-testing-c-and-c-with-ruby-and-rspec</link>
      <category>Embedded</category>
      <category>Dean's Deprecations</category>
      <category>Dynamic Languages</category>
      <category>Agile Methods</category>
      <category>c</category>
      <category>RSpec</category>
      <category>Ruby</category>
      <category>TDD</category>
      <category>testing</category>
    </item>
    <item>
      <title>So just what does synchronized do?</title>
      <description>&lt;p&gt;&lt;b&gt;Synopsis&lt;/b&gt;
&lt;Blockquote&gt;Using synchronized turns a huge state space into a comparatively small one.
&lt;/blockquote&gt;
&lt;p&gt;Normally, the light from a star radiates out in all directions. But what happens when a star collapses? There are several possibilities depending on the mass of the star. Our sun will turn into a red giant and then later turn into a white dwarf, giving out light from its accumulated heat for many years after living on Earth has become unbearable; mostly because of all the traffic.&lt;/p&gt;&lt;/p&gt;


&lt;p&gt;If the mass of the star is around 10x our star, its destiny is just a bit different. It will begin to collapse. Along the way, it will probably have some temporary reprieves from its ultimate fate, to become a Neutron star, by consuming other heavier elements such as carbon and helium . However, the writing is on the wall. The center of star, already an extreme environment, becomes even more so; eventually, the pressure from the collapsing of material into the center of the star results in a massive explosion known as a nova or super nova &amp;#8211; depending on the mass of the star. What is left is a neutron star. A neutron star is the heart of a pulsar, able to spin at amazing rates without pulling itself apart.&lt;/p&gt;

&lt;P&gt;Another option is a black hole. A black hole is an often used metaphor for either the effort expended on support/fixing/updating a big ball of mud or what the development effort appears to be in most of the time. Either way, it is not considered a good thing if you&amp;#8217;re anywhere in the vicinity.&lt;/P&gt;

&lt;p&gt;I&amp;#8217;m a pessimist by nature. I see a project in decline, sucking in other resources, like a black holes eating neighboring galaxies, snuffing the light out of stars, just like projects can suck the life force out of individuals.&lt;/P&gt;

&lt;P&gt;However, energy can escape from a black hole, eventually leading to the demise of the black hole. Energy can escape along the axis of rotation in either direction. In a sense, if we see the expansion of the black hole as a bad thing, anything that diminishes a black hole is a good thing. Stephen Hawking theorized that at the event horizon of black holes, fluctuations in the space can cause the spontaneous creations of pairs of particles and their anti particles. This is another way it can appear that a black hole is losing energy since it gives off particles while the opposite particle goes into the black hole.&lt;/P&gt;

	&lt;p&gt;Now I&amp;#8217;m off track. I wanted to talk about how synchronized give a similar effect as the massive gravity of black hole. But instead of curving space-time, they invert the possible state space of code in the presence of threads. Let&amp;#8217;s take a look.&lt;/p&gt;


Here&amp;#8217;s a simple class:
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
public class X {
   int value;

   public synchronized void incrementValue() {
        ++value;
    }
}&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;
Let&amp;#8217;s say, for the sake of argument, two threads are trying to execute the single method in this class. If the method is written like this:
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
   public synchronized void incrementValue() {
        ++value;
    }
&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;
&lt;P&gt;Then there are only two orderings, Thread 1/Thread 2, or Thread 2/Thread 1. All of those paragraphs at the top were to make this analogy.&lt;/p&gt;

&lt;P&gt;OK, so if we use synchronized that that&amp;#8217;s the black hole. The number of possible paths through the code for N threads is N!. What&amp;#8217;s the opposite? What happens if we take off the keyword and then run two threads through it? In how many ways can that single line of code get executed?&lt;/P&gt;

	&lt;p&gt;Are you ready for it?&lt;/p&gt;


&lt;B&gt;&lt;Blockquote&gt;3,432 different ways&lt;/blockquote&gt;&lt;/B&gt;

	&lt;p&gt;Really? Well at least conceptually. In practice, the Just In Time compiler will probably turn the &lt;span class="caps"&gt;JVM&lt;/span&gt; instructions into native code, so the actual number of individual steps will probably be less. But there really are that many paths through the system. You might ask how?&lt;/p&gt;


	&lt;p&gt;That single line of code is represented in byte code as 7 lines. I could show you the disassembly, but really, it&amp;#8217;s 7. You can convince yourself by having a look at the byte-code using a nice &lt;a href="http://download.forge.objectweb.org/eclipse-update/"&gt; byte-code viewer&lt;/a&gt; plug-in for eclipse.&lt;/p&gt;


	&lt;p&gt;What happens if we change the int to a long? We still have 7 lines of byte-code, but with different instructions. We have a total of 4 long reads/writes. Each long read/write requires two individual 32-bit operations &amp;#8211; or at lest the &lt;span class="caps"&gt;JVM&lt;/span&gt; can implement it that way. The actual number of atomic operations after the Just In Time compiler has had its way with your byte-code will probably be less, but if we stick to byte-codes and the Java memory model, the number 3,432 is now a whopping 705,432!&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s extend that just a bit more. What if you have several lines of code? Each line of Java results in many more lines of byte-code. What if we have have 3 lies of Java? We probably have something like 21 lines of byte-code. How many paths of execution would 21 lines of byte-code executed by two threads have? 538,257,874,440!&lt;/p&gt;


	&lt;p&gt;Where the first program ended up being a white dwarf, the version using longs was a nova. I&amp;#8217;m not sure what to call the thee line Java method, maybe a hyper-nova?&lt;/p&gt;


	&lt;p&gt;In practice, the actual number of paths through a method will end up being smaller. And, most of the paths do not have any negative side-effects. The problem, however, is that there are a small number of hard to find paths of execution that do cause problems and finding them is like looking for a needle in a haystack.&lt;/p&gt;


	&lt;p&gt;Remember what adding the keyword synchronized did? If we use it on a three line method, it turns 538,257,874,440 into 2. It collapses the number of paths into 2 for two threads. And 2 is less than 538,257,874,440, for even vary large values of 2.&lt;/p&gt;


	&lt;p&gt;How did I derive at these magic numbers? Two ways.&lt;/p&gt;


	&lt;p&gt;I wanted to know how many possible orderings there were for 7 instructions and two threads. I knew it had to do with combinations and permutations but I just wasn&amp;#8217;t smart enough to figure it out. Searching on Google didn&amp;#8217;t do much for me either. So I decided to write a program to numerically derive the result. I tested my way into a program that would calculate the result.&lt;/p&gt;


The basic algorithm is:
&lt;ol&gt;
&lt;li&gt;Determine all possible orderings of each of the unique &amp;#8220;nodes&amp;#8221; in a system. For example, if I have 2 threads and 2 instructions, I can generate a natural key (ugh!) to represent each of the different combinations of threads and instructions: &lt;span class="caps"&gt;T1S1 T1S2 T2S1 2S2&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;Produce all valid permutations of these four &amp;#8220;nodes&amp;#8221;.&lt;/li&gt;
&lt;li&gt;Remove any that have invalid orderings.&lt;/li&gt;
&lt;li&gt;Count the results.&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;Many of my first implementations for some of these steps were exercises in writing really inefficient code! But having those tests made it really easy to swap out better algorithms when my brain caught up with what I was doing.&lt;/p&gt;


	&lt;p&gt;What is an invalid ordering? The code generated by the single line using the pre increment operator has 7 steps. Those 7 steps are in a single sequence with no looping and no conditionals. That&amp;#8217;s like saying A is always before B. So if we generate a list of orderings that end up including that combination, we&amp;#8217;ve generated an ordering that cannot happen.&lt;/p&gt;


So you can describe your possible state space in a few steps:
&lt;ol&gt;
&lt;li&gt;Register a node for each thread, step combination. 7 threads, 4 steps = 28 nodes.&lt;/li&gt;
&lt;li&gt;Register dependences between steps. For example, if I have seven steps and two threads executing the same sequence, I could describe this as: &lt;span class="caps"&gt;T1S1&lt;/span&gt; -&amp;gt; &lt;span class="caps"&gt;T1S2&lt;/span&gt; -&amp;gt; &lt;span class="caps"&gt;T1S3&lt;/span&gt;, etc. And for the second thread: &lt;span class="caps"&gt;T2S1&lt;/span&gt; -&amp;gt; &lt;span class="caps"&gt;T2S2&lt;/span&gt; -&amp;gt; T2&amp;gt;S3. Since the name is arbitrary, I just used letters, so in fact I had: a -&amp;gt; b -&amp;gt; c -&amp;gt; d -&amp;gt; e -&amp;gt; f -&amp;gt; g for one set of dependencies and h -&amp;gt; i -&amp;gt; j -&amp;gt; k -&amp;gt; l -&amp;gt; m -&amp;gt; o
&lt;/ol&gt;
&lt;p&gt;In fact, here&amp;#8217;s the test I used to describe that exact space:&lt;/P&gt;
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
    @Test
    public void twoThreadsAndSevenSteps() {
        calculator = new PathCalculator(14);
        createLine('a', 'b', 'c', 'd', 'e', 'f', 'g');
        createLine('h', 'i', 'j', 'k', 'l', 'm', 'n');
        start();
        int totalPaths = calculator.totalPaths();
        stop(2, 4, totalPaths);
    }
&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;

&lt;P&gt;By the time I got to this point, I wrote some &amp;#8220;tests&amp;#8221; using JUnit as a harness to run my code and display timing information and a summary of the &lt;results. The output looked like this.&lt;/p&gt;
&lt;FONT style="line-height:95%"&gt;&lt;code&gt;&lt;pre&gt;
Time:        4ms -- Threads:  3, Opcodes:  2, Total paths:      90
Time:        1ms -- Threads:  2, Opcodes:  3, Total paths:      20
Time:       54ms -- Threads:  4, Opcodes:  2, Total paths:    2520
Time:        3ms -- Threads:  2, Opcodes:  4, Total paths:      70
Time:       61ms -- Threads:  2, Opcodes:  5, Total paths:     252
Time:     1248ms -- Threads:  2, Opcodes:  6, Total paths:     924
Time:    12819ms -- Threads: 10, Opcodes:  1, Total paths: 3628800
&lt;/pre&gt;&lt;/code&gt;&lt;/FONT&gt;

I then used this information to fit a cure to my data and derive a formula for various combinations. For 2 threads, I came up with the following formula. If you let N be the number of steps:
&lt;blockquote&gt;Total Paths = 252 * 3.6667 &lt;sup&gt;N-5&lt;/sup&gt; &lt;/blockquote&gt;

&lt;P&gt;The morning after, Uncle Bob sent an email, showing me his work on how he calculated.&lt;/P&gt;

If you let:
&lt;ol&gt;
&lt;li&gt;T be the number of threads&lt;/li&gt;
&lt;li&gt;N be the number of steps&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;Total = (N*T)! &amp;nbsp; / &amp;nbsp; N! &lt;sup&gt;T&lt;/sup&gt;&lt;/blockquote&gt;

	&lt;p&gt;When I plugged numbers into his formula, they fit my formula. His formula generated an exact result as opposed to my estimate based on fitting a curve. Another thing his solution has going for it is the algorithm I came up with, I believe, is NP-complete. The net effect was I that while I was able to calculate result for 2 threads and 6 steps, 2 threads and 7 steps took a long time before running out of memory with a 2GB heap space. Bob&amp;#8217;s formula gave me a so-called verifier (as did my formula &amp;#8211; only Bob&amp;#8217;s was better) and the algorithm seems to grow based on factorials and not polynomials.&lt;/p&gt;


&lt;p&gt;What&amp;#8217;s the point of all of this? The single, one-line program, is a demonstration of why going from one thread to two threads makes writing/debugging/testing programs so much harder. It also numerically demonstrates &lt;b&gt;why&lt;/b&gt; the single responsibility principle is even more important when we start writing concurrent programs. The more you put in one place, the large the state space. Larger state spaces:
&lt;ol&gt;
&lt;li&gt;Make it harder to find that one or few number of paths that can cause your program to die, under load, in production, while you are on vacation&lt;/li&gt;
&lt;li&gt;Make your efforts to test (which is a sampling technique anyway) for concurrency issues all the more difficult&lt;/li&gt;
&lt;li&gt;Make it harder to find what might actually have caused a failure once you&amp;#8217;ve notice it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In a later post, I&amp;#8217;ll describe how we can improve our chances of covering this huge space of potential orderings.&lt;/P&gt;

&lt;p&gt;If you&amp;#8217;ve made it this far, wow! Congratulations!&lt;/P&gt;</description>
      <pubDate>Thu, 03 Jan 2008 21:27:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:5b8ba16d-124b-4957-a36a-eb8359b589c0</guid>
      <author>Brett Schuchert</author>
      <link>http://blog.objectmentor.com/articles/2008/01/03/so-just-what-does-synchronized-do</link>
      <category>Schuchert's Scattered Synapses </category>
      <category>threading</category>
      <category>concurrency</category>
      <category>testing</category>
      <category>NP</category>
      <category>complete</category>
    </item>
    <item>
      <title>&amp;quot;Big Balls of Mud&amp;quot; and Shanty Towns</title>
      <description>&lt;p&gt;Last Thursday, the last day of &lt;span class="caps"&gt;OOPSLA 2007&lt;/span&gt;, Brian Foote gave a restrospective of &lt;a href="http://www.laputan.org/mud/"&gt;Big Ball of Mud&lt;/a&gt;, which he and Joseph Yoder presented at the Fourth Conference on Patterns Languages of Programs (PLoP &amp;#8216;97/EuroPLoP &amp;#8216;97) and which was published as a paper in 1999.&lt;/p&gt;


	&lt;p&gt;Foote and Yoder argue that the dominant architecture of deployed application is a &lt;em&gt;Big Ball of Mud&lt;/em&gt;, which they define thusly:&lt;/p&gt;


	&lt;p&gt;&lt;cite&gt;A Big Ball of Mud is a haphazardly structured, sprawling, sloppy, duct-tape-and-baling-wire, spaghetti-code jungle. These systems show unmistakable signs of unregulated growth, and repeated, expedient repair. Information is shared promiscuously among distant elements of the system, often to the point where nearly all the important information becomes global or duplicated. The overall structure of the system may never have been well defined. If it was, it may have eroded beyond recognition. Programmers with a shred of architectural sensibility shun these quagmires. Only those who are unconcerned about architecture, and, perhaps, are comfortable with the inertia of the day-to-day chore of patching the holes in these failing dikes, are content to work on such systems.
&lt;/cite&gt;&lt;/p&gt;


	&lt;p&gt;I had to leave mid-way through the talk to catch a plane, but before I left, he said something that caught my attention. He compared such applications to shanty towns, those &lt;i&gt;ad hoc&lt;/i&gt; communities that spring up with no planning, no infrastructure, and reflect the bare minimum of resources and expertise available to their builders and inhabitants.&lt;/p&gt;


	&lt;p&gt;However, as I looked at his picture of a typical shanty town, I noticed that there are paths through the maze of &lt;i&gt;ad hoc&lt;/i&gt; homes. There is &lt;i&gt;some&lt;/i&gt; structure there. Then it occurred to me that, for all their problems, &lt;em&gt;there is one interesting difference between typical shanty towns and many software applications; shanty towns are subject to frequent &amp;#8220;testing&amp;#8221; and &amp;#8220;refactoring&amp;#8221;.&lt;/em&gt; Within the extreme limitations of their architectures and the available resources, the inhabitants do what they can to fix &amp;#8220;bugs&amp;#8221; and adapt to new &amp;#8220;requirements&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Of course, I&amp;#8217;m not saying that shanty towns are good. I&amp;#8217;m just pointing out that they have a feedback loop that leads to modest improvements. In contrast, although we application developers have more resources at our disposal, we don&amp;#8217;t subject our applications to the same scrutiny.&lt;/p&gt;


	&lt;p&gt;Why is this? A big part of the problem is that we forget just how complex software really is. How many points of variation exist within a home and its community? How many points of variation exist within a software application? Perhaps more than one per line of (uncommented) code?&lt;/p&gt;


	&lt;p&gt;We interact with the points of variation in our homes on a regular basis, directly or indirectly, and we make adjustments as needed (unless we&amp;#8217;re lazy ;). In contrast, most of the corresponding points in software applications are deeply hidden and not evident when we use the applications.&lt;/p&gt;


	&lt;p&gt;You know where this is going; automated testing is the only way to subject the points of variation in applications to the same level of scrutiny and to find what needs fixing.&lt;/p&gt;</description>
      <pubDate>Sat, 27 Oct 2007 09:21:23 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:d15d6dd3-7222-49d4-8ee4-fdb127317696</guid>
      <author>Dean Wampler</author>
      <link>http://blog.objectmentor.com/articles/2007/10/27/big-balls-of-mud-and-shanty-towns</link>
      <category>design</category>
      <category>architecture</category>
      <category>testing</category>
    </item>
    <item>
      <title>Not A Task, But An Approach</title>
      <description>&lt;p&gt;Transitions are tough. It seems that lately I&amp;#8217;ve been getting a lot of contact from frustrated people who don&amp;#8217;t really have a good handle on the &amp;#8220;drive&amp;#8221; part of Test Driven Development.  A question heard frequently is: &amp;#8220;I&amp;#8217;ve almost completed the coding, can you help me write the &lt;span class="caps"&gt;TDD&lt;/span&gt;?&amp;#8221;&lt;/p&gt;


	&lt;p&gt;It seems like Test Driven Development is taken backward, that the &lt;em&gt;developers&lt;/em&gt; are &lt;em&gt;driven&lt;/em&gt; to write &lt;em&gt;tests&lt;/em&gt;.  The practitioner winces, realizing that he again faces The Great Misunderstanding of &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;&lt;span class="caps"&gt;TDD&lt;/span&gt; stands for Test-Driven Development, which is not as clear as &lt;span class="caps"&gt;TFD&lt;/span&gt; (Test-First Development). If the consultant would strive to always say the word &amp;#8220;first&amp;#8221; in association with testing, most people would more surely grasp the idea.  In fact, I&amp;#8217;ve begun an experiment in which I will not say the word &amp;#8220;test&amp;#8221; without the word &amp;#8220;first&amp;#8221; in close approximation. I&amp;#8217;ll let you know how that works out for me.&lt;/p&gt;


	&lt;p&gt;If the tests are providing nothing more than reassurance on the tail end of a coding phase, then the tests aren&amp;#8217;t driving the development.  They are like &lt;em&gt;riders&lt;/em&gt; instead of &lt;em&gt;drivers&lt;/em&gt;.  Test-Ridden Development (TRD)[1] would be a better term for such a plan. Even though it is better to have those tail-end tests than to have no automated testing, it misses the point and could not be reasonably be called &lt;span class="caps"&gt;TDD&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;An old mantra for &lt;span class="caps"&gt;TDD&lt;/span&gt; and &lt;span class="caps"&gt;BDD&lt;/span&gt; is &amp;#8220;it&amp;#8217;s not about testing&amp;#8221;. The term &lt;span class="caps"&gt;BDD&lt;/span&gt; was invented largely to get the idea of &amp;#8220;testing&amp;#8221; out of the way.  People tend to associate &amp;#8220;test&amp;#8221; as a release-preparation activity rather than an active approach to programming. &lt;span class="caps"&gt;BDD&lt;/span&gt; alleviates some of that cognitive dissonance.&lt;/p&gt;


	&lt;p&gt;In &lt;span class="caps"&gt;TDD&lt;/span&gt;, tests come first. Each unit test is written as it is needed by the programmer.  Tests are just-in-time and are active in shaping the code. Acceptance Tests likewise tend to precede programming by some short span of time.  [2]&lt;/p&gt;


Through months of repetition I have developed the mantra:
&lt;blockquote&gt;
&lt;span class="caps"&gt;TDD&lt;/span&gt; isn&amp;#8217;t a task. It is not something you do.  It is an approach.  It is how you write your programs.
&lt;/blockquote&gt;

	&lt;p&gt;I wonder if we shouldn&amp;#8217;t resurrect the term Test-First Programming or Test-First Development for simple evocative power. Admittedly there are some who would see that as a phase ordering, but maybe enough people would get the right idea.&lt;/p&gt;


	&lt;p&gt;Brett Schuchert(with some trivial aid from your humble blogger) has worked up an acronym to help socialize the basic concepts which are somehow being lost in translation to the corporate workplace.&lt;/p&gt;


	&lt;p&gt;The teaser:
    Fast, Isolated, Repeatable, Self-validating, and Timely.&lt;/p&gt;


	&lt;p&gt;As a reader of this blog, you are probably very familiar with all of the terminology and concepts behind &lt;span class="caps"&gt;TDD&lt;/span&gt;. I beg of you, socialize the idea that testing comes first and drives the shape of the code.  If we can just get this one simple idea spread into programming dens across our small spheres of influence, then we will have won a very great victory over Test-Ridden Development.&lt;/p&gt;


	&lt;p&gt;&amp;#8220;And there was much rejoicing.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;&lt;small&gt;
1 Jeff Langr will refer to this &lt;span class="caps"&gt;TRD&lt;/span&gt; concept as &amp;#8220;Test-After-Development&amp;#8221;, which he follows with a chuckle and a twinkle, &amp;#8220;which is a &lt;span class="caps"&gt;TAD&lt;/span&gt; too late.&amp;#8221;&lt;/p&gt;


	&lt;p&gt;2 Of course, one still needs QC testing as well, however &lt;span class="caps"&gt;TDD&lt;/span&gt; is about driving development, not testing its quality post-facto.
&lt;/small&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 02 Aug 2007 22:14:00 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:bd848598-96fa-4e15-84e8-ccba83ab4325</guid>
      <author>Tim Ottinger</author>
      <link>http://blog.objectmentor.com/articles/2007/08/02/not-a-task-but-an-approach</link>
      <category>Tim's Tepid Torrent</category>
      <category>FIRST</category>
      <category>testing</category>
      <category>mentoring</category>
      <category>TDD</category>
      <category>TRD</category>
      <category>TAD</category>
      <category>Fast</category>
      <category>Isolated</category>
      <category>Repeatable</category>
      <category>Self</category>
      <category>validating</category>
      <category>Timely</category>
    </item>
  </channel>
</rss>
