Fixtures in Rails und deren Alternative

    Ich sitze noch vor nicht allzu langer Zeit auf den Schienen, habe es aber trotzdem schon geschafft, mich mit etwas auseinanderzusetzen. Eines der Themen, mit denen man sich sorgfältig auseinandersetzen musste, sind Vorrichtungen und ihre Alternativen bei Schienenversuchen.

    Ein bisschen über Fixtures

    Ein kleiner Rückblick für diejenigen, die sich nicht ganz mit dem Thema auseinandersetzen. Mit Fixtures in Rails können Sie vorbereitete Daten, die von den getesteten Objekten verwendet werden, in die Testdatenbank übertragen. Im Testcode selbst genügt der Aufruf der Methode fixtures :usersund es werden automatisch alle Daten für Objekte der Klasse User geladen. Für eine detailliertere Übersicht sollten Sie das Handbuch lesen (das übrigens kurz ist).

    Warum mögen Entwickler keine Fixtures?

    Trotz der Tatsache, dass dieses Tool Entwicklern helfen sollte, indem es ein Problem löste, schuf er mehrere andere. Hier sind die Hauptbeschwerden über Spielpaarungen, die in Blogs häufig vorkommen:
    1. Die Vorrichtungen sind für jeden Test spezifisch, stehen jedoch für jeden Test zur Verfügung. Das heißt, wenn ich in einem Test einige Daten für Benutzerobjekte benötige und in einem anderen Test bereits etwas anders ist - mit Standardgeräten ist dies nicht möglich.
    2. Wenn es nicht sehr wenige Datensätze für die Datenbank gibt, wird es für Fixtures schwieriger, solche Beziehungen von Objekten wie has_one, has_many, habtm und has_many zu modellieren: through - Sie müssen die korrekten Werte von Fremdschlüsseln verfolgen. Obwohl der Standardmechanismus eine bequeme Möglichkeit darstellt, solche Hämorrhoiden zu vermeiden (siehe unten), wird dies häufig vergessen.
    3. Geliebte. Einige Entwickler möchten klar sehen, welche Daten direkt im Testcode verwendet werden.

    Was sind die Alternativen?

    Als Alternative kann die Befestigung in erster Linie sein , Objekte direkt in den Tests zu schaffen, wie zum Beispiel: %w("Tom Bill Frank").each { |name| User.create(:first_name => name) }. Ich habe versucht, dies zu tun, aber der Nachteil hier ist, dass Sie nach jedem Test die Testbasis irgendwie manuell löschen müssen. Wenn solche Tests gleichzeitig mit Tests gestartet werden, die noch Fixtures verwenden, können Konflikte auftreten. Fixtures verwenden Transaktionen, um die Datenbank zu füllen / löschen. Daher kann es vor der Durchführung eines Fake-Tests vorkommen, dass die Datenbank nicht wirklich bereinigt wird. (Aus diesem Grund hat beispielsweise mein nicht-fiktiver Test, der alleine ausgeführt wurde, erfolgreich bestanden wurde, aber zusammen mit anderen Tests ausgeführt wurde, einen Fehler ausgegeben.)

    Die Community ging weiter und entwickelte mehrere Lösungen ( 1 , 2) Vereinfachung der Erstellung von Objekten mit Daten, die Fixtures umgehen.

    Warum ist die Verwendung von Fixtures möglicherweise praktischer?

    Stellen Sie sich vor, Sie fügen Ihrem Modell ein neues Feld hinzu und überprüfen dessen Vorhandensein. Stellen Sie sich nun vor, Sie haben 10 gefälschte Tests, in denen Objekte erstellt und mit Daten gefüllt werden. Wenn Sie all diese 10 Tests bearbeiten, wird Ihnen nicht allzu viel Spaß machen (das Problem ist übrigens sehr wichtig - genau das ist passiert, als ich das restful_authentication-Plugin in das Modell eingebaut und das Passwortfeld hinzugefügt habe). Unit-Tests für diese und Unit-Tests, die nicht länger von irgendetwas abhängen sollten und nur die Daten verwenden sollten, mit denen die Funktionalität des Modells getestet werden soll.

    Daher ist es einfacher, die am Anfang des Artikels angegebenen Mängel innerhalb der Geräte selbst zu beheben, als zu einer Lösung zu wechseln, die neue Probleme schafft. So:
    1. Das Problem der Fixture-Spezifität für jeden Test wird durch das FixtureScenarios- Plugin gelöst . In jedem Test genügt es nun anzugeben scenario :loggingund alle Fixtures werden aus dem Fixtures / Logging Verzeichnis geladen. Über den obigen Link wird im Artikel ein zusätzliches FixtureScenarioBuilder-Plugin erwähnt. Ich habe versucht, es zu verwenden, aber zu diesem Zeitpunkt gab es eindeutig einen Fehler, der dazu führte, dass alle Tests fehlschlugen. weil dynamische Erstellung einer Handvoll von Vorrichtungen in drei Reihen können direkt in den YAML-Dateien mit ERb (siehe Abschnitt. angeordnet sein Mana Befestigungen «die dynamischen Leuchten mit ERb»).
    2. Das Problem, wie man einen Haufen von Datensätzen mit Fremdschlüsseln im Auge behält, wird auf die von Fixtures bereitgestellte Standardweise gelöst: In diesem Fall wird die Datensatz-ID nicht explizit festgelegt (übrigens sehe ich keinen Grund, dies in Fixtures überhaupt zu tun), sondern wird automatisch zugewiesen. Die Schienen ersetzen auch automatisch George und Reginald mit der entsprechenden ID. Und jetzt haben wir eine Beziehung, die nur einer hat und gehört. Weitere Einzelheiten zur Verwendung dieses Ansatzes finden Sie im Handbuch im Abschnitt Erweiterte YAML-Fixtures. Dieser Ansatz ist besonders leistungsfähig und kann mit der Erstellung von Datensätzen mithilfe von ERb kombiniert werden.

      ### in pirates.yml
      reginald:
      name: Reginald the Pirate
      monkey: george

      ### in monkeys.yml
      george:
      name: George the Monkey
      pirate: reginald


    3. Das Problem der Sichtbarkeit wird meiner Meinung nach auch mit dem FixtureScenarios-Plugin gelöst. Mit benannten Skripten können Sie einmal darüber nachdenken, welche Daten für dieses Skript geladen werden, und in Zukunft nicht mehr auf dieses Problem zurückgreifen, indem Sie einfach steuern, welche Skripten im Test verwendet werden. Bei Bedarf können Sie neue Skripte hinzufügen, die übrigens verschachtelt sein können (dann werden beispielsweise zuerst Daten aus Fixtures / Logging und dann aus Fixtures / Logging / Admin geladen).

    Für Kommentare, Ergänzungen und Meinungen von Fachleuten wäre ich dankbar.

    Jetzt auch beliebt: