Gibt es sowas wie RSpec für Python?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Gibt es sowas wie RSpec für Python?

Beitragvon sma » Samstag 24. November 2007, 11:48

Ich finde die Idee von RSpec sehr interessant. Gibt es etwas vergleichbares in Python? Kann man etwas vergleichbares bauen?

RSpec kann Anforderungen derart in einer auf Ruby aufgebauten domain-spezifischen Sprache formulieren, dass es sich fast wie englisch liest, aber als Unit-Test ausgeführt werden können. RSpec kann "Examples" mittels "describe" und "it" beschreiben, "Expectations" mittels "should" definieren und mit Mocks und Stubs nicht für die Tests relevante Teile ersetzen.

RSpec fügt dazu der Ruby-Klasse "Object" einige Methoden hinzu. Hier sehe ich bei Python ein Problem. Ich finde (als relativer Python-Neuling) keinen Weg, "object" um weitere Methoden zu erweitern. Auch finde ich keine Syntax, die nicht umständlich unbeholfen aussieht.

Code: Alles auswählen

describe Account, " when first created" do
  before do
    @account = Account.new
  end

  it "should have a balance of $0" do
    @account.balance.should == 0
  end
end


Code: Alles auswählen

class Account_when_first_created(Spec):
  what = Account
  when = "first created"

  def before(self):
    self.account = Account()

  @it("should have a balance of $0")
  def example(self):
    should(self.account.balance) == 0


Ich komme an die Attribute einer Klasse heran, daher ist dies ein guter Container für die "it"-Methoden. Mich stört, dass ich im Klassennamen - um ihn eindeutig zu machen - die Beschreibung wiederholen muss.

Meine Hoffnung ist, dass ich als hier "example" getauften Methoden (warum kennt Python keine anonymen Funktionen oder Methoden - das wäre nett hier) mit dem selben Namen versehen kann und in "it" dafür sorgen kann, dass sie besondere interne Namen bekommen.

Leider scheint Python nicht zu erlauben, dass ich diesen Trick auch für Klassen benutzen kann. @-Attribute für Klassen sind kein Sprachbestandteil.

Das "should" ist mein hilfloser Versuch, damit klar zu kommen, dass ich nicht einfach eine neue Methode für "object" definieren kann. Es muss eine globale Funktion sein, die man jetzt explizit importieren muss.

Eine andere Idee, die ich hatte ist, nach dem "before" einfach alles, was dann in __dict__ steht - also alle Exemplarvariablen - mit so einer Methode zu versehen:

Code: Alles auswählen

class Should:
  def should(self): ...
...
for v in self.__dict__.values():
  if is_real_object(v): v.should = Should.should

Theoretisch müsste ich "Should" doch auch als Mixin hinzufügen können, doch das wollte mir - jedenfalls zusammen mit Django-Modellen - nicht gelingen.

Stefan
BlackJack

Beitragvon BlackJack » Samstag 24. November 2007, 13:32

Mir ist nichts vergleichbares bekannt und ich denke man kann es auch nicht so einfach nachbauen. Python eignet sich nur sehr eingeschränkt für DSLs die das "Aussehen" von Python-Quelltexten ändern und das ist auch so gewollt. Was Du da vorhast geht IMHO also gegen die Sprachphilosophie. Gegen die Sprache zu programmieren ist nie eine gute Idee.

Warum man das unbedingt "wie englisch" lesen können muss ist mir sowieso nicht so ganz klar. Nettes Gimmick aber verzichtbar.

Python kennt anonyme Funktionen (``lambda``), allerdings sind die auf Ausdrücke beschränkt und dürfen keine Anweisungen enthalten.

Dein `should()` kann man im Grunde mit ``assert`` ausdrücken.

Wenn die Tests "Prosa" enthalten sollen, kann man `doctest` verwenden. Damit kann man auch beliebige Textdokumente verarbeiten, die Text und Doctests enthalten.

Code: Alles auswählen

>>> from forum import Account

An Account should have a balance of 0€ when first created.

>>> account = Account()
>>> account.balance
0


Ansonsten gibt's halt Unit-Tests mit dem `unittest`-Modul oder `py.test` oder `nose`. Mit `py.test` würde das Äquivalent so aussehen:

