test-shiny-app
Acerca de
Esta habilidad ayuda a los desarrolladores a probar aplicaciones Shiny utilizando shinytest2 para pruebas de interfaz de usuario de extremo a extremo y testServer() para pruebas unitarias de la lógica del servidor. Cubre pruebas de instantáneas, pruebas de interacción con la interfaz de usuario, pruebas de módulos e integración con CI/CD. Úsala para validar el comportamiento de la aplicación, configurar pruebas de regresión o incorporar pruebas en tu pipeline de despliegue.
Instalación rápida
Claude Code
Recomendadonpx 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-appCopia y pega este comando en Claude Code para instalar esta habilidad
Documentación
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
Repositorio GitHub
Habilidades relacionadas
evaluating-llms-harness
PruebasEsta Skill de Claude ejecuta el benchmark lm-evaluation-harness para evaluar modelos de lenguaje en más de 60 tareas académicas estandarizadas como MMLU y GSM8K. Está diseñada para que los desarrolladores comparen la calidad de los modelos, realicen seguimiento del progreso del entrenamiento o reporten resultados académicos. La herramienta admite varios backends, incluidos modelos de HuggingFace y vLLM.
cloudflare-cron-triggers
PruebasEsta habilidad proporciona conocimiento integral para implementar Cron Triggers de Cloudflare y programar Workers mediante expresiones cron. Cubre la configuración de tareas periódicas, trabajos de mantenimiento y flujos de trabajo automatizados, manejando problemas comunes como expresiones cron inválidas y inconvenientes de zonas horarias. Los desarrolladores pueden utilizarla para configurar manejadores programados, probar activadores cron e integrar con Workflows y Green Compute.
webapp-testing
PruebasEsta habilidad de Claude proporciona un kit de herramientas basado en Playwright para probar aplicaciones web locales mediante scripts de Python. Permite verificación de frontend, depuración de interfaz de usuario, captura de pantallas y visualización de registros, mientras gestiona los ciclos de vida del servidor. Úsela para tareas de automatización de navegadores, pero ejecute los scripts directamente en lugar de leer su código fuente para evitar contaminación del contexto.
finishing-a-development-branch
PruebasEsta habilidad ayuda a los desarrolladores a completar el trabajo terminado verificando que las pruebas pasen y luego presentando opciones estructuradas de integración. Guía el flujo de trabajo para fusionar, crear PRs o limpiar ramas después de que se completa la implementación. Úsala cuando tu código esté listo y probado para finalizar sistemáticamente el proceso de desarrollo.
