<?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>tartley.com</title>
	<atom:link href="http://tartley.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://tartley.com</link>
	<description>A website dedicated to oneself has been described as the greatest act of hubris. Welcome aboard.</description>
	<lastBuildDate>Thu, 25 Apr 2013 10:12:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>pip install : Lightspeed and Bulletproof</title>
		<link>http://tartley.com/?p=1423</link>
		<comments>http://tartley.com/?p=1423#comments</comments>
		<pubDate>Fri, 08 Mar 2013 09:29:09 +0000</pubDate>
		<dc:creator>tartley</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://tartley.com/?p=1423</guid>
		<description><![CDATA[I saw a post about speeding up the Python packaging command &#8220;pip install&#8221;, by specifying more responsive mirrors for querying and downloading packages. For my situation, a better tactic is this. Step one: Download all your project&#8217;s dependencies into a <a class="more-link" href="http://tartley.com/?p=1423">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I saw a post about <a href="http://www.scottisheyes.com/how-to-fix-slow-pip-install">speeding up the Python packaging command &#8220;pip install&#8221;</a>, by specifying more responsive mirrors for querying and downloading packages. For my situation, a better tactic is this.</p>
<p>Step one: Download all your project&#8217;s dependencies into a local &#8216;packages&#8217; dir, but don&#8217;t install them yet:</p>
<p><code>mkdir packages<br />
pip install --download=packages -r requirements.txt</code></p>
<p>Step two, install from the &#8216;packages&#8217; dir:</p>
<p><code>pip install --no-index --find-links=packages -r requirements.txt</code></p>
<p><em id="__mceDel">(The above syntax works on pip 1.3, released yesterday. Docs for older versions of pip claim to support this, but in practice, for pip 1.2, I&#8217;ve had to use &#8220;<code style="font-style: inherit;">--find-links=file://$PWD/packages</code>&#8220;)</em></p>
<p>Step 2 works even if PyPI is unreachable. It works even if some of your dependencies are self-hosted by the authors, and that website is unreachable. It works even if the version you have pinned of one of your dependencies has been deleted by the author (some packages do this routinely after security updates.) It works even if you have no network connection at all. In short, it makes creation of your virtualenv bulletproof.</p>
<p>As a nice side effect, it runs really fast, because it isn&#8217;t downloading the packages across the internet, nor is it attempting to scan a remote index to check for matching or newer versions of each package. This is much quicker than just using a Pip download cache, especially for large projects with many dependencies which only change occasionally.</p>
<p>At <a href="http://rangespan.com">Rangespan</a>, we check the &#8216;packages&#8217; directory into source control, so that once you&#8217;ve checked out a project&#8217;s repo, you have everything you need to deploy locally and run, even if you have no network. You might choose to treat &#8216;packages&#8217; as ephemeral.</p>
<p>It was pointed out to me recently by <a href="https://twitter.com/jezdez">@jezdez</a>, Pip maintainer, this usage pattern has now been <a href="http://www.pip-installer.org/en/latest/cookbook.html#fast-local-installs">explicitly called out in the documentation</a>, which was substantially reorganised and improved with the recent 1.3 release.</p>
]]></content:encoded>
			<wfw:commentRss>http://tartley.com/?feed=rss2&#038;p=1423</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Hexagonal Django</title>
		<link>http://tartley.com/?p=1404</link>
		<comments>http://tartley.com/?p=1404#comments</comments>
		<pubDate>Tue, 04 Dec 2012 14:42:01 +0000</pubDate>
		<dc:creator>tartley</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://tartley.com/?p=1404</guid>
		<description><![CDATA[The last few weeks I&#8217;ve been thinking about the architectural pattern known as Clean, Onion, Hexagonal, or Ports&#8217;n'Adaptors. I&#8217;m curious if many people are applying it in the Django world. The premise is for your core application entity classes and business <a class="more-link" href="http://tartley.com/?p=1404">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>The last few weeks I&#8217;ve been thinking about the architectural pattern known as <a href="http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html">Clean, Onion, Hexagonal, or Ports&#8217;n'Adaptors</a>. I&#8217;m curious if many people are applying it in the Django world.</p>
<p>The premise is for your core application entity classes and business rules to be plain old objects, with no dependencies. In particular, they are not dependent on the interfaces between your application and external systems, such as your persistence mechanism, or your web framework. Instead, external interface components depend upon your core business objects. This essentially moves the database from the &#8216;bottom&#8217; layer of the old traditional &#8216;three layer architecture&#8217;, to form a part of the topmost layer &#8211; a sibling with the &#8216;UI.&#8217;</p>
<p>For inbound messages (e.g handling a web request) this is straightforward &#8211; Django calls your view code which calls your business layer, but keep your business layer separate from your Django code, so it is stand-alone and unit-testable. For outbound messages, such as then rendering the web page in response, it&#8217;s slightly more complicated: Your business logic must pass the result (typically a pure data structure) back to your web-aware code, but without your business logic depending on the web-aware component. This requires an inversion of control.</p>
<p>That way, all your business logic can easily be tested in unit tests, with no mocking required. You still need some end-to-end tests to verify integration, but you shouldn&#8217;t need to involve your UI or database in testing every detail of your business logic.</p>
<p>Also, you can easily switch out your external system interfaces, such as persistence, to use another RDBMS, another ORM, a NoSQL store, or an in-memory version for testing Since the core of your application doesn&#8217;t have any dependency on these components, it is oblivious to the change. The business logic, because it doesn&#8217;t depend on Django, is no longer riddled with Django&#8217;s convenient ORM database access.</p>
<p>Same thing goes for switching out your web framework, or calling the same logic from web UI or web API calls. And again, for switching out your UI: add a command line application, or a console UI. The core application logic is unaffected, and your new interface components contain only the code that is specific to that interface&#8217;s concerns.</p>
<p>Another side effect is that your web framework, if you&#8217;re using one, becomes a peripheral detail which depends upon your core application, rather than the other way round. Your Django project would become a subdirectory of your project, rather than dominating your project directory structure. Since the business logic formerly contained within it is now elsewhere (in your core business objects) the Django project is now very thin. Views, for example, are delegations to single business-layer functions. The Django project now contains just the web-oriented aspects of your project, as it should.</p>
<p>These ideas all seem like relatively straightforward software engineering, and I feel a bit foolish for not having been aware of them all these years. I console myself that I&#8217;m not alone.</p>
<p>UncleBob&#8217;s Ruby Midwest keynote &#8220;<a href=" http://www.confreaks.com/videos/759-rubymidwest2011-keynote-architecture-the-lost-years">Architecture &#8211; The Lost Years</a>&#8221; attributes one source of this idea to Ivar Jacobsen&#8217;s 1994 book <a href=" http://www.amazon.co.uk/Object-oriented-Software-Engineering-Approach-Press/dp/0201544350">Object Oriented Software Engineering : A Use Case Driven Approach</a> (2nd-hand hardbacks cheap on Amazon.)</p>
<p>I see a few people applying these ideas to Rails, but are many people out there doing this in Django? I plan to refactor a small vertical slice of our monster Django app into this style, to try and prove the idea for myself.</p>
]]></content:encoded>
			<wfw:commentRss>http://tartley.com/?feed=rss2&#038;p=1404</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Encrypted zip files on OSX</title>
		<link>http://tartley.com/?p=1392</link>
		<comments>http://tartley.com/?p=1392#comments</comments>
		<pubDate>Tue, 09 Oct 2012 09:17:07 +0000</pubDate>
		<dc:creator>tartley</dc:creator>
				<category><![CDATA[OSX-dev]]></category>

		<guid isPermaLink="false">http://tartley.com/?p=1392</guid>
		<description><![CDATA[My passwords and other miscellany are in a plain text file within an encrypted zip. Since starting to use OSX I&#8217;ve been looking for a way to access my passwords such that: I get prompted for the decryption password. The <a class="more-link" href="http://tartley.com/?p=1392">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>My passwords and other miscellany are in a plain text file within an encrypted zip. Since starting to use OSX I&#8217;ve been looking for a way to access my passwords such that:</p>
<ul>
<li>I get prompted for the decryption password.</li>
<li>The file gets unzipped, but not in the same directory, because that&#8217;s synced to Dropbox, so would send my plaintext passwords to them every time I accessed them. Maybe to /tmp?</li>
<li>The plaintext file within the zip is opened in $EDITOR.</li>
<li>Wait for me to close $EDITOR, then remove my plaintext passwords from the filesystem.</li>
<li>Before deleting the passwords, check if I&#8217;ve updated them. If so, put the new updated version back into the original zip file.</li>
<li>Don&#8217;t forget to keep the updated zip file encrypted, using the same password as before, without prompting for it again.</li>
</ul>
<p>I failed to find an existing app which would do all this (although I had no trouble on Linux or even on Windows.) Hence, resorting to good old Bash:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #007800;">ZIPDIR</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$HOME</span>/docs/org&quot;</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #660033;">-s</span> <span style="color: #660033;">-p</span> <span style="color: #ff0000;">&quot;Password:&quot;</span> key
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$ZIPDIR</span>
<span style="color: #c20cb9; font-weight: bold;">unzip</span> <span style="color: #660033;">-P</span> <span style="color: #007800;">$key</span> passwords.zip passwords.txt <span style="color: #660033;">-d</span> <span style="color: #007800;">$TMPDIR</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$?</span> <span style="color: #000000; font-weight: bold;">!</span>= <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$TMPDIR</span>&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">touch</span> passwords.datestamp
<span style="color: #007800;">$EDITOR</span> passwords.txt
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span> passwords.txt <span style="color: #660033;">-nt</span> passwords.datestamp <span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> ; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #c20cb9; font-weight: bold;">zip</span> <span style="color: #660033;">-P</span> <span style="color: #007800;">$key</span> <span style="color: #660033;">-r</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$ZIPDIR</span>/passwords.zip&quot;</span> passwords.txt
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">rm</span> passwords.txt
<span style="color: #c20cb9; font-weight: bold;">rm</span> passwords.datestamp</pre></td></tr></table></div>

<p>I don&#8217;t expect this to be watertight, but seems good enough for today. I&#8217;m happy to hear suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://tartley.com/?feed=rss2&#038;p=1392</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Compiling MacVim with Python 2.7</title>
		<link>http://tartley.com/?p=1355</link>
		<comments>http://tartley.com/?p=1355#comments</comments>
		<pubDate>Tue, 18 Oct 2011 11:25:03 +0000</pubDate>
		<dc:creator>tartley</dc:creator>
				<category><![CDATA[OSX-dev]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Vim]]></category>

		<guid isPermaLink="false">http://tartley.com/?p=1355</guid>
		<description><![CDATA[I love the brilliant Vim plugin pyflakes-vim, which highlights errors &#38; warnings, and since I got a MacBook for work, I&#8217;ve been using MacVim a lot. This combination has a problem, that MacVim uses the OSX system default Python 2.6, <a class="more-link" href="http://tartley.com/?p=1355">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I love the brilliant Vim plugin <a href="http://www.vim.org/scripts/script.php?script_id=2441">pyflakes-vim</a>, which highlights errors &amp; warnings, and since I got a MacBook for work, I&#8217;ve been using MacVim a lot.</p>
<p>This combination has a problem, that MacVim uses the OSX system default Python 2.6, so pyflakes is unable to handle Python 2.7 syntax, such as set literals. These are marked as a syntax errors, which prevents the rest of the file from being parsed.</p>
<p>The solution is to compile your own MacVim, using Python 2.7 instead of the system Python. The following commands got MacVim compiled for me:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #c20cb9; font-weight: bold;">git clone</span> git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>b4winckler<span style="color: #000000; font-weight: bold;">/</span>macvim.git
<span style="color: #7a0874; font-weight: bold;">cd</span> macvim<span style="color: #000000; font-weight: bold;">/</span>src
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LDFLAGS</span>=-L<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib
.<span style="color: #000000; font-weight: bold;">/</span>configure \
    <span style="color: #660033;">--with-features</span>=huge \
    <span style="color: #660033;">--enable-rubyinterp</span> \
    <span style="color: #660033;">--enable-perlinterp</span> \
    <span style="color: #660033;">--enable-cscope</span> \
    <span style="color: #660033;">--enable-pythoninterp</span> \
    <span style="color: #660033;">--with-python-config-dir</span>=<span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Frameworks<span style="color: #000000; font-weight: bold;">/</span>Python.framework<span style="color: #000000; font-weight: bold;">/</span>Versions<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2.7</span><span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>python2.7<span style="color: #000000; font-weight: bold;">/</span>config
<span style="color: #c20cb9; font-weight: bold;">make</span>
open MacVim<span style="color: #000000; font-weight: bold;">/</span>build<span style="color: #000000; font-weight: bold;">/</span>Release
<span style="color: #7a0874; font-weight: bold;">echo</span> Drag MacVim.app to your Applications directory</pre></td></tr></table></div>

<p>Without the LDFLAGS setting, I was missing some symbols at link. The &#8211;with-python-config-dir entry came from typing &#8216;which python&#8217; to find where my Python 2.7 install lives, and modifying that result to find its &#8216;config&#8217; directory (whatever that is) near to the binary.</p>
<p>As indicated, install by dragging the resulting macvim/src/MacVim/build/Release/MacVim.app into your Applications directory.</p>
<p>Open up MacVim, and check out the built-in Python version:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="vim" style="font-family:monospace;"><span style="color: #000000;">:</span>python import sys; print sys<span style="color: #000000;">.</span>version
2<span style="color: #000000;">.</span>7<span style="color: #000000;">.</span>1 <span style="color: #000000;">&#40;</span>r271<span style="color: #000000;">:</span>86882M, Nov <span style="color: #000000; font-weight:bold;">30</span> <span style="color: #000000; font-weight:bold;">2010</span>, <span style="color: #000000; font-weight:bold;">10</span><span style="color: #000000;">:</span><span style="color: #000000; font-weight:bold;">35</span><span style="color: #000000;">:</span><span style="color: #000000; font-weight:bold;">34</span><span style="color: #000000;">&#41;</span></pre></td></tr></table></div>

<p>And files with set literals are now correctly parsed for errors.</p>
<p><strong>Update:</strong> This only works if the Python 2.7 is your default &#8216;python&#8217; executable. Otherwise, or if you get &#8220;ImportError: No module named site&#8221;, see Richard&#8217;s comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://tartley.com/?feed=rss2&#038;p=1355</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Python 2.7 regular expression cheatsheet</title>
		<link>http://tartley.com/?p=1349</link>
		<comments>http://tartley.com/?p=1349#comments</comments>
		<pubDate>Fri, 14 Oct 2011 10:20:11 +0000</pubDate>
		<dc:creator>tartley</dc:creator>
				<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://tartley.com/?p=1349</guid>
		<description><![CDATA[Couldn&#8217;t find one of these, so I whipped one up. Bit of restructured text: https://github.com/tartley/python-regex-cheatsheet/blob/master/cheatsheet.rst Install some Python packages: https://github.com/tartley/python-regex-cheatsheet/blob/master/requirements.txt Invoke rst2pdf: https://github.com/tartley/python-regex-cheatsheet/blob/master/Makefile Get a nice PDF out: Python 2.7 regular expression cheatsheet (click this link or the image for <a class="more-link" href="http://tartley.com/?p=1349">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Couldn&#8217;t find one of these, so I whipped one up.</p>
<p>Bit of restructured text:</p>
<p style="padding-left: 30px;"><a href="https://github.com/tartley/python-regex-cheatsheet/blob/master/cheatsheet.rst">https://github.com/tartley/python-regex-cheatsheet/blob/master/cheatsheet.rst</a></p>
<p>Install some Python packages:</p>
<p style="padding-left: 30px;"><a href="https://github.com/tartley/python-regex-cheatsheet/blob/master/requirements.txt">https://github.com/tartley/python-regex-cheatsheet/blob/master/requirements.txt</a></p>
<p>Invoke rst2pdf:</p>
<p style="padding-left: 30px;"><a href="https://github.com/tartley/python-regex-cheatsheet/blob/master/Makefile">https://github.com/tartley/python-regex-cheatsheet/blob/master/Makefile</a></p>
<p>Get a nice PDF out:</p>
<p style="padding-left: 30px;"><a href="https://github.com/downloads/tartley/python-regex-cheatsheet/cheatsheet.pdf">Python 2.7 regular expression cheatsheet</a> (click this link or the image for the most up-to-date PDF from github.)</p>
<p style="padding-left: 30px;"><a href="https://github.com/downloads/tartley/python-regex-cheatsheet/cheatsheet.pdf"><img class="alignnone size-full wp-image-1363" title="Python regular expression cheatsheet 0.3.0" src="http://tartley.com/wp-content/uploads/2011/10/Python-regular-expression-cheatsheet-0.3.0.png" alt="" width="795" height="948" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://tartley.com/?feed=rss2&#038;p=1349</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Django testing 201 : Acceptance Tests vs Unit Tests</title>
		<link>http://tartley.com/?p=1337</link>
		<comments>http://tartley.com/?p=1337#comments</comments>
		<pubDate>Thu, 14 Jul 2011 15:19:43 +0000</pubDate>
		<dc:creator>tartley</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://tartley.com/?p=1337</guid>
		<description><![CDATA[I&#8217;m finding that our Django project&#8217;s tests fall into an uncomfortable middle-ground, halfway between end-to-end acceptance tests and proper unit tests. As such they don&#8217;t exhibit the best qualities of either. I&#8217;d like to fix this. We&#8217;re testing our Django <a class="more-link" href="http://tartley.com/?p=1337">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>I&#8217;m finding that our Django project&#8217;s tests fall into an uncomfortable middle-ground, halfway between end-to-end acceptance tests and proper unit tests. As such they don&#8217;t exhibit the best qualities of either. I&#8217;d like to fix this.</p>
<p>We&#8217;re testing our Django application in what I believe is the canonical way, as described by the <a href="https://docs.djangoproject.com/en/dev/topics/testing/">excellent documentation</a>. We have a half-dozen Django applications, with a mixture of <code>unittest.TestCase</code> and <code>django.test.TestCase</code> subclasses in each application&#8217;s tests.py module. They generally use fixtures or the Django ORM to set up data for the test, then invoke the function-under-test, and then make assertions about return values or side-effects, often using the ORM again to assert about the new state of the database.</p>
<h2>Not an Acceptance Test</h2>
<p>Such a test doesn&#8217;t provide the primary benefit of an acceptance test, namely proof that the application actually works, because it isn&#8217;t quite end-to-end enough. Instead of calling methods-under-test, we should be using the Django testing client to make HTTP requests to our web services, and maybe incorporating Selenium tests to drive our web UI. This change is a lot of work, but at least the path forward seems clear.</p>
<p>However, an additional problem is that acceptance tests ought to be associated with features that are visible to an end user. A single user story might involve calls to several views, potentially spread across different Django apps. Because of this, I don&#8217;t think it&#8217;s appropriate for an acceptance test to live within a single Django app&#8217;s directory.</p>
<h2>Not a Unit Test</h2>
<p>On the other hand, our existing tests are also not proper unit tests. They hit the (test) database and the filesystem, and they currently don&#8217;t do any mocking out of expensive or complicated function calls. As a result, they are slow to run, and will only get slower as we ramp up our feature set and our test coverage. This is a cardinal sin for unit tests, and it discourages developers from running the tests frequently enough. In addition, tests like this often require extensive setup of test data, and are therefore hard to write, so it&#8217;s very labour-intensive to provide adequate test coverage.</p>
<h2>My Solution</h2>
<p><strong>1) I&#8217;ve created a top-level acceptancetests directory.</strong> Most of our  current tests will be moved into this directory, because they are closer  to acceptance tests than unit tests, and will gradually be modified to  be more end-to-end.</p>
<p>These acceptance tests need to be run by the Django testrunner,  since they rely on lots of things that it does, such as creating the  test database and rolling back after each test method. However, the Django testrunner won&#8217;t find these tests unless I make &#8216;acceptancetests&#8217; a new Django application, and import all acceptance test classes into its tests.py. I&#8217;m considering doing this, but for the moment I have another solution, which I&#8217;ll describe in a moment.</p>
<p>We also need to be able to create unit tests for all of our code, regardless of whether that code is within a Django model, or somewhere else in a Django app, or in another top-level directory that isn&#8217;t a Django app. Such unit tests should live in a &#8216;tests&#8217; package right next to the code they test. I&#8217;m puzzled as to why Django&#8217;s testrunner doesn&#8217;t look for unit tests throughout the project and just run them all, along with the Django-specific tests.</p>
<p><strong>2) My solution to this is to augment the Django test runner</strong>, by inheriting from it. My test runner, instead of just looking for tests in each app&#8217;s models.py and tests.py, looks for subclasses of unittest.TestCase in every module throughout the whole project. Setting Django&#8217;s settings.TEST_RUNNER causes this custom test runner to be used by &#8216;manage.py test&#8217;. Thanks to the Django contributors for this flexibility!</p>
<p>So the new test runner finds and runs all the tests which the default Django runner runs, and it also finds our unit tests from all over the project, and it also includes our new top-level &#8216;acceptancetests&#8217; directory. This is great!</p>
<p>One surprise is that the number of tests which get run has actually decreased. On closer inspection, this is because the standard Django test runner includes all the tests for every Django app, and this includes not just my project&#8217;s apps, but also the built-in and middleware Django apps. We are no longer running these tests. Is this important? I&#8217;m not sure: After all, we are not modifying the code in django.contrib, so I don&#8217;t expect these tests to start failing. On the other hand, maybe those tests help to demonstrate that our Django settings are not broken?</p>
<h2>An appeal for sanity</h2>
<p>My solutions seem to work, but I&#8217;m suspicious that I&#8217;m swimming against the current, because I haven&#8217;t found much discussion about these issues, so maybe I&#8217;m just well off the beaten path. Have many other people already written a similar extension to Django&#8217;s test runner? If so, where are they all? If not, why not? How else is everyone running their Django project tests in locations other than models.py or tests.py? Or do they not have tests outside these locations? If not, why not? I&#8217;d love to hear about it if I&#8217;m doing it wrong, or if there&#8217;s an easier approach.</p>
<p><strong>Update: </strong>My <a href="http://rangespan.com/">fabulous employer</a> has given permission to release the test runner as open source:</p>
<p style="padding-left: 30px;"><a href="https://github.com/rangespan/django-alltestsrunner">https://github.com/rangespan/django-alltestsrunner</a></p>
<p><strong>Update2:</strong> I like this post&#8217;s numeric ID (check the URL)</p>
]]></content:encoded>
			<wfw:commentRss>http://tartley.com/?feed=rss2&#038;p=1337</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>£ key in Windows on a US laptop keyboard, done right.</title>
		<link>http://tartley.com/?p=1317</link>
		<comments>http://tartley.com/?p=1317#comments</comments>
		<pubDate>Sun, 10 Jul 2011 12:06:34 +0000</pubDate>
		<dc:creator>tartley</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[MSWin-dev]]></category>

		<guid isPermaLink="false">http://tartley.com/?p=1317</guid>
		<description><![CDATA[The usual solution to typing non-US characters on a US keyboard in Windows is to hold left-alt, then type on the numeric keypad: £ Left-alt + 0163 € Left-alt + 0128 This is a pain on my (otherwise fabulous) Thinkpad <a class="more-link" href="http://tartley.com/?p=1317">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>The usual solution to typing non-US characters on a US keyboard in Windows is to hold left-alt, then type on the numeric keypad:</p>
<p>  £   Left-alt + 0163<br />
  €   Left-alt + 0128</p>
<p>This is a pain on my (otherwise fabulous) Thinkpad laptop, because the numeric keypad is accessed by holding the blue &#8216;Fn&#8217; key while you tap ScrLk, to toggle numeric keypad mode, and then doing the same again afterwards to turn it off.</p>
<p>One inadequate alternative (on WindowsXP, YMMV) is to go into control panel; Regional and Language Options; Languages; Details; Settings. Add a new keyboard configuration, &#8220;United States-International&#8221;, which should be grouped under your existing language (&#8220;English (United Kingdom)&#8221; for me.) OK all the dialogs, restart your applications.</p>
<p>Now you can simply type:</p>
<p> £  Right-alt + Shift + 4<br />
 €  Right-alt + 5</p>
<p>The downside of this solution is that the &#8220;UnitedStates-International&#8221; keyboard setting adds a bunch of other features, including &#8216;dead-keys&#8217;, whereby quotes and other punctuation are used to add accents to letters, which is overly intrusive if, like me, you hardly ever use accents.</p>
<p>Ultimate solution then, define your own personal keyboard layout. Download the Microsoft Keyboard Layout Creator from here: <a href="http://msdn.microsoft.com/en-us/goglobal/bb964665">http://msdn.microsoft.com/en-us/goglobal/bb964665</a>.</p>
<p>My end result is an MSI with which I can install a new keyboard layout, which is exactly like &#8216;US&#8217;, but with the addition of £ on the key right-alt + 3:</p>
<p><a href="http://tartley.com/wp-content/uploads/2011/07/windows-US-keyboard-layout-with-pound-on-right-alt-3.zip">windows-US-keyboard-layout-with-pound-on-right-alt-3</a></p>
<p>The source .klc file is in there, so you could add your own tweaks on top of that.</p>
]]></content:encoded>
			<wfw:commentRss>http://tartley.com/?feed=rss2&#038;p=1317</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
