<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>about:me</title><link href="https://ibofobi.dk/" rel="alternate"></link><link href="https://ibofobi.dk/blog/feeds/latest/index.xml" rel="self"></link><id>https://ibofobi.dk/</id><updated>2013-03-24T00:00:00+01:00</updated><entry><title>SNI-support for requests</title><link href="https://ibofobi.dk/blog/archive/2013/03/sni-support-for-requests/" rel="alternate"></link><updated>2013-03-24T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2013-03-24:blog/archive/2013/03/sni-support-for-requests/</id><summary type="html">&lt;p&gt;The &lt;code&gt;ssl&lt;/code&gt; module in Python 2&amp;#8217;s standard library does not support the &lt;span class="caps"&gt;SNI&lt;/span&gt;
&lt;span class="caps"&gt;TLS&lt;/span&gt;-extension, and it probably never will, which means that the brilliant
&lt;code&gt;requests&lt;/code&gt; &lt;span class="caps"&gt;HTTP&lt;/span&gt; library is also missing &lt;span class="caps"&gt;SNI&lt;/span&gt;-support on Python&amp;nbsp;2.&lt;/p&gt;
&lt;p&gt;Now that &lt;code&gt;urllib3&lt;/code&gt; has a contrib-module for &lt;span class="caps"&gt;SNI&lt;/span&gt;-support on Python 2 this might
change, but if you don&amp;#8217;t want to wait for the updated &lt;code&gt;urllib3&lt;/code&gt; to be included
in a &lt;code&gt;requests&lt;/code&gt; release, you can monkey-patch &lt;code&gt;requests&lt;/code&gt; yourself:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install the required&amp;nbsp;packages:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;pip install pyOpenSSL ndg-httpsclient pyasn1
&lt;/pre&gt;&lt;/div&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Download
   &lt;a href='https://ibofobi.dk/static/files/requests_pyopenssl.py'&gt;&lt;code&gt;requests_pyopenssl.py&lt;/code&gt;&lt;/a&gt;
   and put it somewhere on your &lt;code&gt;PYTHONPATH&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Monkey-patch &lt;code&gt;requests&lt;/code&gt; somewhere early in your application (possibly in a
   &lt;code&gt;sitecustomize&lt;/code&gt; module):&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests_pyopenssl&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;requests.packages.urllib3&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;connectionpool&lt;/span&gt;
    &lt;span class="n"&gt;connectionpool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ssl_wrap_socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests_pyopenssl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ssl_wrap_socket&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ImportError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you want to test that it works, the following Python script should print
&amp;#8220;&lt;code&gt;requests SNI-support Ok&lt;/code&gt;&amp;#8221; when&amp;nbsp;run:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests_pyopenssl&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;requests.packages.urllib3&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;connectionpool&lt;/span&gt;
    &lt;span class="n"&gt;connectionpool&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ssl_wrap_socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests_pyopenssl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ssl_wrap_socket&lt;/span&gt;
&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ImportError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;requests&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;alice&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;bob&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;carol&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;dave&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;mallory&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;www&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;https://&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;.sni.velox.ch&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;replace&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Great!&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;