Code: Alles auswählen

class TestAccount(object):
    def setup_method(self, method):
        self.account = Account()
   
    def test_new_account_balance(self):
        assert self.account.balance == 0


Wobei ich für diesen einfachen Test wohl eher zu einer simplen Funktion tendieren würde:

Code: Alles auswählen

def test_new_account_balance():
    assert Account().balance == 0
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 24. November 2007, 13:56

Dekoratoren für Klassen (@) sind ab Python 3 verfügbar. Auf RSpec hat mich mitsuhiko aufmerksam gemacht, allerdings stehe ich dem auch etwas kritisch gegenüber. Ich finde den Code nicht sonderlich leicht zu lesen. Als Gimmick cool - für den produktiven Einsatz würde ich mir so etwas stark überlegen müssen.

Und das diverse Klassenfeatures mit Django-Models nicht funktionieren ist bekannt. Man kann Django-Models seit `magic-removal` nicht einmal mehr simpel vererben.

Wenn du dir ansehen willst, was man mit Python so "magisches" machen kann, dann solltest du dir vielleicht mitsuhikos Blog ansehen oder PJEs PEAK angucken. PJE hat einige Recht interessante Codes geschrieben, deren Sinn sich mir zwar nicht immer ganz erschlossen hat, aber die dennoch einen durchaus interessanten Ansatz gehen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 24. November 2007, 21:05

Leonidas hat geschrieben:Dekoratoren für Klassen (@) sind ab Python 3 verfügbar.

Update: Gibt es mittels DecoratorTools mit einer etwas anderen Syntax auch für Python 2. Ist natürlich von PJE geschrieben :D
My god, it's full of CARs! | Leonidasvoice vs Modvoice
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Sonntag 25. November 2007, 16:06

BlackJack hat geschrieben:Warum man das unbedingt "wie englisch" lesen können muss ist mir sowieso nicht so ganz klar. Nettes Gimmick aber verzichtbar.

Kannst du dich noch an den TDD Thread erinnern und an meine Aussage?
http://www.python-forum.de/post-79502.html#79502

RSpec ist eines der Überlegungen unter Ruby zu dem Thema und IMO nicht schlecht und keineswegs ein nettes Gimmick.

BlackJack hat geschrieben:Python kennt anonyme Funktionen (``lambda``), allerdings sind die auf Ausdrücke beschränkt und dürfen keine Anweisungen enthalten.

Dein `should()` kann man im Grunde mit ``assert`` ausdrücken.

Wenn die Tests "Prosa" enthalten sollen, kann man `doctest` verwenden. Damit kann man auch beliebige Textdokumente verarbeiten, die Text und Doctests enthalten.

Code: Alles auswählen

>>> from forum import Account

An Account should have a balance of 0€ when first created.

>>> account = Account()
>>> account.balance
0
Ja, wobei diese art der Verfassung einer Ausführbaren Spezifikation ein wenig eingeschränkt ist. Das interessante ist (Wenn gut geschrieben), das man daraus eine Formale Spezifikation generieren kann. Mit `doctest` ist das vergleichsweise mühselig alle Textstellen zu extrahieren und auch den richtigen Bereichen zuzuordnen. -- Man müsste sich eigentlich wenn, dann ein neues UnitTest Framework bauen, das die Überlegungen von RSPec auf pythonische Weise umsetzt...`doctest` ist IMO keine äquivalent dazu.

BlackJack hat geschrieben:Ansonsten gibt's halt Unit-Tests mit dem `unittest`-Modul oder `py.test` oder `nose`. Mit `py.test` würde das Äquivalent so aussehen:

[...]

Wobei ich für diesen einfachen Test wohl eher zu einer simplen Funktion tendieren würde:

Code: Alles auswählen

def test_new_account_balance():
    assert Account().balance == 0
Jupp, meine ansatzt ist mit `py.test` so wie dein letzter, bloss das ich da noch docstrings mit der Sepzifikatin schreibe und mit ein par geschriebenen Tools dann daraus eine formale generieren kann. Natürlich ist dem grenzen gesetzt, da ich
folgendes nicht geht:

Code: Alles auswählen

