Django testrunner
Det är nu dags att introducera den nörd som bor inom mig och hur kan man på bättre sätt göra det än att dela med sig av sin senaste kod-snutt?
På sistone har jag suttit och pillat en hel del med NoSQL-databaser och fastnat för mongodb. Jag ska inte gå in djupare på fenomenet utan istället fokusera på detta inlägg.
Problemet jag stötte på igår när jag började min migration från postgresql till mongodb för denna blogg som du för tillfället läser, stötte jag på ett problem med mina tester i Django. Det visade sig efter lite funderingar att django inte initialiserade en mongodb testdatabas utan en sqlite3-databas som helt enkelt lät mina test passera (när de inte skulle).
För att ta mig runt problemet blev jag tvungen att modifiera django's standard testrunner en aning och följande är vad jag åstadkom.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from django.test.simple import DjangoTestSuiteRunner from django.test import TransactionTestCase from mongoengine import connect class TestRunner(DjangoTestSuiteRunner): def setup_databases(self, **kwangs): db_name = 'testsuite' connect(db_name) print 'Creating test-database: ' + db_name return db_name def teardown_databases(self, db_name, **kwargs): from pymongo import Connection conn = Connection() conn.drop_database(db_name) print 'Dropping test-database: ' + db_name class TestCase(TransactionTestCase): def _fixture_setup(self): pass |
En förklaring
Till att börja med importerar jag DjangoTestSuiteRunner som TestRunner ärver av där databas-setupen skrivs över för att skapa oss en mongodb test-databas via setup_databases samt att ta bort databasen när testet är slutgjort via teardown_databases.
Till en början trodde jag att det var vad som krävdes för att få allt att fungera men det visar sig att django.test.TestCase (som vanligtvis används vid tester) gör några extra kontroller för att se att databasen är tillgänglig. Därav ärver jag TransactionTestCase (som är den klass som TestCase ärver av) och skippar kontrollen i _fixture_setup.
Hur använder jag denna testrunner?
Till att börja med fungerar denna testrunner enbart tillsammans med mongodb och mongoengine. När du har detta installerat sparar du ner testrunnern i valfri fil och väljer att använda en custom runner i settings.py via
# Förutsätter att testrunner.py ligger i samma katalog-nivå som settings.py TEST_RUNNER = 'testrunner.TestRunner'
Ett test
1 2 3 4 5 6 7 8 | from testrunner import TestCase from models import BlogEntry class SimpleTest(TestCase): def testBlogEntry(self): be = BlogEntry(title = 'Hello world') be.save() self.failUnlessEqual(be.slug, 'hello-world') |