class: inverse, center, title-slide, middle ## {shinyValidator}: toward a new audit process for Shiny apps quality through CI/CD ###### AppsilonConf 2022 Apr 29 .flex.tc[ .w-30.mr3.center[ <img class="br-100" width="100px" height="100px" src="assets/images/jpeg/david.jpeg" class="svg-img"/> <br> .f5[David Granjon] .small[Senior Expert Data Scientist] ] ] --- class: header_background # <img src="assets/images/svg/shiny.svg" width="5%" style="display: inline; margin: auto;" class="svg-img"/> apps may look amazing ... <br/> `{Shiny}` is about __10__ years old π²π²π². -- Today, many tools can make your apps __shining__... .center[ <img src="assets/images/jpeg/outstanding-shiny.jpg" width="20%" /> ] --- class: header_background # Clothes don't make the man <br/> Yet ... too many __unexplained__ syndromes: -- - The well known "It worked for me ... but not for you" π€·ββοΈ - The famous "It was fine yesterday" π - And many others... --- class: header_background # Clothes don't make the man <br/> .center[ <img src="assets/images/svg/404.svg" width="40%" style="display: block; margin: auto;" class="svg-img"/> ] Your app may be as beautiful and as cool as you want, it is __useless__ if it does not start/run. --- class: header_background # Most Shiny apps are "just" prototypes <br/> Why is my app not starting/running β -- Possible answers: - __Quickly__ developed, no planning π± - No code quality __management__ π± - No __tests__ π± - ... -- This must stop π! --- class: header_background # About software validation <br/> Check that a product is __conform__ to initial __requirements__ (Software engineering). -- For Shiny apps: - __Reliability__: is the app doing what it is intended to do? - __Stability__: how often does it crash? - __Performance/Availability__: is the app fast enough to handle multiple concurrent users? -- In practice, a few apps meet all these requirements π. How do we transition from __prototypes__ to __production-ready__ tools β --- class: inverse center middle title-slide-without-bg title-slide # 1. Production Ready Shiny Apps <img src="assets/images/jpeg/engineering-shiny.jpg" width="20%" style="display: block; margin: auto;" /> --- class: header_background # Consolidate Shiny apps projects <br/> .panelset[ .panel[.panel-name[Package your app] .center[ <img src="assets/images/svg/golem.svg" width="10%" style="display: block; margin: auto;" class="svg-img"/> ] - Easier checking, linting, documentation and testing. - Just ... __easier__. π ] .panel[.panel-name[Manage your __dependencies__] .center[ <img src="assets/images/svg/renv.svg" width="10%" style="display: block; margin: auto;" class="svg-img"/> ] - Fix package versions. - Increased __reproducibility__. ] .panel[.panel-name[__Test__ your code] .center[ <img src="assets/images/svg/testthat.svg" width="10%" style="display: inline; margin: auto;" class="svg-img"/> ] - Unit tests: test business logic. - Server testing: test how Shiny modules or pieces work together (with reactivity). - UI testing: test UI components, snapshots, headless-testing (`{shinytest2}`). ] .panel[.panel-name[Optimize] Are there bottlenecks? - __Load__ testing: How does the app behave with 10 simultaneous user? `{shinyloadtest}`. - __Profiling__: What part of my app is slow?`{profvis}`. - Reactivity: Are there any reactivity issues? <img src="assets/images/svg/reactlog.svg" width="10%" style="display: inline; margin: auto;" class="svg-img"/>. ] ] --- class: header_background # Stop ... I am lost ... <br> .center[ <img src="assets/images/svg/sad.svg" width="40%" style="display: block; margin: auto;" class="svg-img"/> ] - There are just so many tools! How to use them properly? - Is there a way to __automate__ all of this? I just don't have time ... π --- class: inverse center middle title-slide-without-bg title-slide # 3. Leveraging CI/CD --- class: header_background # What, why and how? <br> .panelset[ .panel[.panel-name[What] - Continuous integration: automatically __check__ new features. π₯ - Continuous deployment: automatically __deploy__ content. βοΈ - Running on a __remote__ environment βοΈ: - [Github Actions](https://github.com/features/actions). - [Jenkins](https://www.jenkins.io/). - [Gitlab CI/CD](https://docs.gitlab.com/ee/ci/). ] .panel[.panel-name[Benefits] - __Automated__. - More __reproducible__ (more os/R flavors available). - __Time saver__. - Less duplication. ] .panel[.panel-name[How?] Not easy π’ - Select __DevOps__ platform (GitLab, GitHub, ...). - Add __version control__ (git knowledge). - Build custom GitLab runner (optional). - Write __CI/CD instructions__ (better support for GitHub). - Enjoy ... Can't we make things easierβ ] ] --- class: inverse center middle title-slide-without-bg title-slide # 4. Welcome {shinyValidator} --- class: header_background # {shinyValidator} <br> .panelset[ .panel[.panel-name[Purpose] - __Eases__ Shiny Apps validation: - __Provides__ plug and play CI/CD pipelines. - __Lints__ and __checks__ the package code. - Performs a Shiny app __crash test__. - Displays __outputs__ differences: plots, htmlwidgets. - Measure __performance__: load-test, profiling and reactivity checkup. All is __integrated__ into a nice HTML report. ] .panel[.panel-name[Requirements] - Requires a __package__, especially with `{golem}`. - Control R __dependencies__ with `{renv}`. - Requires __git__ + remote repository. - Have __unit tests__. ] .panel[.panel-name[Setup] - Install it: .small[ ```r remotes::install_github("Novartis/shinyValidator") ``` ] - Run `use_validator("github")` (for Github Actions). - `devtools::document()`. - Run `renv::snapshot()` to capture dependencies. - Commit, push and enjoy. π ] ] --- class: header_background # {shinyValidator}: audit app <br> `audit_app()` main package function: .pull-left.small[ ```r audit_app( timeout = 5, headless_actions = NULL, workers = 5, scope = c("DMC", "POC"), output_validation = TRUE, coverage = TRUE, load_testing = TRUE, profile_code = TRUE, check_reactivity = TRUE, flow = TRUE ) ``` ] .pull-right[ <img src="assets/images/png/shinyValidator.png" width="100%" /> ] --- class: header_background # Live Demo <br> Because a demo is better than 30 slides. --- class: header_background # Thanks ππ» <br> - Barret Schloerke (RStudio). - Peter Krusche (Novartis). - Lucas Widmer (Novartis). - Janice Branson (Novartis). - Technology & Innovation Team (Novartis): Aleks, Bo, Marie, Dave, David, Mustapha, Ardalan, Bill and Stefan. - Christophe Dervieux (RStudio). - Sebastien Rochette (ThinkR). - Romain Lesur (Insee). - Katerina Limpitsouni (unDraw, illustrations). --- # Follow me <br> - <img src="assets/images/svg/twitter.svg" width="5%" style="display: inline; margin: auto;" class="svg-img"/> [Twitter](https://twitter.com/divadnojnarg). - <img src="assets/images/svg/github.svg" width="5%" style="display: inline; margin: auto;" class="svg-img"/> [Github](https://github.com/DivadNojnarg).