&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;requests SNI-support Ok&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</summary><category term="python"></category><category term="requests"></category><category term="http"></category><category term="ssl"></category><category term="sni"></category></entry><entry><title>Pelican</title><link href="https://ibofobi.dk/blog/archive/2013/03/pelican/" rel="alternate"></link><updated>2013-03-23T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2013-03-23:blog/archive/2013/03/pelican/</id><summary type="html">&lt;p&gt;No more crufty, home-grown static-site-generation &amp;#8212; this is now generated by
shiny &lt;a href='http://getpelican.com'&gt;pelican&lt;/a&gt;.&lt;/p&gt;</summary></entry><entry><title>Ubuntu vs sitecustomize.py</title><link href="https://ibofobi.dk/blog/archive/2013/03/ubuntu-vs-sitecustomizepy/" rel="alternate"></link><updated>2013-03-23T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2013-03-23:blog/archive/2013/03/ubuntu-vs-sitecustomizepy/</id><summary type="html">&lt;p&gt;Sometimes it is almost like the Ubuntu developers go out of their way to annoy
the rest of the world, &lt;a
href='https://bugs.launchpad.net/ubuntu/+source/python2.5/+bug/197219'&gt; this
time&lt;/a&gt; (for ancient values of &amp;#8220;this time&amp;#8221;) the Python package-maintainer
decided to add a &lt;code&gt;sitecustomize&lt;/code&gt; module to the Python standard library. This
is &lt;em&gt;not&lt;/em&gt; what &lt;code&gt;sitecustomize&lt;/code&gt; is for, &lt;code&gt;sitecustomize&lt;/code&gt; is for &amp;#8220;performing
arbitrary site-specific&amp;nbsp;customizations&amp;#8221;.&lt;/p&gt;
&lt;p&gt;This is pretty annoying, when you want to use &lt;code&gt;sitecustomize&lt;/code&gt; for its intended
purpose, so puppet to the&amp;nbsp;rescue:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="k"&gt;file&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;/usr/lib/python2.7/sitecustomize.py&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;/usr/lib/python2.7/sitecustomize.pyc&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;&amp;#39;/usr/lib/python2.7/sitecustomize.pyo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="na"&gt;ensure&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="na"&gt;removed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</summary><category term="ubuntu"></category><category term="python"></category><category term="puppet"></category></entry><entry><title>New bestest Firefox extension</title><link href="https://ibofobi.dk/blog/archive/2006/03/new-bestest-firefox-extension/" rel="alternate"></link><updated>2006-03-13T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2006-03-13:blog/archive/2006/03/new-bestest-firefox-extension/</id><summary type="html">&lt;p&gt;I have a new favourite Firefox extension: &lt;a href="http://click2tab.mozdev.org/"&gt;click2tab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I can&amp;#8217;t count how many times I have pressed ctrl+w in a Firefox textarea, trying to rub out
the last word I wrote, and instead been faced with loosing my entire browser. &amp;#8220;Grrrr,&amp;#8221; is
my usual response to&amp;nbsp;this.&lt;/p&gt;
&lt;p&gt;In my opinion Firefox should recognize that ctrl+w in a textarea very probably is
a Unix person making a bad mistake. Alas, it does not. &lt;a href="http://click2tab.mozdev.org/"&gt;click2tab&lt;/a&gt;
does not save me from making the mistake, but it lets me undo the close tab operation.
Which is just as&amp;nbsp;swell.&lt;/p&gt;
&lt;p&gt;Yay!&lt;/p&gt;</summary></entry><entry><title>The Classics</title><link href="https://ibofobi.dk/blog/archive/2006/02/the-classics/" rel="alternate"></link><updated>2006-02-26T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2006-02-26:blog/archive/2006/02/the-classics/</id><summary type="html">&lt;p&gt;For the past 10 years the only fiction I have read is sci.fi., with a few detours into fantasy. It started some time during late primary school, when the slow, painful death of my literature classes took their toll. Those classes were meant to introduce us to classic literature and good writing in general. I thought all of the books we read were mind-numbingly dull. So depressingly, horribly dull that in spite I didn&amp;#8217;t read a single book for literature class all through high&amp;nbsp;school.&lt;/p&gt;
&lt;p&gt;The sad thing is, then and now, I love reading. So, the danish primary education system turned a confessed bibliophile off classic literature. Which has bugged me ever since: I always felt there must be a good reason classic literature is considered.. well, classic. So, once in a while, when shopping science fiction, I would also buy a classic, thinking: “Maybe, this one is worth reading.” Alas, those books always went to the bottom of the pile. And stayed&amp;nbsp;there.&lt;/p&gt;
&lt;p&gt;But. Recently I dug into the book pile next to my reading chair, and decided to give one of the classics a try. Orwell&amp;#8217;s &lt;a href="http://www.amazon.com/gp/product/0451526341"&gt;Animal Farm&lt;/a&gt; came first. I was right, Animal Farm &lt;em&gt;is&lt;/em&gt; a very good book. Next I picked up Kafka&amp;#8217;s &lt;a href="http://www.amazon.com/gp/product/0805210407"&gt;The Trial&lt;/a&gt;. The cover says &amp;#8220;the masterpiece of the 20th century&amp;#8221;; that must mean the book is a classic. And, so far the story captivates me (pun somewhat&amp;nbsp;intended.)&lt;/p&gt;
&lt;p&gt;A whole new world of books. Yay!&amp;nbsp;:)&lt;/p&gt;</summary></entry><entry><title>E-mail-disclaimer-virus parody</title><link href="https://ibofobi.dk/blog/archive/2006/02/e-mail-disclaimer-virus-parody/" rel="alternate"></link><updated>2006-02-25T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2006-02-25:blog/archive/2006/02/e-mail-disclaimer-virus-parody/</id><summary type="html">&lt;p&gt;Noticed this gem in Carlo &lt;span class="caps"&gt;C8E&lt;/span&gt; Miron&amp;#8217;s&amp;nbsp;signature:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Disclaimer:
If I receive a message from you, you are agreeing that:
1. I am by definition, &amp;#8220;the intended recipient&amp;#8221;.
2. All information in the email is mine to do with as I see fit and
 make such financial profit, political mileage, or good joke as it
 lends itself to. In particular, I may quote it on &lt;span class="caps"&gt;USENET&lt;/span&gt; or the &lt;span class="caps"&gt;WWW&lt;/span&gt;.
