UnitTests auf ein TracPlugin...

written by Martin HĂ€cker on

... sind eine schöne Sache. Wenn man sie denn hinkriegt.

Da wÀre zuerst der einfache Fall: Was macht man um eine Wiki-Seite zu erzeugen und zu laden?

Well, hier ist wie es geht:

#!/usr/bin/env python

import unittest

from trac.wiki.model import WikiPage
from trac.test import EnvironmentStub

class PluginTests(unittest.TestCase):

    def test_can_save_and_load_wiki_page(self):
        env = EnvironmentStub()
        page = WikiPage(env, "Foo", None)
        page.text = "barfoo"
        page.save("fnord", "bar", "localhost")

        self.assertEquals("barfoo", WikiPage(env, "Foo", None).text)

Soweit nicht soo schwer. Vor allem sehr schick, das das EnvironmentStub() einem die ganze Arbeit abnimmt um das Trac-Environment UnitTest fÀhig zu machen. Ein Call und alles ist da - inklusive einer in-memory Sqlite Datenbank.

Nice.

Der eigentliche Hammer ist dann aber, wenn man ein Plugin bauen will das von anderen Plugins abhÀngt. Das ist nÀmlich deutlich komplizierter.

Da ergibt sich nĂ€mlich das Problem, das man plötzlich das Component-System von Trac verstehen muss, damit man ĂŒberhaupt auf die Klassen und ExtensionPoints eines anderen Plugins aufbauen kann.

FĂŒr uns um Beispiel das TracTags-Plugin. Dieser Blog basiert auf diesen Tags. Blog-Posts werden durch einen speziellen Tag ("blog") zu einem Blog-Post, Kategorien sind nur Tags und ĂŒberhaupt funktioniert alles nur ĂŒber Tags. Tags sind cool.

Aber, man muss das Plugin erst einmal schwer zur Zusammenarbeit ĂŒberreden - denn, es benötigt ein Datenbankupgrade damit es ĂŒberhaupt funktioniert.

Und ĂŒberhaupt ist die Datenbank am Anfang total leer. :/

Um es gleich zu verraten: Die Lösung lag darin, das man dem Environment einerseits sagen muss, das man gerne Standard-Daten hÀtte und andererseits, welche Plugins es alles aktivieren soll. Nicht schwer. Nur nicht offensichtlich. :(

#!/usr/bin/env python

import unittest

from trac.wiki.model import WikiPage
from trac.test import Mock, EnvironmentStub, MockPerm

from tractags.api import TagSystem

from tractags.model import TagModelProvider

class PostFinderTest(unittest.TestCase):

    def setUp(self):
        self.env = EnvironmentStub(default_data=True, enable=["tractags.*", 'trac.*'])
        self.env.upgrade()        
        self.env.db.commit()


    def test_can_save_and_load_wiki_page(self):
        page = WikiPage(self.env, "Foo", None)
        page.text = "barfoo"
        page.save("fnord", "bar", "localhost")

        self.assertEquals("barfoo", WikiPage(self.env, "Foo", None).text)


    def test_can_add_tags_and_retrieve_tagged_pages(self):
        from trac.web.href import Href
        page = WikiPage(self.env, "Foo", None)
        page.text = "barfoo"
        tag_system = TagSystem(self.env)
        req = Mock(perm=MockPerm(), args={}, href=Href('/'))
        tag_system.add_tags(req, page.resource, ["blog"])
        page.save("fnord", "bar", "localhost")

        self.assertEquals("barfoo", WikiPage(self.env, "Foo", None).text)

        blog_resources = [i for i in tag_system.query(req, "blog")]
        self.assertEquals(1, len(blog_resources))

Mei war das eine Arbeit die ganzen Objekte zusammen zu suchen die man fĂŒr test_can_add_tags_and_retrieve_tagged_pages() benötigt.

Well, ein start ist gemacht, aus dem wir jetzt einen Page-Loader refactor-n (-ieren?) werden.

Yay!