Blog

Besser - Automatisierte Tests in Ruby mit dem SitePrism Gem für das Page Object Model Pattern

Aktualisiert Oktober 21, 2025
5 Minuten

Capybara ist eine einfache domänenspezifische Sprache (DSL), die für eine kleine Anzahl von automatisierten Tests völlig in Ordnung ist. Wenn die Anzahl der Tests jedoch wächst, wird deren Verwaltung zu einem großen Unterfangen, denn selbst kleine Änderungen an der Benutzeroberfläche können verschiedene Tests stören.

Das SitePrism-Gem, ein Page Object Model DSL, kommt zur Rettung und kann mit Capybara verwendet werden. Dank dieses Tools können Sie die Seitenstruktur und die Elemente in Ihrer Anwendung einfach beschreiben. Mit diesem Juwel sind Ihre Tests leichter zu lesen, zu verstehen und zu pflegen. Die einfachere Wartung ist der größte Vorteil von SitePrism, da Änderungen an Seitenelementen (z.B. an id oder Klasse) nur an einer Stelle in der Seitenklasse vorgenommen werden müssen.

Ein Mittel für Ihre Probleme

SitePrism ist ein großartiges Tool, das Sie verwenden können, wenn die Anwendung, an der Sie arbeiten, die Seitenelemente nicht eindeutig identifiziert - vor allem, wenn es notwendig ist, eine Art hässliches Voodoo mit xpaths durchzuführen, die mehrere Knotenebenen umfassen.

Sie haben zum Beispiel eine einfache Tabelle ohne IDs oder CSS und möchten eine Tabellenzeile mit einem bestimmten Kunden finden.

client_row = page.find(:xpath, "(//div[enthält(text(), '#{client_name}')]/../../..)")
expect(client_row).to have_content("#{client_phone}")
expect(client_row).to have_content("#{client_balance}")

Dieser einfache Code testet, ob die Telefonnummer und das Guthaben des Kunden korrekt sind. Der Knoten für den Kundennamen muss gefunden werden und der Knoten, der drei Ebenen höher liegt, muss zurückgegeben werden, um die gesamte Zeile zu erhalten. Mit SitePrism wird derselbe Code wie folgt aussehen:

client_row = @app.clients_index.find_client_by_name(client_name)
expect(client_row.client_phone.text).to eq(client_phone)
expect(client_row.balance.text).to eq(client_balance)

Der Code direkt oben ist viel sauberer und übersichtlicher. Sie können jede Zeilenspalte genau testen, ohne auf Probleme zu stoßen. Das Auffinden von Knoten anhand ihrer Kindelemente ist so einfach wie der Vergleich des Inhalts des Kindknotens mit dem erwarteten Ergebnis im gefundenen Block. Kein xpath-Voodoo mehr! Ein weiteres gutes Beispiel ist die Schaltfläche, die anhand ihres Textes gefunden werden kann - eine kleine Änderung an der Beschriftung der Schaltfläche zwingt Sie dazu, viele Ihrer Tests zu korrigieren. Mit SitePrism werden die Schaltflächen an einer Stelle definiert. Wenn der Beschriftungstext geändert wird, müssen die Änderungen nur an einer Stelle vorgenommen werden.

Eine weitere großartige Funktion von SitePrism ermöglicht es Ihnen, Ihre Anwendung im Detail zu testen, indem Sie verschachtelte Abschnitte verwenden, z.B. eine Eingabezeile, die ein Etikett, eine Eingabe, eine Beschreibung und eine Validierungsfehlermeldung enthalten kann. Ohne SitePrism ist es schwierig, die richtigen Elemente zu testen, wenn das getestete Seitenformular mehrere Eingaben hat, die unterschiedliche Zustände haben können.

Installation

Zunächst müssen Sie in Ihrem Anwendungsprojekt ein Verzeichnis "page_objects" erstellen (z.B. im Stamm- oder spec-Verzeichnis) und innerhalb von "page_objects" die Verzeichnisse "pages" und "sections". Sie können alle Seitenobjekte in Ihrem "spec_helper" benötigen. Sie sollten auch daran denken, die Abschnittsdateien vor den Seiten einzubinden.

Dir["spec /page_objects/sections/**/*.rb",
  "spec/ page_objects /**/*.rb"].each {|f| require Rails.root.join(f)}

Seiten

Seiten beschreiben die Elemente Ihrer Anwendung. Es empfiehlt sich, die gleiche Seitenstruktur wie die Vorlagen für die Ansichten der Anwendung zu erstellen. Zum Beispiel:

Seite_Objekte
  |->  Seiten
  |->  Admins
  |->  index_page.rb
  |->  neue_seite.rb
  |->  edit_page.rb
  |->  Kunden
  |->  index_page.rb
  |->  neue_seite.rb
  |->  edit_page.rb
  |->  Startseite
  |->  index_page.rb

