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!