def test_ddl():
    """Allgemein""" # docstring

    # Läst sich nicht zur Laufzeit extrahieren, man muss dan doch wider
    # ein parser schreiben der das ganze aus den unit test saugt. :/
    """sub test 1"""
    for i in ....

    """sub test 2""" # siehe oben
    do() ....

Hm, klar könnte man alles in den docstring unterbringen, aber das schöne an RSpec ist ja gerade, das die einzelnen Sätze näher an dem Code gebunden werden und für mehr übersicht sorgen ;) Kannst du mir soweit folgen? Sonst schiebe ich ein richtiges Beispiel nach.

Leonidas hat geschrieben:Auf RSpec hat mich mitsuhiko aufmerksam gemacht, allerdings stehe ich dem auch etwas kritisch gegenüber. Ich finde den Code nicht sonderlich leicht zu lesen.

Was ist daran unleserlicher als sonstiger Ruby code?! Kann es sein das du noch nicht viel mit Ruby gemacht hast?

Leonidas hat geschrieben:Als Gimmick cool - für den produktiven Einsatz würde ich mir so etwas stark überlegen müssen.
Dir ist schon klar, das RSpec für das schrieben von unit tests gedacht ist, die da aber halt als Ausführbare Spezifikationen bezeichnet werden?

Leonidas hat geschrieben:Und das diverse Klassenfeatures mit Django-Models nicht funktionieren ist bekannt. Man kann Django-Models seit `magic-removal` nicht einmal mehr simpel vererben.
Was hat der Topic mit Django zu tun?


Da sei den interessierten noch folgender Link nahe gelegt. Wie ihr sieht wurde das Thema auch im Rubyforum recht Kontrovers diskutiert.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Sonntag 25. November 2007, 16:28

poker hat geschrieben:
Leonidas hat geschrieben:Auf RSpec hat mich mitsuhiko aufmerksam gemacht, allerdings stehe ich dem auch etwas kritisch gegenüber. Ich finde den Code nicht sonderlich leicht zu lesen.

Was ist daran unleserlicher als sonstiger Ruby code?! Kann es sein das du noch nicht viel mit Ruby gemacht hast?

Ich habe durchaus einige Dinge mit Ruby gemacht und dort auch die Erfahrung gemacht, dass man mehr darüber nachdenken muss was ein Code macht. RSpec letzt da meines Erachtens aber noch einen drauf.

poker hat geschrieben:
Leonidas hat geschrieben:Als Gimmick cool - für den produktiven Einsatz würde ich mir so etwas stark überlegen müssen.
Dir ist schon klar, das RSpec für das schrieben von unit tests gedacht ist, die da aber halt als Ausführbare Spezifikationen bezeichnet werden?

Als ausführbare Spezifikation finde ich Doctests einfacher verständlich.

poker hat geschrieben:
Leonidas hat geschrieben:Und das diverse Klassenfeatures mit Django-Models nicht funktionieren ist bekannt. Man kann Django-Models seit `magic-removal` nicht einmal mehr simpel vererben.
Was hat der Topic mit Django zu tun?

poker, liest du überhaupt das worauf ich antworte oder unterstellst du mir einfach immer das ich das Thema verfehle?

sma hat geschrieben:Theoretisch müsste ich "Should" doch auch als Mixin hinzufügen können, doch das wollte mir - jedenfalls zusammen mit Django-Modellen - nicht gelingen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
poker
User
Beiträge: 146
Registriert: Donnerstag 20. September 2007, 21:44

Beitragvon poker » Sonntag 25. November 2007, 16:45

Leonidas hat geschrieben:
poker hat geschrieben:
Leonidas hat geschrieben:Auf RSpec hat mich mitsuhiko aufmerksam gemacht, allerdings stehe ich dem auch etwas kritisch gegenüber. Ich finde den Code nicht sonderlich leicht zu lesen.

Was ist daran unleserlicher als sonstiger Ruby code?! Kann es sein das du noch nicht viel mit Ruby gemacht hast?

Ich habe durchaus einige Dinge mit Ruby gemacht und dort auch die Erfahrung gemacht, dass man mehr darüber nachdenken muss was ein Code macht. RSpec letzt da meines Erachtens aber noch einen drauf.
Ansichtssache und eine frage der persönliche Präferenz und Anlage.

