<p><div><div><div><div data-width="100" data-show-faces="false" data-send="true" data-layout="button_count" data-height="21" data-href="https://www.r-bloggers.com/announcing-shinytester-a-package-that-helps-you-build-shiny-apps/"></div></div><div></div></div><div></div></div>
<div>
(This article was first published on <strong><a href="http://amitkohli.com/announcing-shinytester-a-package-that-helps-you-build-shiny-apps/"> R – AmitKohli.com</a></strong>, and kindly contributed to <a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers)</a> </div>
<p>Shiny is awesome, but can be a bit daunting and easy to make mistakes in. I recently came back to Shiny after a hiatus of a few years and it was much more challenging than I feel comfortable admitting. I was making bonehead mistakes like writing <code>something</code> instead of <code>output$something</code>, confusing where to put <code>Output</code> commands vs <code>Render</code> commands, etc. I would eventually find my mistake, curse myself and move on with a crumpled ego. Then I had the realization that maybe if I was a beginner, I wouldn’t even know what I was doing wrong. Thusly did I conclude that I was in a unique position to help out the R community: Dumb enough to make mistakes, but experienced enough to eventually remember how to resolve them. So naturally, I wrote an R package that tests the code of the Shiny app itself.</p>
<p> </p>
<p>To install: <code>install.packages(&quot;ShinyTester&quot;)</code> cause yes, it’s on CRAN (my first!!! Shoutout to <a target="_blank" rel="nofollow" href="http://jkunst.com/">@jbkunst</a> for invaluable help!)</p>
<p> </p>
<p><strong>Quick caveat</strong>: Since this package parses code and everyone writes code differently, it will necessarily be super buggy. If this package doesn’t work for your app (after reading the full list of caveats at the bottom of this post), please help by <a target="_blank" rel="nofollow" href="https://github.com/mexindian/ShinyTester/issues">opening an Issue on the github repo</a>.</p>
<p> </p>
<p>The package consists of two functions that analyze the code itself:</p>
<ul>
<li><code>ShinyDummyCheck()</code> – checks how items are created in <code>server.R</code> and then how they are called in <code>ui.R</code> and runs some fairly naive checks</li>
<li><code>ShinyHierarchy()</code> – to create an <em>ad hoc</em> hirearchy of the structure of the Shiny Apps – ie – what inputs go to what reactives, what reactives go to other reactives, and what then gets pushed back out to the UI as an output.</li>
</ul>
<p>It is my hope that both of these combined minimize the intrinsic boneheadedness in us all. This is really quite beta though… please do check the Caveats! In the meantime, some examples:</p>
<h3>Examples for <code>ShinyDummyCheck</code>:</h3>
<pre><code>ShinyTester::ShinyDummyCheck(&quot;https://raw.githubusercontent.com/mexindian/ShinyServer/master/LineSelector&quot;)
</code></pre>
<p>Provides this table:</p>
<p> </p>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/amitkohli.com/wp-content/uploads/2017/02/shinyDummyCheck.png"><img sizes="(max-width: 300px) 100vw, 300px" data-image-description="" data-orig-file="https://i1.wp.com/amitkohli.com/wp-content/uploads/2017/02/shinyDummyCheck.png?fit=467%2C216" data-orig-size="467,216" data-image-title="shinyDummyCheck" class="wp-image-728" data-comments-opened="1" data-recalc-dims="1" data-attachment-id="728" data-permalink="http://amitkohli.com/announcing-shinytester-a-package-that-helps-you-build-shiny-apps/shinydummycheck/" alt="" data-medium-file="https://i1.wp.com/amitkohli.com/wp-content/uploads/2017/02/shinyDummyCheck.png?fit=300%2C139" data-large-file="https://i1.wp.com/amitkohli.com/wp-content/uploads/2017/02/shinyDummyCheck.png?fit=467%2C216" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" src="https://i1.wp.com/amitkohli.com/wp-content/uploads/2017/02/shinyDummyCheck.png?resize=300%2C139"></a></p>
<p>Which shows that there are no errors in the Shiny app, oh except for the fact that I defined an object twice… whoops (Yeah, see that’s exactly the boneheadedness I’m talkin bout). The structure of the table is as follows:</p>
<p> </p>
<ul>
<li>Item – The name of the asset that maybe should be on both server.R and ui.R</li>
<li>SrvCall – the TYPE of object that you’re saying this specific item is (in server.R)</li>
<li>isOutput – is a binary that will specify if in server.R you wrote just <code>item</code> or <code>output$item</code></li>
<li>VisualCall – is the TYPE of thingie you’re trying to push the item into (in ui.R).</li>
<li>Status – Compares the SrvCall to the VisualCall, also looks at isOutput and then applies some rules to figure out if it’s probably ok or not</li>
</ul>
<h3>Examples for <code>ShinyHierarchy</code>:</h3>
<p>A simple example:</p>
<pre><code>library(ShinyTester)
ShinyHierarchy(&quot;https://raw.githubusercontent.com/rstudio/shiny-examples/master/003-reactivity&quot;)
</code></pre>
<p>Will yield:</p>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/cloud.githubusercontent.com/assets/8094091/21746544/7830f6b2-d50e-11e6-8583-c90670786adc.png?ssl=1"><img alt="image" src="https://i1.wp.com/cloud.githubusercontent.com/assets/8094091/21746544/7830f6b2-d50e-11e6-8583-c90670786adc.png?w=750&ssl=1" data-recalc-dims="1"></a></p>
<p> </p>
<p>Which shows one of the weaknesses of the function… it assumes all Item names are unique… and will act strangely if this assumption doesn’t hold (ie – caption).</p>
<p> </p>
<p>A more complex example:</p>
<pre><code>ShinyTester::ShinyHierarchy(&quot;https://raw.githubusercontent.com/mexindian/ShinyServer/master/LineSelector&quot;)
</code></pre>
<p>Yields:</p>
<p><a target="_blank" rel="nofollow" href="https://i1.wp.com/cloud.githubusercontent.com/assets/8094091/21746698/169dcdc0-d514-11e6-88ed-357d37293b65.png?ssl=1"><img alt="image" src="https://i1.wp.com/cloud.githubusercontent.com/assets/8094091/21746698/169dcdc0-d514-11e6-88ed-357d37293b65.png?w=750&ssl=1" data-recalc-dims="1"></a></p>
<p>And here we can start to see the structure that I’m attempting to show… there are basically three ROWS of nodes. The first one is the UI Inputs, the second row are the reactives (kinda…), and the third row are the outputs being visualized. I said the reactives are “kinda” the second row because I have introduced a small shift to each node in the middle row in order to see reactive flows into each other (if they are all in the same row, you can’t really see them). The structure is made evident in a more complex case below (forgive the redacted names):</p>
<p><a target="_blank" rel="nofollow" href="https://i0.wp.com/cloud.githubusercontent.com/assets/8094091/21746742/67a21a86-d515-11e6-96d4-5456b54a7747.png?ssl=1"><img alt="image" src="https://i0.wp.com/cloud.githubusercontent.com/assets/8094091/21746742/67a21a86-d515-11e6-96d4-5456b54a7747.png?w=750&ssl=1" data-recalc-dims="1"></a></p>
<p>If you want to suppress the shift in reactive nodes, use <code>offsetReactives = F</code></p>
<h3>Caveats:</h3>
<p>This is a very naive app, and in early stages at that… it works best with my style of programming and will probably take significant work to universalize (since we’re talking about code… maybe it’s impossible to fully universalize).  Some other caveats:</p>
<ul>
<li>For now only works with <code>&lt;-</code> assignments, not <code>=</code> or <code>-></code> assignments</li>
<li><del>For now calling items only works with doublequotes. (ie. <code>plotOutput(&quot;thingie&quot;)</code> works, <code>plotOutput('thingie')</code> doesn’t.</del></li>
<li>For now, only supports seperate ui.R and server.R Shiny apps… the single <code>app.R</code> implementation is not supported.</li>
<li><code>isolate</code> and <code>observe</code> are not supported yet</li>
<li>For now, I don’t read in data outside the shinyserver call (for example, if I want to pass data in that only needs to be calculated once. Not sure yet what’s the best way.</li>
<li>For now it only analyzes the main scripts, if you are SOURCEing files in from other places, it won’t work.</li>
</ul>
<h3>Other tips for working in Shiny:</h3>
<ul>
<li>Add to your server.R and ui.R TEST items. for example, add one for a data.frame and one for a figure. You can keep these commented out or displaying random data… then, when you add a new element, just test them in the test blocks before adding them to the exact place. Saves time.</li>
<li>Likewise, during testing, if you need to run through the code to debug, you can always simulate inputs by writing this: <code>input &lt;- data.frame(Parameter1=&quot;thingie1&quot;,Parameter2=&quot;thingie2&quot;)</code>. Keep this commented out, but when you test, you can run through the Shiny app as if it were live.</li>
<li>Check Dean Attali’s excellent tips and tricks (<a target="_blank" rel="nofollow" href="http://deanattali.com/blog/advanced-shiny-tips/">http://deanattali.com/blog/advanced-shiny-tips/</a>).</li>
</ul>
<p> </p>
<p>Enjoy!</p>
<p>(Thanks to my <a target="_blank" rel="nofollow" href="http://rusers.co/">rusers community</a>, especially to <a target="_blank" rel="nofollow" href="http://jkunst.com/">Joshua Kunst</a> and <a target="_blank" rel="nofollow" href="http://www.pivotsciences.com/">Colin Phillips</a> for discussion, help and encouragement required to push this through to CRAN).</p>
<p>
<div>
<div>To <strong>leave a comment</strong> for the author, please follow the link and comment on their blog: <strong><a href="http://amitkohli.com/announcing-shinytester-a-package-that-helps-you-build-shiny-apps/"> R – AmitKohli.com</a></strong>.</div>
<hr>
<a rel="nofollow" href="https://www.r-bloggers.com/">R-bloggers.com</a> offers <strong><a rel="nofollow" href="https://feedburner.google.com/fb/a/mailverify?uri=RBloggers">daily e-mail updates</a></strong> about <a title="The R Project for Statistical Computing" rel="nofollow" href="https://www.r-project.org/">R</a> news and <a title="R tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/tutorial">tutorials</a> on topics such as: <a title="Data science" rel="nofollow" href="https://www.r-bloggers.com/search/data%20science">Data science</a>, <a title="Big Data" rel="nofollow" href="https://www.r-bloggers.com/search/Big%20Data">Big Data, <a title="R jobs" rel="nofollow" href="https://www.r-users.com/">R jobs</a>, visualization (<a title="ggplot and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/ggplot2">ggplot2</a>, <a title="Boxplots using lattice and ggplot2 tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/boxplot">Boxplots</a>, <a title="Maps and gis" rel="nofollow" href="https://www.r-bloggers.com/search/map">maps</a>, <a title="Animation in R" rel="nofollow" href="https://www.r-bloggers.com/search/animation">animation</a>), programming (<a title="RStudio IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/RStudio">RStudio</a>, <a title="Sweave and literate programming" rel="nofollow" href="https://www.r-bloggers.com/search/sweave">Sweave</a>, <a title="LaTeX in R" rel="nofollow" href="https://www.r-bloggers.com/search/LaTeX">LaTeX</a>, <a title="SQL and databases" rel="nofollow" href="https://www.r-bloggers.com/search/SQL">SQL</a>, <a title="Eclipse IDE for R" rel="nofollow" href="https://www.r-bloggers.com/search/eclipse">Eclipse</a>, <a title="git and github, Version Control System" rel="nofollow" href="https://www.r-bloggers.com/search/git">git</a>, <a title="Large data in R using Hadoop" rel="nofollow" href="https://www.r-bloggers.com/search/hadoop">hadoop</a>, <a title="Web Scraping of google, facebook, yahoo, twitter and more using R" rel="nofollow" href="https://www.r-bloggers.com/search/Web+Scraping">Web Scraping</a>) statistics (<a title="Regressions and ANOVA analysis tutorials" rel="nofollow" href="https://www.r-bloggers.com/search/regression">regression</a>, <a title="principal component analysis tutorial" rel="nofollow" href="https://www.r-bloggers.com/search/PCA">PCA</a>, <a title="Time series" rel="nofollow" href="https://www.r-bloggers.com/search/time+series">time series</a>, <a title="finance trading" rel="nofollow" href="https://www.r-bloggers.com/search/trading">trading</a>) and more...
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/9GHlEd3aUcA"></a></div>