3. I may take the contents as representing the views of your company.
4. This overrides any disclaimer or statement of confidentiality that
 may be included on your&amp;nbsp;message.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That very nicely sums up how I feel about the e-mail-disclaimer virus, which
seem to have infected a large number of&amp;nbsp;work-computers.&lt;/p&gt;</summary></entry><entry><title>Meaningful Relational Sex?!</title><link href="https://ibofobi.dk/blog/archive/2006/02/meaningful-relational-sex/" rel="alternate"></link><updated>2006-02-23T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2006-02-23:blog/archive/2006/02/meaningful-relational-sex/</id><summary type="html">&lt;p&gt;From the comments to &lt;a href="http://lesscode.org/2005/09/29/should-database-manage-the-meaning/#comment-523"&gt;Should Database Manage The
Meaning?&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To the extent that relational databases are like sex, I agree that the use of bicycle
helmets is generally&amp;nbsp;advisable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&amp;#8217;s priceless&amp;nbsp;:)&lt;/p&gt;</summary></entry><entry><title>Joel is crotchety, but has a point</title><link href="https://ibofobi.dk/blog/archive/2006/01/joel-is-crotchety-but-has-a-point/" rel="alternate"></link><updated>2006-01-03T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2006-01-03:blog/archive/2006/01/joel-is-crotchety-but-has-a-point/</id><summary type="html">&lt;p&gt;From &lt;a href="http://www.nedbatchelder.com/blog/20060101T073856.html"&gt;Joel Spolsky is a crotchety old man&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why does Joel pick out pointers and recursion as the two gatekeeper concepts? Because he found them&amp;nbsp;difficult?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my experience (from helping fellow comp. sci. students) understanding
pointers and recursion requires a level of abstraction beyond most people. Also,
those who do understand these concepts, can pretty easily spot those who
do&amp;nbsp;not. &lt;/p&gt;
&lt;p&gt;So, weeding out those who do not understand pointers and recursion, is
a cheap and good enough first step in selecting the best&amp;nbsp;programmers.&lt;/p&gt;</summary></entry><entry><title>XHTML-as-HTML middleware updated</title><link href="https://ibofobi.dk/blog/archive/2005/11/xhtml-as-html-middleware-updated/" rel="alternate"></link><updated>2005-11-19T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2005-11-19:blog/archive/2005/11/xhtml-as-html-middleware-updated/</id><summary type="html">&lt;p&gt;I&amp;#8217;ve updated &lt;a href="http://code.ibofobi.dk/public/wiki/XHTMLAsHTMLMiddleware"&gt;XHTMLAsHTMLMiddleware&lt;/a&gt;
to turn response content into &lt;span class="caps"&gt;HTML&lt;/span&gt; 4.01 Strict, instead of just munging
the Content-Type header. This should work better with software which expects
the quirks of &lt;span class="caps"&gt;HTML&lt;/span&gt;, such as &lt;code&gt;&amp;lt;br&amp;gt;&lt;/code&gt; elements which have no&amp;nbsp;end-tag.&lt;/p&gt;</summary></entry><entry><title>Django doctest framework</title><link href="https://ibofobi.dk/blog/archive/2005/11/django-doctest-framework/" rel="alternate"></link><updated>2005-11-08T00:00:00+01:00</updated><author><name>Sune Kirkeby</name></author><id>tag:https://ibofobi.dk,2005-11-08:blog/archive/2005/11/django-doctest-framework/</id><summary type="html">&lt;p&gt;Inspired by Hugo&amp;#8217;s post &lt;a href="http://hugo.muensterland.org/2005/10/31/a-test-framework-for-django/"&gt;A Test Framework for Django&lt;/a&gt; and
his &lt;a href="https://simon.bofh.ms/cgi-bin/trac-django-projects.cgi/wiki/DjangoTesting"&gt;DjangoTesting&lt;/a&gt; framework I wrote &lt;code&gt;ibofobi.utils.test&lt;/code&gt;. Another Django test-framework which provides the same features plus request/response testing also, but in a different way that I like&amp;nbsp;better.&lt;/p&gt;
&lt;p&gt;The big differences are that I built it on top of doctest instead of unittest and the fixtures are written in &lt;span class="caps"&gt;YAML&lt;/span&gt; not Python code. I think doctest is a lot nicer to work with than the Java&amp;#8217;ish unittest module; and &lt;span class="caps"&gt;YAML&lt;/span&gt; is good for simple data-structures such as the fixtures. Also, I implemented simple request/response tests on top of &lt;a href="http://www.crummy.com/software/BeautifulSoup/"&gt;Beautiful Soup&lt;/a&gt;, which is so cool I almost cannot belive it :). Also, the tests are run in an in-memory sqlite database, inspired by Ian Maurer&amp;#8217;s &lt;a href="http://itmaurer.com/blog/?p=2"&gt;Django Unit Testing&lt;/a&gt;&amp;nbsp;post.&lt;/p&gt;
&lt;p&gt;To test an application you first create a &lt;code&gt;fixtures&lt;/code&gt; directory and put your fixtures in there as &lt;code&gt;*.yml&lt;/code&gt;, for example in &lt;code&gt;ibofobi/apps/blog/fixtures/blog.yml&lt;/code&gt; I&amp;nbsp;have:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;hello_world&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Hello&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
        &lt;span class="n"&gt;slug&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;world&lt;/span&gt;
        &lt;span class="n"&gt;posted&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1979&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;00.0&lt;/span&gt;
        &lt;span class="n"&gt;listed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="n"&gt;lot&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;go&lt;/span&gt; &lt;span class="n"&gt;here&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The fixtures are grouped by model-name and each fixture has a name, which you can use in the doctests to refer to the database-object. When you have some fixtures you create a &lt;code&gt;tests&lt;/code&gt; module for your doctests, so in &lt;code&gt;ibofobi/apps/blog/tests/__init__.py&lt;/code&gt; I&amp;nbsp;have:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&amp;quot;&amp;quot;&amp;quot;
