i18n/de/skills/test-shiny-app/SKILL.md
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.
npx skillsauth add pjt222/agent-almanac test-shiny-appInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Shiny-Anwendungen mit shinytest2 (End-to-End) und testServer() (Unit-Tests) zuverlässig testen.
tests/-Verzeichnisstrukturshinytest2 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).
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.
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.
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.
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.
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.
tests/testthat/_snaps/ erstellttestServer() prüfen Logik isoliertset.seed() verwenden und dynamischen Inhalt mocken.--no-sandbox-Flag in CI-Umgebungen setzen. GitHub Actions braucht spezielle Chromium-Konfiguration.testServer() vs AppDriver: testServer() testet Server-Logik isoliert (keine echten UI). AppDriver testet echte Browser-Interaktionen.shinytest2::snapshot_review() oder shinytest2::snapshot_update() aktualisiert werden.app$wait_for_idle() nach auslösenden Aktionen.testServer() benötigt reaktive Inputs — immer session$setInputs() vor Assertions aufrufen.scaffold-shiny-app — Shiny-App vor dem Testen scaffoldenbuild-shiny-module — Module erstellen, die mit testServer() getestet werdendeploy-shiny-app — Getestete App deployensetup-github-actions-ci — CI/CD-Workflows einrichtentesting
Launch all available agents in parallel waves for open-ended hypothesis generation on problems where the correct domain is unknown. Use when facing a cross-domain problem with no clear starting point, when single-agent approaches have stalled, or when diverse perspectives are more valuable than deep expertise. Produces a ranked hypothesis set with convergence analysis and adversarial refinement.
tools
Write integration tests for a Node.js CLI application using the built-in node:test module. Covers the exec helper pattern, output assertions, filesystem state verification, cleanup hooks, JSON output parsing, error case testing, and state restoration after destructive tests. Use when adding tests to an existing CLI, testing a new command, verifying adapter behavior across frameworks, or setting up CI for a CLI tool.
development
Screen a proposed trademark for conflicts and distinctiveness before filing. Covers trademark database searches (TMview, WIPO Global Brand Database, USPTO TESS), distinctiveness analysis using the Abercrombie spectrum, likelihood of confusion assessment using DuPont factors and EUIPO relative grounds, common law rights evaluation, and goods/services overlap analysis. Produces a conflict report with a risk matrix. Use before adopting a new brand name, logo, or slogan — distinct from patent prior art search, which uses different databases, legal frameworks, and analysis methods.
tools
Scaffold a new CLI command using Commander.js with options, action handler, three output modes (human-readable, quiet, JSON), and optional ceremony variant. Covers command naming, option design, shared context patterns, error handling, and integration testing. Use when adding a command to an existing Commander.js CLI, designing a new CLI tool from scratch, or standardizing command structure across a multi-command CLI.