Klasse Definition

Um die Seitenklasse zu erstellen, fügen Sie einfach die Vererbung von SitePrism::Page hinzu.

Modul AppName
  Modul Seiten
  Modul Kunden
  Klasse Index  <  SitePrism::Seite
  set_url "clients/index.htm"

  # Seitenelemente und Methoden hier
  Ende
  Ende
  Ende
Ende

Die Seitenklasse kann ein Element, Elemente, einen Abschnitt und Abschnitte enthalten. Sie können zum Beispiel ganz einfach alle Seitenelemente zuordnen:

Abschnitt :Filter, "Formular[id='new_search']" tun
  Abschnitt :client_name, "div.search_name" do
  Element :label, "Etikett[for='search_name']"
  element :input, "input[id='search_name']"
  element :fehler, "span[class='help-block']"
  Ende
  element :search_button, "Eingabe[type='submit']"
Ende

Dieses Beispiel beschreibt Filter mit Eingaben und Schaltflächen. Der Abschnitt client_name beschreibt die Eingabezeile mit allen möglichen Elementen.

Rubriken

Abschnitte sind Klassen, die kleine Seitenelemente beschreiben, die auf mehreren Seiten dargestellt werden können. Unten finden Sie zum Beispiel den Abschnitt, der die Seitenleiste beschreibt.

Modul AppName
  Modul Abschnitte
  Modul Layouts
  Modul Geteilt
  Klasse Sidebar  <  SitePrism::Abschnitt
  element :admins, "li[id='admins']"
  element :clients, "li[id='clients']"
  Ende
  Ende
  Ende
  Ende
Ende

Sie können diesen Abschnitt dann zu den Klassen Ihrer Seite hinzufügen.

section :sidebar, AppName::Sections::Layouts::Shared::Sidebar, "#sidebar"

Es empfiehlt sich, eine Klasse zu erstellen, die Methoden enthält, die Instanzen der Objektklassen der Seite zurückgeben. Auf diese Weise vermeiden Sie, dass Sie für jede Seitenklasse, die Sie in Ihren Tests verwenden werden, Instanzen erstellen müssen.

Modul AppName
  Klasse Anwendung
  def dashboard_index
  AppName::Pages::Dashboard::IndexPage.new
  Ende
  def clients_index
  AppName::Pages::Clients::IndexPage.new
  Ende
  def clients_new
  AppName::Pages::Clients::NewPage.new
  Ende
  Ende
Ende

Ein Beispiel

Ein Beispieltest, der das Page Object Model-Muster verwendet (der die Seite lädt, Text in die Eingabe einträgt, die Ergebnisse filtert und überprüft, ob die Ergebnisse angezeigt werden), ist unten zu sehen:

Funktion 'Kundenfilter' do
  let!(:app) { AppName::Anwendung }
  Szenario 'gefilterter Client wird angezeigt'
  app.clients_index.load
  app.clients_index.filters.client_name.input.set "Ruby"
  app.clients_index.filters.search_button.click

  expect(app.clients_index.results[0].text).to eq "Ruby"
  Ende
Ende

Fazit

Aus meiner QA-Perspektive hilft mir dieses Juwel dabei, sehr detaillierte Tests zu erstellen, ohne die Lesbarkeit zu beeinträchtigen - ich kann selbst die kleinsten Aspekte testen, die mir früher Kopfschmerzen bereitet haben. Zum Beispiel kann ich jeden Validierungsfehler für die spezifische Eingabe von Seitenformularen überprüfen. Ich bin in der Lage, Within-Blöcke loszuwerden, die Tests übermäßig verkomplizieren. Und ich liebe es, dass der Code, den ich schreibe, für alle lesbar ist und nicht nur für die Entwickler und mich. SitePrism hat seine Stärke auf vielen Ebenen in dem Projekt gezeigt, an dem ich gerade arbeite. Es wurden bestimmte Änderungen an der Tabellenstruktur vorgenommen, die in wenigen Sekunden behoben waren, indem nur die Elementdefinitionen der Seite geändert wurden. Sonst nichts!

Zusammenfassung

SitePrism schafft Abhilfe für all die Änderungen an der Benutzeroberfläche, die dazu führen, dass Ihre Tests nicht mehr funktionieren. Wenn sich etwas ändert, können Sie einfach ein Seitenklassenelement mit neuen Werten aktualisieren und alle Tests werden automatisch das neue Element verwenden.

Dieser Edelstein erleichtert eines der größten Kopfschmerzen - die Wartung von Tests. Die Pflege von erstellten Tests ist viel einfacher, wenn Änderungen nur an einem Klassenelement einer Seite oder an den Definitionen eines bestimmten Abschnitts vorgenommen werden können.

Links

Contact

Let’s discuss how we can support your journey.