Kontakt
#Tech | 6 min read | Updated: 4/2/2025

Sidekiq-Aufträge testen: Welchen Modus sollte ich wählen?

Updated: 4/2/2025
, Senior QA Engineer
#Tech
6 min read

Sidekiq ist ein Hintergrundjob-Prozessor, der Rails-Entwicklern hilft, die Effizienz und Reaktionsfähigkeit einer Anwendung zu erhöhen.

Das geniale Sidekiq-Gem bietet integrierte Tools zum Testen der verschiedenen Aspekte des Lebenszyklus Ihres Workers. Die wichtigste Einstellung, die Sie als Entwickler wählen können, ist der Testmodus, der bei einem bestimmten Test angewendet werden soll. Die Dokumentation beschreibt das Verhalten für beide Modi ziemlich klar. Aber abgesehen davon wäre es gut, wenn Sie wüssten, für welche Aspekte ein bestimmter Modus am besten geeignet ist.

In diesem Artikel werden wir die Verwendung von Sidekiq für die Optimierung der Rails-Anwendungsleistung betrachten. Wir haben für Sie eine kurze Anleitung zur Integration von Sidekiq in Ihr Projekt und zum Testen des Sidekiq Workers in den verschiedenen Modi vorbereitet. Dieses Material wird Ihnen helfen, jeden Testmodus zu bewerten und zu verstehen, wie Sie effektiv mit jedem von ihnen arbeiten können.

Lassen Sie uns eintauchen und versuchen, das Problem zu lösen.

Hinweis: Wir werden RSpec als Testframework verwenden.

Sidekiq in Rails-Anwendungen verwenden

Sidekiq wird für die Hintergrundverarbeitung von Aufgaben verwendet, die viel Zeit in Anspruch nehmen können. Dies erhöht die Reaktionsfähigkeit der Anwendung, so dass die Benutzer nicht auf die Fertigstellung der Arbeit warten müssen.

Dies ist sehr praktisch für die Bearbeitung komplexer Aufgaben (z. B. das Einscannen von Daten aus einem großen Dokument und deren Speicherung in der Datenbank). Wenn die Aufgaben gestartet werden, werden sie in eine Warteschlange gestellt. Wenn ein Benutzer zum Beispiel einen Brief aus einer Rails-Anwendung sendet, die Sidekiq verwendet, muss nicht auf die tatsächliche Fertigstellung der Aufgaben gewartet werden. Der Benutzer sendet den Brief, Sidekiq erhält die Aufgabe zum Senden und der Browser zeigt die Nachricht an: „Brief wird versendet“. Währenddessen sendet Sidekiq den Brief im Hintergrundmodus.

Im Folgenden werden wir mit zwei gängigen Sidekiq-Begriffen arbeiten: Job und Worker. Der Einfachheit halber wollen wir ihre Bedeutung definieren.

Ein Sidekiq-Job ist ein Vorgang, der im Hintergrund verarbeitet wird. Der Gem verwaltet die Warteschlange der Jobs in der Datenbank als JSON-Datensätze. Ein Worker ist eine Ruby-Klasse, die für die Ausführung eines Jobs verantwortlich ist. Wenn Sidekiq bereit ist, mit der Jobverarbeitung zu beginnen, wird der zuständige Worker gestartet.

So richten Sie Sidekiq für Ihr Projekt ein

Sidekiq ist sehr einfach einzurichten – es reicht aus, den Edelstein zum Gemfile hinzuzufügen und die Installation des neuen Edelsteins in der Rails Console auszuführen:

gem 'sidekiq'
bundle install

Dann geben Sie den Queue-Server in config/application.rb an und erstellen einen Task:

config.active_job.queue_adapter = :sidekiq
rails generiert Job Einige

Dadurch wird die Datei app/jobs/some_job.rb mit folgendem Inhalt erzeugt:

class SomeJob < ApplicationJob
queue_as :default


def perform(*args)
# Später etwas tun
end
end

Um mit Sidekiq zu arbeiten, müssen wir den redis-server einrichten und starten. Zum Beispiel auf Ubuntu 14.04, ist es einfach mit sudo apt-get install redis-server Befehl einzurichten. Nachdem Sie Sidekiq in der Entwicklungsumgebung gestartet haben, sind Sie nun bereit zu arbeiten.

Arten von Sidekiq-Aufträgen zum Testen

Täuschen Sie es vor, bis Sie es schaffen

Sidekiq::Testing.fake! ist der Standardtestmodus. Wenn er verwendet wird, schiebt Sidekiq alle Aufträge, die sich in der Warteschlange befinden, in das interne Array für jede Arbeiterklasse.

require "sidekiq/testing" # Sie würden dies wahrscheinlich zu Ihrer rails_helper.rb hinzufügen


expect { MyWorker.perform_async(:my_arg) }.to change { MyWorker.jobs.size }.by(1)

Ihre Aufträge werden in eine Warteschlange gestellt, aber nicht wirklich ausgeführt. Um sie auszuführen, müssen Sie die Warteschlangen leeren:

Sidekiq::Worker.drain_all

Leider bedeutet dies, dass Sie das Sidekiq::Worker.drain_all Snippet vor jedem Test in Ihrem Worker-Set von Beispielen wiederholen müssen:

beschreibe MyWorker do
er "tut etwas Nützliches" do
MyWorker.perform_async(:my_arg)
Sidekiq::Worker.drain_all
# expect(...).to ...
end


es "tut wieder etwas Nützliches" do
MyWorker.perform_async(:my_arg, :additional_arg)
Sidekiq::Worker.drain_all
# expect(...).to ...
end
end

