<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gooli.org &#187; Testuff</title>
	<atom:link href="http://www.gooli.org/blog/category/testuff/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gooli.org/blog</link>
	<description>on software development and related issues</description>
	<lastBuildDate>Tue, 31 Mar 2009 03:36:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Unicode and permalinks</title>
		<link>http://www.gooli.org/blog/unicode-and-permalinks/</link>
		<comments>http://www.gooli.org/blog/unicode-and-permalinks/#comments</comments>
		<pubDate>Mon, 22 Sep 2008 08:11:38 +0000</pubDate>
		<dc:creator>gooli</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Testuff]]></category>

		<guid isPermaLink="false">http://www.gooli.org/blog/?p=155</guid>
		<description><![CDATA[Working on integrating of automation scripts with Testuff, I&#8217;ve encountered an interesting Unicode-related issue I&#8217;d like to share.
The integration allows for an automated testing script to report the results of its run to the Testuff server. In order for the results to be grouped, displayed and summarized correctly, the automation script needs to tell the [...]]]></description>
			<content:encoded><![CDATA[<p>Working on integrating of automation scripts with <a href="http://www.testuff.com/">Testuff</a>, I&#8217;ve encountered an interesting Unicode-related issue I&#8217;d like to share.</p>
<p>The integration allows for an automated testing script to report the results of its run to the Testuff server. In order for the results to be grouped, displayed and summarized correctly, the automation script needs to tell the server which test it ran, and whether the test has passed or failed. A long discussion emerged on what the best way to uniquely identify tests.</p>
<p>After quite a bit of back and forth, we&#8217;ve settled on <a href="http://en.wikipedia.org/wiki/Permalink">permalinks</a>, those more-or-less-readable URLs that are in common use in blogs. The idea of a permalink is to take the title (of a blog post or a test) and replace any characters that aren&#8217;t numbers or letters with an underscore or a hyphen. Using this simple scheme, &#8220;Unicode and permalinks&#8221; becomes &#8220;unicode-and-permalinks&#8221;, which is quite suitable for use in a URL.</p>
<p>The implementation is a simple regular expression:</p>
<div class="ch_code_container" style="font-family: monospace;height:100%;"><span style="color: #ff7700;font-weight:bold;">def</span> to_permalink<span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;[^a-zA-Z0-9]+&quot;</span>, <span style="color: #483d8b;">&quot;_&quot;</span>, <span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span>.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div>
<p>While this code works perfectly for the English language, it doesn&#8217;t work at all if <em>string</em> is a Unicode string containing something in Hebrew, Russian or Polish &#8211; language that some of our customers use. And so, I set out to write code that will essentially behave like the regular expression above, but will work for letters and numbers in all the languages of the world.</p>
<p>Fortunately the Unicode standard includes a rarely used classification of characters into various categories. For each given character we can find out whether it is an uppercase letter, a lowercase letter, and number, a punctuation mark and so on. Surprisingly, Python includes a module called <a href="http://docs.python.org/lib/module-unicodedata.html">unicodedata</a> that contains all that information. The function <em>category</em> accepts a character and returns a string that tells us <a href="http://www.unicode.org/Public/4.1.0/ucd/UCD.html#General_Category_Values">what the character is</a>: &#8220;Lu&#8221; denotes an uppercase letter, &#8220;Nd&#8221; denotes a decimal digit, etc.</p>
<p>All that remains to be done is go over the characters in the title, keep the letters and numbers, and replace all the other characters with a dash or an underscore. The regular expression at the end replaces any sequence of underscores into a single underscore to make the resulting URLs even nicer to look at.</p>
<div class="ch_code_container" style="font-family: monospace;height:100%;"><span style="color: #ff7700;font-weight:bold;">def</span> to_permalink<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;&quot;</span><span style="color: #483d8b;">&quot;<br />
&nbsp; &nbsp; Converts sequences of characters that aren&#8217;t letters or numbers<br />
&nbsp; &nbsp; to a single underscore to achieve wikpedia like unicode URLs.<br />
&nbsp; &nbsp; &quot;</span><span style="color: #483d8b;">&quot;&quot;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">unicodedata</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> conv<span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #dc143c;">unicodedata</span>.<span style="color: black;">category</span><span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;L&quot;</span>, <span style="color: #483d8b;">&quot;N&quot;</span><span style="color: black;">&#93;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> c<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;_&quot;</span><br />
&nbsp; &nbsp; s2 = <span style="color: #483d8b;">&quot;&quot;</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#91;</span>conv<span style="color: black;">&#40;</span>c<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> c <span style="color: #ff7700;font-weight:bold;">in</span> s<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;_+&quot;</span>, <span style="color: #483d8b;">&quot;_&quot;</span>, s2<span style="color: black;">&#41;</span></div>
<p><em>[Update]</em> Or, as Almad correctly pointed out, you could just use the <em>re</em> module support for Unicode and be done with it in two lines, which kind of takes the air out of this post.</p>
<div class="ch_code_container" style="font-family: monospace;height:100%;"><span style="color: #ff7700;font-weight:bold;">def</span> to_permalink<span style="color: black;">&#40;</span>s<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">re</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;<span style="color: #000099; font-weight: bold;">\W</span>+&quot;</span>, <span style="color: #dc143c;">re</span>.<span style="color: black;">UNICODE</span><span style="color: black;">&#41;</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;_&quot;</span>, s<span style="color: black;">&#41;</span></div>
<p>There&#8217;s one other thing to consider when dealing with Unicode permalinks. If you&#8217;re a native speaker of a language other than English, you&#8217;ve probably seen URLs that in your own language in Wikipedia.</p>
<p><a href="http://gooli.org/blog/wp-content/uploads/2008/09/hebrew-url.png"><img class="alignnone size-medium wp-image-156" title="hebrew-url" src="http://gooli.org/blog/wp-content/uploads/2008/09/hebrew-url-300x23.png" alt="" width="300" height="23" /></a></p>
<p><a href="http://gooli.org/blog/wp-content/uploads/2008/09/russian-url.png"><img class="alignnone size-medium wp-image-157" title="russian-url" src="http://gooli.org/blog/wp-content/uploads/2008/09/russian-url-300x23.png" alt="" width="300" height="23" /></a></p>
<p>From the looks of it, URLs can include characters in any language. Right?</p>
<p>Wrong.</p>
<p><a href="http://tools.ietf.org/html/rfc3986">RFC3986</a> defines the syntax for URLs (actually URIs, but that&#8217;s a moot point) explicitly and states which characters are allowed in a URL. This includes <a href="http://en.wikipedia.org/wiki/Percent-encoding#Percent-encoding_in_a_URI">little more than English letters and numbers</a> from the lower half of the <a href="http://www.asciitable.com/">ASCII chart</a>.</p>
<p>If you look at the headers your browser passes when you access such a URL, you&#8217;ll see that it encodes all the characters with percent encoding, so neither the browser nor the web server is violating the standard. This is what the server saw when I navigated to the main Hebrew page of Wikipedia:</p>
<pre>GET /wiki/%D7%A2%D7%9E%D7%95%D7%93_%D7%A8%D7%90%D7%A9%D7%99 HTTP/1.1
Host: he.wikipedia.org</pre>
<p>In order to understand what this percent encoding means, you need to know a <a href="http://www.joelonsoftware.com/articles/Unicode.html">bit about Unicode</a>. Basically, the Unicode URL is encoded in UTF8 and each byte of the UTF8-encoded string is encoded using percent encoding. The browser apparently recognized this specific encoding scheme (which isn&#8217;t documented anywhere I could fine) and displays nice internationalized URLs for the user.</p>
<p>If you want to support such URLs in your server, you&#8217;ll probably need to write some code to translate the percent-encoded URLs into their actual Unicode representation.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.gooli.org/blog/unicode-and-permalinks/&amp;title=Unicode+and+permalinks" title="Add 'Unicode and permalinks' to Del.icio.us"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Unicode and permalinks' to Del.icio.us" alt="Add 'Unicode and permalinks' to Del.icio.us" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.gooli.org/blog/unicode-and-permalinks/&amp;title=Unicode+and+permalinks" title="Add 'Unicode and permalinks' to digg"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Unicode and permalinks' to digg" alt="Add 'Unicode and permalinks' to digg" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.gooli.org/blog/unicode-and-permalinks/" title="Add 'Unicode and permalinks' to Technorati"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Unicode and permalinks' to Technorati" alt="Add 'Unicode and permalinks' to Technorati" /></a>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.gooli.org/blog/unicode-and-permalinks/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Digging into Python&#8217;s PYC files</title>
		<link>http://www.gooli.org/blog/digging-into-pythons-pyc-files/</link>
		<comments>http://www.gooli.org/blog/digging-into-pythons-pyc-files/#comments</comments>
		<pubDate>Fri, 25 Jan 2008 12:20:23 +0000</pubDate>
		<dc:creator>gooli</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Testuff]]></category>

		<guid isPermaLink="false">http://www.gooli.org/blog/digging-into-pythons-pyc-files/</guid>
		<description><![CDATA[One of the first things we needed to do when we started working on Testuff, was to figure out how are we going to update the installed desktop clients. This is one of those problems that seems to usually fall under the NIH syndrome, and like many others before me, I invented my own scheme. [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first things we needed to do when we started working on <a href="http://www.testuff.com">Testuff</a>, was to figure out how are we going to update the installed desktop clients. This is one of those problems that seems to usually fall under the <a href="http://en.wikipedia.org/wiki/Not_Invented_Here">NIH</a> syndrome, and like many others before me, I invented my own scheme. The gist of it is a <a href="http://download.testuff.com/release/version.xml">version.xml</a> file that sits alongside the setup file for the newest release and looks something like this:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;update-info version="0.8.0[1212]"&gt;
    &lt;update file="TestuffSetup.exe" from-version="all"/&gt;
    &lt;update file="TestuffUpdate.exe" from-version="0.7.1[1110]"/&gt;
    &lt;md5hashes&gt;
        &lt;file md5="3a23dd6eff6fd6c1d0fbfcbfb0d57221" path="async.pyc"/&gt;
        &lt;file md5="0d1ea490a18c65cec7ba8715b5ea9e69" path="atexit.pyc"/&gt;
        &lt;file md5="166723a4330a98b573119326fc689322" path="base64.pyc"/&gt;
        &lt;file md5="01c1bda049936de570ed922424c057a8" path="BeautifulSoup.pyc"/&gt;
    &lt;/md5hashes&gt;
&lt;/update-info&gt;</pre>
<p>When the Testuff client launches, it gets the version.xml file from the server and compares its version to the version attribute of the <em>update-info</em> tag. If the client&#8217;s version is wrong, it checks the <em>update</em> tags to see which update it should download and install. We generate two separate setup files &#8211; one to update the most recent version to the new one called and another to update all the other (older) versions.</p>
<p>Aside from the info about which version of the client should use which update file, version.xml also contains the MD5 hashes for each file in the distribution. That might seem like a lot of wasted space and time, but it&#8217;s actually there for a very good reason. When our setup building script is creating <em>TestuffUpdate.exe</em>, it too downloads version.xml from our server. It then tries to determine which files have changed or have been added since the last version by comparing the MD5 hashes in version.xml to the the hashes of the actual files that have been generated by the build. Any file that is different is added to the update so we can be sure we haven&#8217;t missed any essential component in the update.</p>
<p>Recently I discovered that our update files are much larger than they should be. We release a new version with just a couple of fixes in a single module, and the size of the update is half the size of the full install. As it turned out, that most of the PYC files were marked as changed and added to the update. That didn&#8217;t seem right, especially for things like threading.pyc, which is a Python module that shouldn&#8217;t change unless you upgrade to a different version of Python, which we didn&#8217;t (still stuck at 2.4.4 I&#8217;m afraid). That got me curious enough to go digging in the, apparently undocumented, binary structure of the PYC files.</p>
<blockquote><p>This module contains functions that can read and write Python values in a binary  format. The format is specific to Python, but independent of machine  architecture issues (e.g., you can write a Python value to a file on a PC,  transport the file to a Sun, and read it back there). <strong>Details of the format are  undocumented on purpose</strong>; it may change between Python versions (although it  rarely does).</p></blockquote>
<p>The first thing I did was compare the two threading.pyc files &#8211; the one from the current distribution and the one just generated by the build script. The result showed there was difference in only two bytes:</p>
<pre>D:GooliDevTempcompare&gt;fc /b threading-old.pyc threading-new.pyc
Comparing files threading-old.pyc and threading-new.pyc
00000004: 6E CE
00000005: F7 6A</pre>
<p>Only two bytes differ, and they are right at the beginning of the file? That looks suspiciously like a version or a timestamp in the file header. Since the PYC file structure is undocumented, I went looking for the details in Python&#8217;s source code, but the answer was actually closer to home &#8211; in the <a href="http://docs.python.org/lib/compiler.html">compiler</a> package. A file called pycodegen.py in Python\Lib\compiler contains the following code:</p>
<div class="ch_code_container" style="font-family: monospace;height:100%;"><span style="color: #ff7700;font-weight:bold;">def</span> getPycHeader<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; mtime = <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span>.<span style="color: black;">getmtime</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">filename</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; mtime = <span style="color: #dc143c;">struct</span>.<span style="color: black;">pack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&#8216;&amp;lt;i&#8217;</span>, mtime<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">self</span>.<span style="color: black;">MAGIC</span> + mtime</div>
<p>So, the PYC header file contains a magic number that identifies the Python release and the modification time of the original source file as the number of seconds since the epoch. That shouldn&#8217;t be a problem &#8211; the threading module hasn&#8217;t changed and should have the same timestamp. But as we&#8217;ve seen, the PYC files were different. How can that be?</p>
<p>Acting on a hunch, I wrote a short script to read the header from the PYC file and print the embedded date:</p>
<div class="ch_code_container" style="font-family: monospace;height:100%;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">os</span>, <span style="color: #dc143c;">os</span>.<span style="color: black;">path</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">struct</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> timedef print_internal_date<span style="color: black;">&#40;</span>filename<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; f = <span style="color: #008000;">open</span><span style="color: black;">&#40;</span>filename, <span style="color: #483d8b;">&quot;rb&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; data = f.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">8</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; mtime = <span style="color: #dc143c;">struct</span>.<span style="color: black;">unpack</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&amp;lt;i&quot;</span>, data<span style="color: black;">&#91;</span><span style="color: #ff4500;">4</span>:<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">time</span>.<span style="color: black;">asctime</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">time</span>.<span style="color: black;">gmtime</span><span style="color: black;">&#40;</span>mtime<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>print_internal_date<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;threading-old.pyc&quot;</span><span style="color: black;">&#41;</span><br />
print_internal_date<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;threading-new.pyc&quot;</span><span style="color: black;">&#41;</span></div>
<p>Which printed the following results:</p>
<pre>Mon Mar 13 22:51:26 2006
Mon Mar 13 12:51:26 2006</pre>
<p>Notice anything odd about them? They are <em>exactly</em> 10 hours apart. At first I thought I might actually be looking at two different versions of threading.py, but the chances of two edits being exactly 10 hours apart right down to the second is practically non-existent. It had to be something with time zones. I live and work in Israel, which is at GMT+2:00. The default timezone for Windows is Pacific time, which is GMT-8:00. Exactly 10 hours apart. However, no matter how I tweak the Regional Settings on my computer, all the PYC files I generate here have the same timestamp. Perhaps it has to do with the timezone you have set when you install Python. If I ever find out, I&#8217;ll let you know.</p>
<p>But that wasn&#8217;t the point of this post. The point was to figure out what PYC files look inside and we did that, at least in part &#8211; they start with a magic number that is different for each Python version (check out the comments in <a href="http://svn.python.org/view/python/tags/r244/Python/import.c?rev=52384&amp;view=markup">import.c</a>), and they have an embedded timestamp of the source code they got generated from after that. The rest is generated by the marshal module and can be read by it to get the code objects and the global data in the module.</p>
<p>Another thing to be learned from this is that we really should always build the Testuff client on the same machine, which is why I&#8217;m heading to the office right now to burn a copy of the VMWare image I created with everything needed to build Testuff. We got a new version with a couple of important fixes to our Mantis support to release today.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.gooli.org/blog/digging-into-pythons-pyc-files/&amp;title=Digging+into+Python%26%238217%3Bs+PYC+files" title="Add 'Digging into Python&#8217;s PYC files' to Del.icio.us"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Digging into Python&#8217;s PYC files' to Del.icio.us" alt="Add 'Digging into Python&#8217;s PYC files' to Del.icio.us" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.gooli.org/blog/digging-into-pythons-pyc-files/&amp;title=Digging+into+Python%26%238217%3Bs+PYC+files" title="Add 'Digging into Python&#8217;s PYC files' to digg"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Digging into Python&#8217;s PYC files' to digg" alt="Add 'Digging into Python&#8217;s PYC files' to digg" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.gooli.org/blog/digging-into-pythons-pyc-files/" title="Add 'Digging into Python&#8217;s PYC files' to Technorati"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Digging into Python&#8217;s PYC files' to Technorati" alt="Add 'Digging into Python&#8217;s PYC files' to Technorati" /></a>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.gooli.org/blog/digging-into-pythons-pyc-files/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Testuff is finally usable</title>
		<link>http://www.gooli.org/blog/133/</link>
		<comments>http://www.gooli.org/blog/133/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 11:28:49 +0000</pubDate>
		<dc:creator>gooli</dc:creator>
				<category><![CDATA[Testuff]]></category>

		<guid isPermaLink="false">http://www.gooli.org/blog/133/</guid>
		<description><![CDATA[It&#8217;s a very exciting time for us here at Testuff as our product has finally reached a point where it can actually be used by real people. You can&#8217;t use testing software unless you can report bugs, and until now we could only report bugs to Trac. Now, with the addition of support for Bugzilla [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed">It&#8217;s a very exciting time for us here at Testuff as our product has finally reached a point where it can actually be used by real people. You can&#8217;t use testing software unless you can report bugs, and until now we could only report bugs to Trac. Now, with the addition of support for Bugzilla and FogBugz, we really do integrate with several bug trackers as our home page claims, and the new test editor make it a breeze to add and edit test cases.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed">I&#8217;m going to talk about some of the new things we did for this version in the rest of this post, but if you just want to take a look at the new Testuff, <a href="http://www.testuff.com/download">just grab it from our site</a>.</p>
<p><strong>Eating Bonzo for breakfast</strong><a href="http://gooli.org/blog/wp-content/uploads/2007/12/testeditor.PNG" title="New Test Editor"><img src="http://gooli.org/blog/wp-content/uploads/2007/12/testeditor.PNG" style="margin: 10px; float: right" alt="New Test Editor" height="218" width="256" /></a><br />
They say eating your own dog food is important. Although I personally prefer a good steak, you can&#8217;t argue with some of the best minds of the software industry. Following the canine oriented software practice we finally sat down to create some tests for Testuff in, well, Testuff. And boy, was it awkward to write tests with our test editor. So we wrote a new test editor, which makes typing tests easy. Just separate the steps with a blank line and the editor will do the rest. You can also copy-paste tests into the new editor from almost anywhere â€“ Word, Excel, the web, etc.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed">We helped manually convert a bunch of tests for some of our clients who had a few hundred test cases written down in Excel. Took about half an hour to get it done including reorganizing the tests making sure there were no duplicates.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed"><strong>Integrate early, integrate often</strong><br />
It was kind of ridiculous that the Testuff front page said we supported integration with various bug trackers and when you scrolled down to the list, you saw we actually only supported <a href="http://trac.edgewall.org/">Trac</a>. We started out with Trac as we use it ourselves, but we now added support for two more popular bug trackers. We&#8217;re are going to add support for even more bug trackers, as that seems to be what our users want most.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed"><o:p></o:p><a href="http://www.bugzilla.org/">Bugzilla</a> is probably the oldest guy on the block. With almost 10 years of experience under their belts, the guys there know how to manage defects and have seen it all. <a href="http://avatraxiom.livejournal.com/58084.html">A interesting recent post</a> seems to indicate Bugzilla may be <a href="http://www.perlmonks.com/?node_id=561229">dying along side Perl</a>, but itâ€™s still widely used and loved by many however ugly I may think it&#8217;s UI is.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed">Many software developers know the name of Joel Spolsky. I was first introduced to <a href="http://www.joelonsoftware.com/Archive.html">his excellent articles</a> when I was a young officer in the Israeli army trying to lead a team of soldiers-developers through the mud of an enormous C++/MFC HR planning system. Some of the articles were amusing, some interesting and a few were a real eye-opener to me. His company, FogCreek, makes a bug tracking and project management software called <a href="http://www.fogcreek.com/FogBugz/">FogBugz</a>. Personally, I prefer the more Spartan approach of Trac and like to tinker with it&#8217;s Python code base, but FogBugz has many followers and it is now offered as an on-demand service, which makes it a great match with Testuff.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed"><strong>Those damn proxies</strong><br />
Being a desktop application with a web-based backend, the Testuff client needs to access our server in order to work. It turned out that accessing the internet through a proxy is a challenging task, which Python doesn&#8217;t help with nearly enough. I ended up wrapping the WinHTTP library with ctypes code and using it to connect to the internet using the settings in Internet Explorer. That seems to be working with all our clients so far, but it&#8217;s not a portable solution. I&#8217;ll be taking a look at <a href="http://pycurl.sourceforge.net/">pycurl</a> next, to see if it works as well as promised on their website. I&#8217;ll post a full report on the proxy fighting process sometime soon.<o:p> </o:p></p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed">Oh, yeah, and you can finally change the password you use to connect to Testuff.<o:p> That doesn&#8217;t have anything to do with the proxy support, but this stupid omission we made in previous versions doesn&#8217;t justify it&#8217;s own heading, right? </o:p></p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed"><strong>What&#8217;s next?</strong><br />
Right now weâ€™re hard at work on our next version, 0.8. There will be support for even more bug trackers that our customers asked for (<a href="http://www.mantisbt.org/" target="_blank">Mantis</a>, <a href="http://www.elementool.com/" target="_blank">Elementool</a>, <a href="http://www.atlassian.com/software/jira/" target="_blank">Jira</a> and maybe another one or two if we have the time), and, if I can fix that damn segfault, a Linux version of the Testuff client.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed">You can download Testuff from <a href="http://www.testuff.com/download">www.testuff.com/download</a>.</p>
<p class="MsoNormal" dir="ltr" style="text-align: left; direction: ltr; unicode-bidi: embed"><o:p> </o:p></p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.gooli.org/blog/133/&amp;title=Testuff+is+finally+usable" title="Add 'Testuff is finally usable' to Del.icio.us"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Testuff is finally usable' to Del.icio.us" alt="Add 'Testuff is finally usable' to Del.icio.us" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.gooli.org/blog/133/&amp;title=Testuff+is+finally+usable" title="Add 'Testuff is finally usable' to digg"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Testuff is finally usable' to digg" alt="Add 'Testuff is finally usable' to digg" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.gooli.org/blog/133/" title="Add 'Testuff is finally usable' to Technorati"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Testuff is finally usable' to Technorati" alt="Add 'Testuff is finally usable' to Technorati" /></a>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.gooli.org/blog/133/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ian&#8217;s comments on Testuff</title>
		<link>http://www.gooli.org/blog/ians-comments-on-testuff/</link>
		<comments>http://www.gooli.org/blog/ians-comments-on-testuff/#comments</comments>
		<pubDate>Fri, 19 Oct 2007 09:46:32 +0000</pubDate>
		<dc:creator>gooli</dc:creator>
				<category><![CDATA[Testuff]]></category>

		<guid isPermaLink="false">http://www.gooli.org/blog/ians-comments-on-testuff/</guid>
		<description><![CDATA[Wow!
I finally sat down today to write those Testuff emails I talked about and just as I was getting into the mood of doing that I spotted this post. Apparently Ian keeps track of whoever mentions his name and had quite a few things to say about our offer and our site. Thanks Ian!
Most of [...]]]></description>
			<content:encoded><![CDATA[<p>Wow!</p>
<p>I finally sat down today to write those <a href="http://www.testuff.com">Testuff</a> <a href="http://www.gooli.org/blog/testuff-a-test-case-management-service/">emails I talked about</a> and just as I was getting into the mood of doing that I spotted <a href="http://www.userscape.com/blog/index.php/site/testuff_feedback">this post</a>. Apparently Ian <a href="http://www.google.com/alerts">keeps track</a> of whoever mentions his name and had quite a few things to say about our offer and our site. Thanks Ian!</p>
<p>Most of the comments about <a href="http://www.testuff.com">Testuff</a> are dead on and we&#8217;re defeinitely going to address them, both on the website and in our application. Following are a couple of items I want to elaborate on.</p>
<p>Ian mentioned that it is unclear why he needed to download something:</p>
<blockquote><p>Itâ€™s also a bit confusing which parts are online and why Iâ€™m downloading something. Clearing that up a bit would be useful.</p>
</blockquote>
<p>We&#8217;re going to change the site to convey it better, but I do want to answer it right here for those who might have the same question. Testuff is a hybrid application with a rich GUI front end and a web-based backend. That means you have to download the client application to use it, but everything is stored online and can be shared between several people. That is similar to how services like <a href="http://www.apple.com/itunes/">iTunes</a> and <a href="http://www.osafoundation.org/">Chandler</a> work.</p>
<p>Ian also said that we need to state clearly that Testuff integrated with existing bug trackers:</p>
<blockquote><p>Your site makes it appear that the bugs are logged with you , though I found one random note that suggests it actually integrates with commercial bug trackers. This is a huge point, nobody wants to log bugs with you. You should prominently display the names of the bug trackers you support all over the place. That way when I come to your site I can see my bug trackers name and know you support it right away and that this <b>improves</b> my existing bug tracker not replaces it.</p>
</blockquote>
<p>Yes, we are going to integrate with existing bug trackers, but we haven&#8217;t done that yet. That&#8217;s why there&#8217;s only a random note about it on the site and it&#8217;s not in H1 on the main page. We&#8217;re hard at work on <a href="http://trac.edgewall.org/">Trac</a> integration with <a href="http://www.bugzilla.org/">Bugzilla</a> and <a href="http://www.fogcreek.com/FogBugz/">Fogbugz</a> on our feature list for the coming weeks. The selling point of actually improving your existing bug tracker is a great spin. After all, everybody uses a bug tracker these days (even if it is a simple excel sheet) and having the video records of the bugs in it could be huge!</p>
<p>Our original concept for building Testuff was to create something akin to <a href="http://www.mercury.com/us/products/quality-center/testdirector/">TestDirector</a>, but lighter, simpler and more useful for small companies. Using what we know about testing and QA we built a tool you could manage your testing process with &#8211; create tests, run them, record the results, and see reports about the quality of your product. That feature list seems to strike a note with the larger companies that already have a team of testers in place who are looking for tools to imrpove their processes. Smaller companies and mISV on the other hand, which we&#8217;re eager to please, seem to have less interest in test managament and are more excited by a better way to reproduce bugs.</p>
<p>&nbsp;</p>
<p><a href="http://www.testuff.com">Testuff</a> is a young service and is a work in progress. I am very eager to hear more comments and thoughts on the subject, especially the negative ones as you learn the most from those. I promise to address each and every one.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.gooli.org/blog/ians-comments-on-testuff/&amp;title=Ian%26%238217%3Bs+comments+on+Testuff" title="Add 'Ian&#8217;s comments on Testuff' to Del.icio.us"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Ian&#8217;s comments on Testuff' to Del.icio.us" alt="Add 'Ian&#8217;s comments on Testuff' to Del.icio.us" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.gooli.org/blog/ians-comments-on-testuff/&amp;title=Ian%26%238217%3Bs+comments+on+Testuff" title="Add 'Ian&#8217;s comments on Testuff' to digg"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Ian&#8217;s comments on Testuff' to digg" alt="Add 'Ian&#8217;s comments on Testuff' to digg" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.gooli.org/blog/ians-comments-on-testuff/" title="Add 'Ian&#8217;s comments on Testuff' to Technorati"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Ian&#8217;s comments on Testuff' to Technorati" alt="Add 'Ian&#8217;s comments on Testuff' to Technorati" /></a>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.gooli.org/blog/ians-comments-on-testuff/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Testuff &#8211; a test case management service</title>
		<link>http://www.gooli.org/blog/testuff-a-test-case-management-service/</link>
		<comments>http://www.gooli.org/blog/testuff-a-test-case-management-service/#comments</comments>
		<pubDate>Wed, 17 Oct 2007 13:41:24 +0000</pubDate>
		<dc:creator>gooli</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Testuff]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.gooli.org/blog/testuff-a-test-case-management-service/</guid>
		<description><![CDATA[&#60;marketing&#62;
I haven&#8217;t posted too much here lately and for a good reason. Arik and I have been hard at work to release the first public beta of our test management service called Testuff. Developing software is hard enough when you have plenty of resources but when you are a one- or two-man shop with limited [...]]]></description>
			<content:encoded><![CDATA[<p>&lt;marketing&gt;</p>
<p><a href="http://gooli.org/blog/wp-content/uploads/2007/10/icon.jpg"><img src="http://gooli.org/blog/wp-content/uploads/2007/10/icon-thumb.jpg" style="border: 0px none " alt="icon" align="right" border="0" height="160" width="160" /></a>I haven&#8217;t posted too much here lately and for a good reason. Arik and I have been hard at work to release the first public beta of our test management service called <a href="http://www.testuff.com">Testuff</a>. Developing software is hard enough when you have plenty of resources but when you are a one- or two-man shop with limited funds it&#8217;s even harder. We&#8217;ve built Testuff to help small companies and <a href="http://en.wikipedia.org/wiki/Micro_ISV">mISV&#8217;s</a> like ourselves manage and run their software tests. We&#8217;ve based it on the <a href="http://en.wikipedia.org/wiki/Software_as_a_Service">SaaS</a> model so you don&#8217;t have to install any servers, but we also made a rich desktop client for it so you could enjoy a better user experience. If you&#8217;re doing any sort real development for actual, breathing clients, you should <a href="http://www.testuff.com/download">try it out</a>.</p>
<p>&lt;/marketing&gt;</p>
<p>It&#8217;s been a week since the public release and although we made some marketing efforts (like this post) we&#8217;re still not getting enough traffic to our site. Only a few people have actually downloaded and tried to use our application and I think there&#8217;s only one name on that list that I don&#8217;t know. I realize we should be doing more marketing and getting the word out to as many people as we can but I don&#8217;t seem to be able to get past my perfectionism. I&#8217;m looking at Testuff now and it is (aside from some bugs and quirks) a fine achievement. It is quite convenient, rather pretty and has some really cool features like recording the video of the application you&#8217;re testing so you could reproduce the bugs with ease. However, since I&#8217;ve been working on it for so long, I&#8217;ve gotten u sed to all the cool things by now and I am already cultivating a new vision in my mind. A cleaner interface, less features, a faster bug video recorder, an ability to email a test to your friends who could run it and report the recording of the bug directly and so on. I&#8217;m struggling because I&#8217;ve promised my partner I&#8217;d write emails to some key figures in the micro ISV world (people like <a href="http://47hats.com/">Bob Walsh</a>, <a href="http://www.ericsink.com/">Eric Sink</a>, <a href="http://www.joelonsoftware.com/">Joel Spolsky</a>, <a href="http://www.userscape.com/blog/">Ian Landsman</a> and <a href="http://successfulsoftware.net/">Andy Brice</a>). But how can I describe the wonders of Testuff to them when I&#8217;m already thinking about the next version and the one after it?</p>
<p>Another thing I&#8217;m worried about is the fact that although every developer and QA I&#8217;ve talked to was very excited about Testuff, very few have visited the site and tried it out, not to mention started using it on their own team. Price shouldn&#8217;t be an obstacle as we&#8217;re giving it out for free right now and I don&#8217;t think there is a lack of need for a service like this. Something is amiss however and I still haven&#8217;t figured out what it is.</p>
<p>I&#8217;d love to hear any thoughts you may have on the subject and any advice you might have. You&#8217;ll probably need to install Testuff to do that (Ha! Gotcha!) so you&#8217;d better head on to the <a href="http://www.testuff.com/download">Testuff download page</a>.</p>
<!-- Social Bookmarks BEGIN -->
<div class="social_bookmark">
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.gooli.org/blog/testuff-a-test-case-management-service/&amp;title=Testuff+%26%238211%3B+a+test+case+management+service" title="Add 'Testuff &#8211; a test case management service' to Del.icio.us"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Testuff &#8211; a test case management service' to Del.icio.us" alt="Add 'Testuff &#8211; a test case management service' to Del.icio.us" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.gooli.org/blog/testuff-a-test-case-management-service/&amp;title=Testuff+%26%238211%3B+a+test+case+management+service" title="Add 'Testuff &#8211; a test case management service' to digg"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Testuff &#8211; a test case management service' to digg" alt="Add 'Testuff &#8211; a test case management service' to digg" /></a>
<a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.gooli.org/blog/testuff-a-test-case-management-service/" title="Add 'Testuff &#8211; a test case management service' to Technorati"><img src="http://gooli.org/blog/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Testuff &#8211; a test case management service' to Technorati" alt="Add 'Testuff &#8211; a test case management service' to Technorati" /></a>
</div>
<!-- Social Bookmarks END -->
]]></content:encoded>
			<wfw:commentRss>http://www.gooli.org/blog/testuff-a-test-case-management-service/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
