スキル一覧に戻る

test-shiny-app

pjt222
更新日 2 days ago
4 閲覧
17
2
17
GitHubで表示
テストtesting

について

このスキルは、開発者がShinyアプリケーションをテストする際に、エンドツーエンドのブラウザテストにはshinytest2を、サーバーロジックのユニットテストにはtestServer()を使用する方法を支援します。スナップショットテスト、CI統合、外部サービスのモック化についてもカバーしています。既存アプリへのテスト追加、新規プロジェクトのテスト環境構築、回帰テストの作成、CI/CDパイプラインへのテスト統合などの場面でご活用ください。

クイックインストール

Claude Code

推奨
メイン
npx skills add pjt222/agent-almanac -a claude-code
プラグインコマンド代替
/plugin add https://github.com/pjt222/agent-almanac
Git クローン代替
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/test-shiny-app

このコマンドをClaude Codeにコピー&ペーストしてスキルをインストールします

ドキュメント

Test Shiny App

Set up comprehensive testing for Shiny applications using shinytest2 (end-to-end) and testServer() (unit tests).

When Use

  • Add tests to existing Shiny application
  • Set up testing strategy for new Shiny project
  • Write regression tests before refactoring Shiny code
  • Integrate Shiny app tests into CI/CD pipelines

Inputs

  • Required: Path to Shiny application
  • Required: Test scope (unit tests, end-to-end, or both)
  • Optional: Whether to use snapshot testing (default: yes for e2e)
  • Optional: CI platform (GitHub Actions, GitLab CI)
  • Optional: Modules to test in isolation

Steps

Step 1: Install Testing Dependencies

install.packages("shinytest2")

# For golem apps, add as a Suggests dependency
usethis::use_package("shinytest2", type = "Suggests")

# Set up testthat infrastructure if not present
usethis::use_testthat(edition = 3)

Got: shinytest2 installed, testthat directory structure in place.

If fail: shinytest2 needs chromote (headless Chrome). Install Chrome/Chromium on system. WSL: sudo apt install -y chromium-browser. Verify with chromote::find_chrome().

Step 2: Write testServer() Unit Tests for Modules

Create tests/testthat/test-mod_dashboard.R:

test_that("dashboard module filters data correctly", {
  testServer(dataFilterServer, args = list(
    data = reactive(iris),
    columns = c("Species", "Sepal.Length")
  ), {
    # Set inputs
    session$setInputs(column = "Species")
    session$setInputs(value_select = "setosa")
    session$setInputs(apply = 1)

    # Check output
    result <- filtered()
    expect_equal(nrow(result), 50)
    expect_true(all(result$Species == "setosa"))
  })
})

test_that("dashboard module handles empty data", {
  testServer(dataFilterServer, args = list(
    data = reactive(iris[0, ]),
    columns = c("Species")
  ), {
    # Module should not error on empty data
    expect_no_error(session$setInputs(column = "Species"))
  })
})

Key patterns:

  • testServer() tests module server logic without a browser
  • Pass reactive arguments via the args list
  • Use session$setInputs() to simulate user interactions
  • Access reactive return values directly by name
  • Test edge cases: empty data, NULL inputs, invalid values

Got: Module tests pass with devtools::test().

If fail: testServer() errors with "not a module server function"? Ensure function uses moduleServer() internally. session$setInputs() doesn't trigger reactives? Add session$flushReact() after setting inputs.

Step 3: Write shinytest2 End-to-End Tests

Create tests/testthat/test-app-e2e.R:

test_that("app loads and displays initial state", {
  # For golem apps
  app <- AppDriver$new(
    app_dir = system.file(package = "myapp"),
    name = "initial-load",
    height = 800,
    width = 1200
  )
  on.exit(app$stop(), add = TRUE)

  # Wait for app to load
  app$wait_for_idle(timeout = 10000)

  # Check that key elements exist
  app$expect_values()
})

test_that("filter interaction updates the table", {
  app <- AppDriver$new(
    app_dir = system.file(package = "myapp"),
    name = "filter-interaction"
  )
  on.exit(app$stop(), add = TRUE)

  # Interact with the app
  app$set_inputs(`filter1-column` = "cyl")
  app$wait_for_idle()

  app$set_inputs(`filter1-apply` = "click")
  app$wait_for_idle()

  # Snapshot the output values
  app$expect_values(output = "table")
})

Key patterns:

  • AppDriver$new() launches the app in headless Chrome
  • Always use on.exit(app$stop()) to clean up
  • Module input IDs use the format "moduleId-inputId"
  • app$expect_values() creates/compares snapshot files
  • app$wait_for_idle() ensures reactive updates complete

Got: End-to-end tests create snapshot files in tests/testthat/_snaps/.

If fail: Chrome not found? Set CHROMOTE_CHROME environment variable to Chrome binary path. Snapshots fail on CI but pass local? Check for platform-dependent rendering differences — use app$expect_values() for data snapshots rather than app$expect_screenshot() for visual ones.