Außerdem scheint mir die Kontrolle, die durch das Entleeren aller Warteschlangen nach jedem Beispiel ausgeübt wird, ein wenig zu unspezifisch zu sein. Wie wäre es, wenn wir jede „Worker“-Zeile wirklich ausführen könnten, ohne dass wir uns mit dem Ablassen von Warteschlangen herumschlagen müssen? Der nächste Abschnitt beschreibt den Sidekiq::Testing Modus, der genau so funktioniert.

Zusammenfassend lässt sich sagen, dass der Zweck des Fake-Modus darin besteht, das tatsächliche Verhalten der „Worker“-Leistung zu testen und zu prüfen, wie korrekt sie ausgeführt wird. Im Gegensatz dazu sollte das Testen, ob der Worker in der Warteschlange steht, nur ein Sanity Check sein und könnte in ein gemeinsames Beispiel extrahiert werden:

shared_examples "a worker with args of" do |*args|
es "wird in die Warteschlange gestellt" do
expect { described_class.perform_async(*args) }.to change { described_class.jobs.size }.by(1) }
end
end


describe MyWorker do
it_behaves_like "ein Arbeiter mit Args von", :my_arg
end

Real werden

Der Testmodus Sidekiq::Testing.inline! führt die Aufträge sofort aus, wenn sie in die Warteschlange gestellt werden. Meiner Meinung nach sollte dies der Standard-Testmodus für Sidekiq sein. Natürlich können Sie Ihre Worker auch direkt testen:

worker = MyWorker.new
worker.perform(:my_arg)

Aber dadurch werden Ihre Testaufrufe inkonsistent im Vergleich zu den Aufrufen im echten Code (perform_async).

Mit dem Sidekiq Inline-Modus als Standard wird die Logik Ihres Workers sofort getestet. Dies führt dazu, dass Sie über die Abhängigkeiten Ihrer Worker nachdenken müssen, um sie effektiv mocken zu können und sogar Erwartungen an ihre Aufrufe zu stellen.

# Implementierung
Klasse DeleteFromRemoteApiWorker
include Sidekiq::Worker

def perform(item_ids)
ApiWrapper.delete_items(item_ids) # Abhängigkeit
end
end


# test
describe DeleteFromRemoteApiWorker do
let(:items) do
# ...
end

it "delegiert die Arbeit wie erwartet an den API-Wrapper" do
allow(ApiWrapper).to receive(:delete_items)
item_ids = items.map(&:id)

described_class.perform_async(item_ids)


expect(ApiWrapper).to(
have_received(:delete_items).with(item_ids)
)
end
end

Um die Verwendung für die Fälle zu vereinfachen, in denen Sie den Fake-Modus benötigen, schlage ich vor, den folgenden Ausschnitt in Ihre rails_helper.rb einzufügen:

require "sidekiq/testing"
Sidekiq::Testing.inline!

config.around(type: :worker) do |example|
if example.metadata[:sidekiq_fake] == true
Sidekiq::Testing.fake! { example.run }
end

# und seine Verwendung
# (eigentlich ein gutes Beispiel für den Fall, dass man nur testen muss, ob der Job in der Warteschlange steht)


describe "rake my_project:my_task" do
it "fügt neuen Job zur Warteschlange hinzu", :sidekiq_fake do
task.execute # ein Teil der benutzerdefinierten Funktionalität, die die in der Beispielbeschreibung erwähnte Rake-Aufgabe ausführt
expect(MyWorker).to have_enqueued_sidekiq_job
end
end

Bonus: Lassen Sie Ihre Worker-Tests natürlicher lesen

Aber Moment mal! Was war das mit have_enqueued_sidekiq_job?

Um Sidekiq-Jobs natürlicher zu testen, empfehle ich die Verwendung des schönen rspec-sidekiq-Gems, das viele Matcher mit „sprechenden“ Namen enthält. Gehen Sie und entdecken Sie sie!

Schlussfolgerung

Nachdem Sie diesen Artikel gelesen haben, kennen Sie nun die verschiedenen Arten des Testens von Sidekiq.

Während der täglichen Testarbeit testen Sie Ihre Anwendung immer auf Unit-Ebene. Später testen Sie, wie sie mit den anderen Teilen des Programms interagiert. Schließlich testen Sie die Integration der Anwendung mit der Datenbank und den anderen Diensten. Auf diese Weise sollten Sie auch mit Sidekiq arbeiten:

  • Unit-Tests zu verwenden, um das Verhalten der Worker zu bewerten;
  • die Interaktion Ihrer Jobs zu testen, während Sie die Interaktion der verschiedenen Teile Ihrer Anwendung testen;
  • Worker inline zu testen, wenn es notwendig ist, um die Leistung des Gesamtsystems zu testen.

Viel Spaß beim Testen von Sidekiq!

How useful was this post?

Click on a star to rate it!

Average rating / 5. Vote count:

No votes so far! Be the first to rate this post.

Share:

Abonnieren
Benachrichtige mich bei
guest

0 Comments
Inline Feedbacks
View all comments
Recommended articles
#Tech 19 min

Die Auswirkungen eines einzigen Fehlers oder Bugs, der sich nach der Produktfreigabe einschleicht, können katastrophal sein. Sicher, Unternehmen investieren viel in Qualitätssicherung und Tests. Aber was können Sie sonst noch tun, um Ihr Produkt schneller…

Erweitern Sie Ihr Team
mit uns

Steigern Sie Ihr Geschäft mit unseren engagierten Entwicklern

    Alex, VP für Kundenengagement
    alex@sloboda-studio.com