Leonidas hat geschrieben:
poker hat geschrieben:
Leonidas hat geschrieben:Als Gimmick cool - für den produktiven Einsatz würde ich mir so etwas stark überlegen müssen.
Dir ist schon klar, das RSpec für das schrieben von unit tests gedacht ist, die da aber halt als Ausführbare Spezifikationen bezeichnet werden?

Als ausführbare Spezifikation finde ich Doctests einfacher verständlich.
[/quote]Aber eingeschränkter. Leis dir nochmal die antworten von mir auf BlackJack's aussage durch.

Leonidas hat geschrieben:
poker hat geschrieben:
Leonidas hat geschrieben:Und das diverse Klassenfeatures mit Django-Models nicht funktionieren ist bekannt. Man kann Django-Models seit `magic-removal` nicht einmal mehr simpel vererben.
Was hat der Topic mit Django zu tun?

poker, liest du überhaupt das worauf ich antworte oder unterstellst du mir einfach immer das ich das Thema verfehle?
Ja ich lese worauf du antwortest und zweitens war das nicht als Unterstellung gemeint. Auch sollte das kein versteckter Angriff gegen deine Person sein, falls **du** das mit deiner kryptischen Frage meinst :roll:

Was mich auch wundert ist dass gerade **du** jetzt pampig wirst und dich angegriffen fühlst. Und dann möchte ich gerne jetzt von dir wissen wo ich dir **immer** etwas unterstelle. Bin ich hier im Kindergarten gelandet? :roll:

Also nochmal, in wiefern hat deine Ausführung von Django mit dem Topic zu tun? Vielleicht habe ich ja was nicht verstanden? Ist doch ein normale, höffliche und einfache Frage :) BTW: Den quote von sma habe ich gesehen. Frage bleibt nach wie vor offen.

/edit typos
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Sonntag 25. November 2007, 17:15

poker hat geschrieben:Ansichtssache und eine frage der persönliche Präferenz und Anlage.

Was für Python und Ruby ebenfalls gilt. Einige finden Ruby Code einfach zu lesen, doch kann man damit auch recht simpel Code konstruieren, der sich anders verhält als man es erwarten würde. Da war erst letztens eine Umfrage zu dem Thema von WoNaDo im Ruby-Forum.
Python kann man nicht so weit hacken wie Ruby, das steht außer Frage, aber das ist auch Absicht.

poker hat geschrieben:
Leonidas hat geschrieben:
poker hat geschrieben:
Leonidas hat geschrieben:Als Gimmick cool - für den produktiven Einsatz würde ich mir so etwas stark überlegen müssen.
Dir ist schon klar, das RSpec für das schrieben von unit tests gedacht ist, die da aber halt als Ausführbare Spezifikationen bezeichnet werden?

Als ausführbare Spezifikation finde ich Doctests einfacher verständlich.
Aber eingeschränkter. Leis dir nochmal die antworten von mir auf BlackJack's aussage durch.

Gut, du kannst dir eine formale Spezifikation generieren lassen. Ist nett, aber kaum ein Killerkriterium. Wobei, wenn du ein Unit-Testing-Framework schreibst, das ein "pythonisches" RSpec ist, wäre ich interessiert mir das anzusehen. Aber ohne Implementation ist die ganze Diskussion recht unergiebig. Jeder fährt sein Unit-Test-Framework auf, bewirft die anderen mit Argumenten, warum das des anderen nichts taugt und dabei bleibt es dann.

poker hat geschrieben:Ja ich lese worauf du antwortest und zweitens war das nicht als Unterstellung gemeint. Auch sollte das kein versteckter Angriff gegen deine Person sein, falls **du** das mit deiner Kryptischen Frage meinst :roll:

Ich frage mich, ob meine Posts so unverständlich sind, dass du den Bezug nicht finden kannst. Die "kryptische Frage" war dazu da, um mich zu versichern, ob du überhaupt den Kontext meiner Antwort mitbekommen hast. Scheint wohl der Fall gewesen zu sein, daher bin ich nun umso erstaunter, wo das Problem ist die Aussage von sma mit meiner Antwort zu kombinieren.