Step 4: Record Test Interactively (Optional)

shinytest2::record_test("path/to/app")

This opens the app in a browser with a recording panel. Interact with the app, then click "Save test" to auto-generate test code.

Got: Test file generated in tests/testthat/ with recorded interactions.

If fail: Recorder doesn't open? Check app runs successful with shiny::runApp() first. Recorder needs working app.

Step 5: Set Up Snapshot Management

For snapshot-based tests, manage expected values:

# Accept new/changed snapshots after review
testthat::snapshot_accept("test-app-e2e")

# Review snapshot differences
testthat::snapshot_review("test-app-e2e")

Add snapshot directories to version control:

tests/testthat/_snaps/    # Committed — contains expected values

Got: Snapshot files tracked in git for regression detection.

If fail: Snapshots change unexpected? Run testthat::snapshot_review() to see diffs. Accept intentional changes with testthat::snapshot_accept().

Step 6: Integrate with CI

Add to .github/workflows/R-CMD-check.yaml or create a dedicated workflow:

- name: Install system dependencies
  run: |
    sudo apt-get update
    sudo apt-get install -y chromium-browser

- name: Set Chrome path
  run: echo "CHROMOTE_CHROME=$(which chromium-browser)" >> $GITHUB_ENV

- name: Run tests
  run: |
    Rscript -e 'devtools::test()'

For golem apps, ensure the app package is installed before testing:

- name: Install app package
  run: Rscript -e 'devtools::install()'

Got: Tests pass in CI with headless Chrome.

If fail: Common CI issues: Chrome not installed (add apt-get step), display server missing (shinytest2 uses headless mode default so usually not issue), or timeout on slow runners (increase timeout in AppDriver$new()).

Checks

  • devtools::test() runs all tests without errors
  • testServer() tests cover module server logic
  • shinytest2 tests cover key user workflows
  • Snapshot files committed to version control
  • Tests pass in CI environment
  • Edge cases tested (empty data, NULL inputs, error states)

Pitfalls

  • Test UI rendering instead of logic: Prefer testServer() for logic and app$expect_values() for data. Only use app$expect_screenshot() when visual appearance matters — screenshots brittle across platforms.
  • Module ID format in e2e tests: Setting module inputs via AppDriver? Use "moduleId-inputId" format (hyphen-separated), not "moduleId.inputId".
  • Flaky timing: Always call app$wait_for_idle() after app$set_inputs(). Without it, assertions may run before reactive updates complete.
  • Snapshot drift: Never commit snapshots generated on different platforms (Mac vs Linux). Standardize on CI platform for snapshot generation.
  • Missing Chrome on CI: shinytest2 needs Chrome/Chromium. Always include installation step in CI workflows.

See Also

  • build-shiny-module — create testable modules with clear interfaces
  • scaffold-shiny-app — set up app structure with testing infrastructure
  • write-testthat-tests — general testthat patterns for R packages
  • setup-github-actions-ci — CI/CD setup for R packages (golem apps)

GitHub リポジトリ

pjt222/agent-almanac
パス: i18n/caveman/skills/test-shiny-app
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

関連スキル

evaluating-llms-harness

テスト

このClaudeスキルは、lm-evaluation-harnessを実行し、MMLUやGSM8Kなど60以上の標準化学術タスクでLLMをベンチマークします。開発者がモデルの品質を比較し、トレーニングの進捗を追跡し、学術的な結果を報告するために設計されています。このツールはHuggingFaceやvLLMモデルを含む様々なバックエンドをサポートしています。

スキルを見る

cloudflare-cron-triggers

テスト

このスキルは、cron式を使用してWorkersをスケジュールするためのCloudflare Cron Triggersの実装に関する包括的な知識を提供します。定期的なタスクの設定、メンテナンスジョブ、自動化されたワークフローの構築を網羅し、無効なcron式やタイムゾーン問題といった一般的な課題への対処法も含みます。開発者はこれを使用して、スケジュールされたハンドラーの設定、cronトリガーのテスト、WorkflowsやGreen Computeとの連携を構成できます。

スキルを見る

webapp-testing

テスト

このClaude Skillは、Playwrightベースのツールキットを提供し、Pythonスクリプトを通じてローカルWebアプリケーションのテストを可能にします。フロントエンドの検証、UIデバッグ、スクリーンショット撮影、ログ表示を実現し、サーバーライフサイクルを管理します。ブラウザ自動化タスクにご利用いただけますが、コンテキストの汚染を避けるため、スクリプトのソースコードを読むのではなく直接実行してください。

スキルを見る

finishing-a-development-branch

テスト

このスキルは、開発者がテストの合格を確認し、構造化された統合オプションを提示することで、完成した作業を仕上げることを支援します。実装が完了した後のマージ、PR作成、ブランチの整理といったワークフローを案内します。コードが準備できてテスト済みの際に使用し、開発プロセスを体系的に完了させましょう。

スキルを見る