
Getting Started with {shinytest2} Part 2 || Exporting values || RStudio
00:00 Introduction 00:29 Exporting reactives 03:28 Using exportTestValues() Part 1 - Getting started: https://youtu.be/SS1Na3c8lhk Part 3 - Using shiny.testmode: https://youtu.be/xDxa_mDwN04 Manually testing Shiny applications is often laborious, inconsistent, and doesn’t scale well. Whether you are developing new features, fixing bug(s), or simply upgrading dependencies on a serious app where mistakes have real consequences, it is critical to know when regressions are introduced. shinytest2 provides a streamlined toolkit for unit testing Shiny applications and seamlessly integrates with the popular testthat framework for unit testing R code. shinytest2 uses chromote to render applications in a headless Chrome browser. chromote allows for a live preview, better debugging tools, and/or simply using modern JavaScript/CSS. By simply recording your actions as code and extending them to test the more particular aspects of your application, it will result in fewer bugs and more confidence in future Shiny application development. Read up on shinytest2 here: https://rstudio.github.io/shinytest2/ Learn more about Shiny here: https://shiny.rstudio.com/ Got questions? The RStudio Community site is a great place to get assistance: https://community.rstudio.com/ Content: Barret Schloerke (@schloerke) Motion design and editing: Jesse Mostipak (@kierisi) Theme song: Brad PKL by Blue Dot Sessions (https://app.sessions.blue/browse/track/113507)
image: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
Sometimes, just knowing your inputs and outputs is not enough, because they can hide the middle interactions of your reactives. I know this is a smaller app, but it tries to get across the point of, we can export these inner reactive values. It's not just your inputs and outputs, you can export these inner reactives. I'm interested in this first letter. I know the phrasing of the first letter in your name is B, or whatever the first part of your name is, but I want to actually just have that letter as a value that I can test against.
It's not just your inputs and outputs, you can export these inner reactives.
Exporting reactives
We have our recording, and I'm going to adjust this copy and adjust this recording. I'm going to do some alterations for it, so we can export those test values. Let's say, let's call a new test, so export test values, and we'll say export values just for fun. In this case, the app is not going to be doing anything specific with screenshots, or the app itself is not dependent on the width, so I'm going to remove the height and width restriction and just use the defaults. I'm going to set the inputs of name Barrett, and I'm going to click greet.
One thing we could do here is just get value, and we want to say output equals first letter. This should have, if I'm running the application, this should be this phrase. We can just copy it, and I'm going to say first letter, not just the first letter, but the first letter phrase. We'll say expect equal to first letter phrase, and the whole, like my first letter in my name is B. For now, I'm just going to comment that earlier test.
We're going to just run all the tests right here. This will start a new app driver given the application. It's just called export values to have it as a name. Set the name to Barrett. I then click greet, and then I get the value of the output first letter, but we should just actually see what this is like in the console just because it's fun to see this interactively because I'm just taking a guess that first letter phrase is this. First letter phrase. It does equal the first letter in your name is B, so this expect equal passed, and we saw that pass.
The little warning here of deleting unused screenshots or snapshots is of these. That is because I commented this test, so test set is like those tests don't exist anymore, so we should delete them. That's okay. If I undo this and rerun it, those snapshots will come right back. This is how we can get the whole phrase, but the thing I was interested in was the letter B, and this is where it becomes very neat in that we can export those values.
Using exportTestValues()
There's a method under Shiny called export test values, and export test values is a key to reactive expression set of arguments that it can take, so in here I could say first letter. I could just call it first. It doesn't really matter. It's my own custom key, but I'm just going to, for consistency, I'm going to just call it first letter, and this will equal to the output of the reactive expression, so the reactive expression that I'm executing is first letter, and then since first letter is a reactive, I need to execute it at the end.
Okay, so a lot of things there, but what does that give us? If we were to, since the app has been updated, we need to rerun our app, so I will kill the old one, app stop, and then let's actually just get us back into the state that we are at, so let's make a new app driver. Let's call set inputs. Let's click, and let's just look at the values that are currently in the app with get values, so this will return all the input, output, and exported values. We just added a first letter exported value.
Yay, so we have our inputs that we remember. We have input greet and input name. We have our outputs of first letter and greeting, and then we have export this first letter, and now we have access to this reactive value, so it doesn't need to be outputted. We can just use an exported value, so for this one, we can also say app dollar get value of export equals first letter, and here on 15, this get value of output as first letter is retrieving output first letter, where I'm more interested in export first letter, so I will say export of first letter, and we'll do expect equal to B, and if I run this, it passes.
Just for proof, if I change it to a J and I run it, it'll say, oh, error found actual is B, but you expected J, so we do want B, so I'll change it back and run it just to confirm. Great, we're good, and then I will run all the tests because it's unit tests. We should be able to run these all the time quickly. Great, now we have two checks passed. Awesome.