poker hat geschrieben:Was mich auch wundert ist dass gerade **du** jetzt pampig wirst und dich angegriffen fühlst! Und dann möchte ich gerne jetzt von dir wissen wo ich dir **immer** etwas unterstelle.

In dem letzten Thread hast du auch meinen, konstruktiv gemeinten Einwand zum Thema Pyrex und Cython gemeint, dass es nicht zum Thema passt. In diesem Thread meinst du hingegen, dass meine Antwort auf eine Aussage von sma nicht zum Thema passt. Hier zeichnet sich ein Muster ab. Entweder antworte ich immer totalen, abwegigen, zusammenhangslosen Quatsch ohne es bisher gemerkt zu haben oder du bist überempfindlich was das Thema der Threads angeht.

poker hat geschrieben:Also nochmal, in wiefern hat deine Ausführung von Django mit dem Topic zu tun? Vielleicht habe ich ja was nicht verstanden? Ist doch ein Normale, höffliche und einfache Frage :) BTW: Den quote von sma habe ich gesehen. Frage bleibt.

Gut, gehen wir nochmal von der Anfangsposition aus:
sma hat geschrieben:Theoretisch müsste ich "Should" doch auch als Mixin hinzufügen können, doch das wollte mir - jedenfalls zusammen mit Django-Modellen - nicht gelingen.

Daraufhin habe ich gemeint, dass Versuche mit Django-Models nichts bringen, da sich die Klassen die von den Django-Models abgeleitet sind seit dem `magic-removal`-Merge nicht mehr wie normale Klassen verhalten. Unter anderem ist die Vererbung mitunter problematisch, daher wird der Versuch Mix-ins mit Django zu verwenden eher wenig aussichtsreich sein. So etwas mit "normalen" Klassen zu versuchen würde vermutlich eher zum Erfolg führen (so weit es natürlich mit Python möglich ist, versteht sich).
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Beitragvon mitsuhiko » Sonntag 25. November 2007, 17:36

Halten wir fest: RSpec geht in Python nicht und py.test geht in Ruby nicht. So what?
TUFKAB – the user formerly known as blackbird
BlackJack

Beitragvon BlackJack » Sonntag 25. November 2007, 17:38

@poker: Ich habe wohl RSpec falsch gesehen. Ich dachte das sei dazu da um Unit-Tests zu schreiben, aber der Name sagt ja eigentlich schon was anderes. Es fühlt sich aber irgendwie falsch und verkehrtherum an und lädt dazu ein, dass man am Ende doch Unit-Tests damit schreibt und im Nachhinein eine Spezifikation daraus generieren lässt, und auf wundersame Weise das Programm immer der Spezifikation entspricht. ;-)

Was genau findest Du an `doctest` für die Spezifikation eingeschränkt? Man hat da doch die Freiheit wirklich *alles* zu schreiben was man mag. So formal oder umgangssprachlich wie man möchte und mit Tests versehen. Und was meinst Du mit "extrahieren und den richtigen Bereichen zuordnen"!?
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Sonntag 25. November 2007, 17:46

Leonidas hat geschrieben:Entweder antworte ich immer totalen, abwegigen, zusammenhangslosen Quatsch ohne es bisher gemerkt zu haben oder ...


Jetzt is es raus. Und wir haben gedacht, wenn wir es dir ganz unauffällig und schonend beibringen...
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
BlackJack

Beitragvon BlackJack » Sonntag 25. November 2007, 18:14

Hast Du da einen Smiley vergessen, glaubst Du die werden sowieso ignoriert, oder suchst Du Streit!? :P
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Beitragvon birkenfeld » Sonntag 25. November 2007, 18:21

Ich setze darauf, dass auch heutzutage noch zumindest manche Leute Ironie ohne plakativen Smiley erkennen.
Wenn er möchte, kann sich Leonidas ja beim nächsten Usertreffen mit mir schlagen...
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Sonntag 2. Dezember 2007, 15:21

Leute,

danke für die Antworten.

Das "wie englisch lesen" ist der entscheidende Vorteil gegenüber unit tests, wenn man den Urhebern der Idee des Behavior Driven Developments glauben schenkt. Allgemein gilt ja, kenne ich den wahren Namen von etwas, habe ich Macht darüber ;)