&amp;gt;&amp;gt;&amp;gt; hello_world.title
&amp;#39;Hello, World!&amp;#39;
&amp;quot;&amp;quot;&amp;quot;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This asserts that the title of the post created from the fixture &lt;code&gt;hello_world&lt;/code&gt; has the expected title. Now, I want to test that the month-archive view works, so I also have this in the&amp;nbsp;tests-module:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;&amp;quot;&amp;quot;&amp;quot;
&amp;gt;&amp;gt;&amp;gt; browser.go(&amp;#39;/archive/1979/07/&amp;#39;)
&amp;gt;&amp;gt;&amp;gt; browser.soup.li.a.string
&amp;#39;Hello, World!&amp;#39;
&amp;quot;&amp;quot;&amp;quot;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;browser&lt;/code&gt; object is a helper which invokes the Django handler and parses
the result with &lt;code&gt;BeautifulSoup&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you want to try &lt;code&gt;ibofobi.utils.test&lt;/code&gt; get it&amp;nbsp;with:&lt;/p&gt;
&lt;div class="codehilite"&gt;&lt;pre&gt;git clone http://mel.ibofobi.dk/~sune/r/ibofobi.git
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And run the &lt;code&gt;django-test&lt;/code&gt; script, which will run tests in each application in 
&lt;code&gt;INSTALLED_APPS&lt;/code&gt;. Both &lt;code&gt;PyYAML&lt;/code&gt; and &lt;code&gt;BeautifulSoup&lt;/code&gt; are bundled, so you don&amp;#8217;t have to install the&amp;nbsp;separately.&lt;/p&gt;
&lt;p&gt;Alas, the tests are always run in an in-memory sqlite database, so you will need sqlite working for Django. I will fix this wart so the tests can be run with other database-backends
in one-shot databases like with &lt;code&gt;django/tests/runtests.py&lt;/code&gt;.&lt;/p&gt;</summary></entry></feed>