test-shiny-app
À propos
Cette compétence aide les développeurs à tester des applications Shiny en utilisant shinytest2 pour les tests d'interface utilisateur de bout en bout et testServer() pour les tests unitaires de la logique serveur. Elle couvre les tests par instantané, les tests d'interaction avec l'interface utilisateur, les tests de modules et l'intégration CI/CD. Utilisez-la pour valider le comportement de l'application, mettre en place des tests de régression ou intégrer des tests dans votre pipeline de déploiement.
Installation rapide
Claude Code
Recommandénpx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/test-shiny-appCopiez et collez cette commande dans Claude Code pour installer cette compétence
Documentation
name: test-shiny-app description: > Shiny-Anwendungen mit shinytest2 für End-to-End-Tests und testServer() für Unit-Tests der Server-Logik testen. Behandelt Snapshot-Tests, UI-Interaktionstests, Modul-Unit-Tests und CI-Integration. Verwenden, wenn Shiny-App-Verhalten validiert, Regressionstests eingerichtet oder Tests in CI/CD eingebunden werden sollen. license: MIT locale: de source_locale: en source_commit: 6f65f316 translator: claude-opus-4-6 translation_date: 2026-03-16 allowed-tools: Read Write Edit Bash Grep Glob metadata: author: Philipp Thoss version: "1.0" domain: shiny complexity: intermediate language: R tags: shiny, testing, shinytest2, testthat, ci-cd
Shiny-App testen
Shiny-Anwendungen mit shinytest2 (End-to-End) und testServer() (Unit-Tests) zuverlässig testen.
Wann verwenden
- Shiny-App-Verhalten vor dem Deployment validieren
- Regressionstests für kritische User Journeys einrichten
- Modul-Logik isoliert unit-testen
- Shiny-Tests in GitHub Actions CI einbinden
Eingaben
- Erforderlich: Laufende Shiny-App (lokal oder remote)
- Optional: Bestehende
tests/-Verzeichnisstruktur - Optional: CI-Workflow für automatische Testausführung
Vorgehensweise
Schritt 1: shinytest2 installieren
shinytest2 und seine Dependencies installieren.
install.packages("shinytest2")
# Chromium-Browser für UI-Tests installieren (benötigt Netzwerkzugriff)
shinytest2::install_chromium()
# Für CI (headless Chrome verwenden)
# Chromium wird über chromote automatisch gefunden
In bestehende Teststruktur integrieren:
# Tests-Verzeichnis einrichten (wenn noch nicht vorhanden)
usethis::use_testthat()
# shinytest2 in Testinfrastruktur integrieren
shinytest2::use_shinytest2()
Erwartet: shinytest2 installiert. tests/testthat/setup-shinytest2.R erstellt.
Bei Fehler: Wenn Chromium-Installation fehlschlägt, systemweit installierten Chrome/Chromium verwenden: shinytest2::install_chromium(force = TRUE).
Schritt 2: Ersten Snapshot-Test erstellen
shinytest2 im Record-Modus verwenden, um Test-Snapshots automatisch zu generieren.
# Aufzeichnung starten (öffnet App + Test-Recorder)
shinytest2::record_test(".")
# Alternativ: Manuell ersten Test schreiben
# tests/testthat/test-app.R
Aufgezeichnete Tests sehen aus wie:
# tests/testthat/test-app.R
library(shinytest2)
test_that("app startet und UI rendert korrekt", {
app <- AppDriver$new(
app_dir = system.file(package = "myapp"), # oder "."
name = "app-startup-test"
)
# Anfangs-Screenshot aufnehmen
app$expect_screenshot()
app$stop()
})
Erwartet: Snapshot-Bilder in tests/testthat/_snaps/ erstellt. Test läuft ohne Fehler.
Bei Fehler: Wenn App nicht startet, Konsolen-Output mit app$get_logs() prüfen. Wenn Screenshot-Vergleich fehlschlägt, Snapshots mit shinytest2::snapshot_review() aktualisieren.
Schritt 3: UI-Interaktionstests schreiben
Tests für spezifisches User-Verhalten schreiben.
# tests/testthat/test-interactions.R
library(shinytest2)
test_that("Datensatz-Auswahl aktualisiert Tabelle", {
app <- AppDriver$new(".", name = "dataset-selection")
# Initialen Zustand prüfen
initial_value <- app$get_value(output = "table")
expect_true(length(initial_value$body) > 0)
# Input ändern
app$set_inputs(dataset = "mtcars")
app$expect_values(output = "table")
app$stop()
})
test_that("Slider filtert Zeilenanzahl", {
app <- AppDriver$new(".", name = "slider-filter")
app$set_inputs(n_rows = 5)
app$click("apply")
# Wert aus Output extrahieren und prüfen
table_data <- app$get_value(output = "table")
expect_equal(nrow(table_data$body), 5)
app$stop()
})
Erwartet: Tests simulieren User-Interaktionen und prüfen Output-Änderungen.
Bei Fehler: Wenn get_value() unerwartete Struktur zurückgibt, app$get_value(output = "table") |> str() verwenden, um die tatsächliche Struktur zu untersuchen.
Schritt 4: Server-Logik unit-testen
Shiny-Server-Funktionen mit testServer() isoliert testen.
# tests/testthat/test-server.R
library(shiny)
library(testthat)
test_that("server berechnet korrekten Mittelwert", {
testServer(app_server, {
# Inputs setzen
session$setInputs(dataset = "iris", n_rows = 10)
# Output prüfen
expect_s3_class(output$table$result, "data.frame")
expect_equal(nrow(output$table$result), 10)
})
})
test_that("reactive Werte aktualisieren korrekt", {
testServer(app_server, {
session$setInputs(multiplier = 2)
# Reaktiven Wert prüfen
result <- filtered_data()
expect_true(all(result$value > 0))
})
})
Für Modul-Tests:
# tests/testthat/test-mod_data_filter.R
test_that("data filter Modul filtert korrekt", {
test_data <- reactive({ head(iris, 100) })
testServer(
mod_data_filter_server,
args = list(data = test_data),
{
session$setInputs(n_rows = 5, apply = 1)
result <- session$returned()
expect_equal(nrow(result()), 5)
}
)
})
Erwartet: Server-Logik unabhängig von UI testbar. Reaktive Berechnungen verifizierbar.
Bei Fehler: Wenn testServer() fehlschlägt mit "could not find function", sicherstellen, dass Server-Funktion exportiert oder im Paket-Namespace zugänglich ist.
Schritt 5: Edge Cases und Fehlerbehandlung testen
Randfälle und Fehlerszenarien testen.
# tests/testthat/test-edge-cases.R
test_that("app behandelt leere Eingaben korrekt", {
testServer(app_server, {
session$setInputs(dataset = NULL, n_rows = 0)
# Sicherstellen dass App nicht abstürzt
expect_silent(output$table)
})
})
test_that("app zeigt Fehlermeldung bei ungültigen Eingaben", {
app <- AppDriver$new(".", name = "error-handling")
# Ungültige Eingabe erzwingen (z. B. via URL-Parameter)
app$set_inputs(n_rows = -1)
app$click("apply")
# Fehlermeldung prüfen
error_output <- app$get_value(output = "error_message")
expect_false(is.null(error_output))
app$stop()
})
Erwartet: App behandelt edge cases ohne Absturz. Fehlermeldungen korrekt angezeigt.
Bei Fehler: Wenn Tests edge cases nicht abdecken, Fehlerbehandlung im Server mit tryCatch() oder validate(need(...)) hinzufügen.
Schritt 6: CI-Integration
Tests in GitHub Actions CI einbinden.
# .github/workflows/test-shiny.yml
name: Shiny Tests
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
- name: Install system dependencies
run: |
sudo apt-get install -y chromium-browser
- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: shinytest2, testthat
- name: Run tests
run: |
Rscript -e "testthat::test_dir('tests/testthat')"
env:
CHROMOTE_CHROME_ARGS: "--no-sandbox" # Für CI erforderlich
Erwartet: Tests in CI auf Push/PR ausgeführt. Fehlgeschlagene Tests blockieren Merge.
Bei Fehler: Wenn Chromium in CI nicht gefunden wird, CHROMOTE_CHROME_ARGS="--no-sandbox --disable-gpu" und sicherstellen, dass chromium-browser oder google-chrome installiert ist.
Validierung
- shinytest2 installiert und Chromium verfügbar
- Snapshots in
tests/testthat/_snaps/erstellt - UI-Interaktionstests simulieren echte User-Workflows
- Server-Unit-Tests via
testServer()prüfen Logik isoliert - Edge Cases und Fehlerbehandlung getestet
- Tests in CI laufen ohne Fehler
Haeufige Stolperfallen
- Nicht-deterministische Snapshots: Animationen, Timestamps oder zufällige Daten verursachen Snapshot-Instabilität.
set.seed()verwenden und dynamischen Inhalt mocken. - Chromium fehlt in CI: Immer
--no-sandbox-Flag in CI-Umgebungen setzen. GitHub Actions braucht spezielle Chromium-Konfiguration. testServer()vsAppDriver:testServer()testet Server-Logik isoliert (keine echten UI).AppDrivertestet echte Browser-Interaktionen.- Veraltete Snapshots: Nach UI-Änderungen müssen Snapshots mit
shinytest2::snapshot_review()odershinytest2::snapshot_update()aktualisiert werden. - Timing-Probleme: Asynchrone Operationen (Plots, Downloads) benötigen
app$wait_for_idle()nach auslösenden Aktionen. - Modul-Tests ohne Reaktivität:
testServer()benötigt reaktive Inputs — immersession$setInputs()vor Assertions aufrufen.
Verwandte Skills
scaffold-shiny-app— Shiny-App vor dem Testen scaffoldenbuild-shiny-module— Module erstellen, die mittestServer()getestet werdendeploy-shiny-app— Getestete App deployensetup-github-actions-ci— CI/CD-Workflows einrichten
Dépôt GitHub
Compétences associées
evaluating-llms-harness
TestsCette compétence Claude exécute le lm-evaluation-harness pour évaluer les modèles de langage sur plus de 60 tâches académiques standardisées telles que MMLU et GSM8K. Elle est conçue pour permettre aux développeurs de comparer la qualité des modèles, de suivre les progrès de l'entraînement ou de rapporter des résultats académiques. L'outil prend en charge différents backends, incluant les modèles HuggingFace et vLLM.
cloudflare-cron-triggers
TestsCette compétence fournit une connaissance complète pour la mise en œuvre de Déclencheurs Cron Cloudflare afin de planifier des Workers à l'aide d'expressions cron. Elle couvre la configuration de tâches périodiques, de travaux de maintenance et de flux de travail automatisés, tout en traitant des problèmes courants tels que les expressions cron non valides et les problèmes de fuseau horaire. Les développeurs peuvent l'utiliser pour configurer des gestionnaires planifiés, tester des déclencheurs cron et intégrer avec Workflows et Green Compute.
webapp-testing
TestsCette Compétence Claude fournit une boîte à outils basée sur Playwright pour tester des applications web locales via des scripts Python. Elle permet la vérification frontend, le débogage d'interface utilisateur, la capture d'écrans et la consultation des journaux, tout en gérant les cycles de vie du serveur. Utilisez-la pour les tâches d'automatisation de navigateur, mais exécutez les scripts directement plutôt que de lire leur code source pour éviter la pollution du contexte.
finishing-a-development-branch
TestsCette compétence aide les développeurs à finaliser leur travail en vérifiant que les tests passent, puis en présentant des options d'intégration structurées. Elle guide le processus de fusion, de création de PRs ou de nettoyage des branches une fois l'implémentation terminée. Utilisez-la lorsque votre code est prêt et testé pour finaliser systématiquement le cycle de développement.