Doctests als "der Python-Weg" sind eine interessante Alternative und ich finde es spannend, diese Dinge kennen zu lernen, um tiefer in die Philosophie der Sprache einsteigen. Ich glaube allerdings nicht, dass ich einem Kunden einen Ausdruck mit doctests vorlegen kann, sie mischen doch zu stark den Programmcode und die Erklärungen (poker meinte das selbe). Auch

Code: Alles auswählen

def test_new_account_balance():
    assert Account().balance == 0

ist nichts, was ich eine für Nicht-Programmier lesbare Spezifikataion nennen würde. Die Aussage

Code: Alles auswählen

Account, when first created
  - should have a balance of $0

hingegen klingt gut und kann von jedem verstanden werden.

Bei der entbrannten Diskussion meine ich zu erkennen, dass zu sehe auf die Implementation der Tests geschaut wird. Dies ist aber eigentlich zu low-level und man tut sich keinen Gefallen beim Erfassen von Anforderungen, bereits immer mit einer Gehirnhälfte zu überlegen, wie man das wohl implementieren sollte. Daher ist es IMHO nicht gut, hier direkt unit-tests schreiben zu wollen.

Aber darüber will ich eigentlich gar nicht streiten.

Nehmen wir einmal an, die Idee ist gut und soll in Python realisiert werden. Ich wollte dafür den Weg einer inneren DSL wie in Ruby gehen. Doch ich habe wohl den Aufwand für eine externe DSL überschätzt, denn das scheint mir der wesentlich bessere Weg zu sein.

Hier nochmal mein Beispiel (als externe DSL, die IMHO wie Python aussieht):

Code: Alles auswählen

describe Account, "when first created":

    before:
        self.account = Account()

    it "should have a balance of $0":
        assert self.account.balance == 0

Ich habe 4 neue Schlüsselwörter `describe`, `it`, `before` und `after`. Der Rest ist Python. Es war nicht schwer, `python.vim` anzupassen, auch diese hervorzuheben. Die Funktion, die obiges in ausführbares Python verwandelt, ist gerade mal 25 Zeilen lang. Leider tue ich mich damit schwer, die Zeilennummern beizubehalten. Aus der ersten Zeile mache ich z.B.

Code: Alles auswählen

class Describe_Account_when_first_created_0(Behavior):

um dann später davon ein Exemplar zu erzeugen und die Zusicherungen, die zu Methoden werden, auszuführen.

Mein erster Ansatz, etwas wie "Account, when first created" zu einem doc-String zu machen, war nicht gut, weil das eine weitere Zeile erzeugte und dann tracebacks von fehlgeschlagenen Tests in die Irre führen. Daher muss ich mir wohl den Klassennamen und den String merken und dann ganz am Ende der übersetzten Datei folgendes generieren:

Code: Alles auswählen

Describe_Account_when_first_created_0.__doc__ = "Account, when first created"

Bei den Methoden hatte ich probiert, ihren `__name__` zu überschreiben, doch das wird leider nicht für den traceback benutzt.

Ein anderer Ansatz, den ich nochmal ausprobieren wollte ich, im Methoden bzw. Klassennamen ganz hinten nicht eine laufende Nummer (zum Eindeutigmachen) anzuhängen, sondern die ursprüngliche Zeilennummer. Dann könnte ich die original-tracebacks nochmal parsen und dort die Zeilennummern korrigieren. Außerdem könnte dann wieder die ursprünglichen it-Strings benutzen, und nicht meine etwas kryptischeren validen Namen.

Jetzt muss ich nur noch das `should`-Problem lösen. Einfach

Code: Alles auswählen

line.sub(r'(.*?)\.(should(_not)?)\.)',
  lambda m: return '%s(%s).' % (m.group(2), m.group(1)))

benutzen wirkt auf mich doch fahrlässig ;)

Stefan
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Sonntag 9. Dezember 2007, 18:23

Note to self: Specipy ist ein von JSSpec inspiriertes BDD-Rahmenwerk für Python.

Stefan (der gerne mit sich selbst redet ;)

Wer ist online?

Mitglieder in diesem Forum: brainstir