Getting Started with {shinytest2} Part 3 || Using shiny.testmode in {shinytest2} || RStudio
videoimage: thumbnail.jpg
Transcript#
This transcript was generated automatically and may contain errors.
So, this example has some serious effects for production-sized apps where you have authentication or things that testing should not be confirming. One of the difficulties when doing production-sized apps and you're running it through unit tests is interacting with outside sources. This can be authentication, this can be database requests. One of the things that we recommend you do is you listen to a flag or a global option of shiny.testmode. If shiny.testmode is true, I recommend having a different UI or server or reactive behavior given this flag.
You can have things like the authentication isn't even addressed. If I do a restricted database call, maybe instead I load a CSV of information. One, we're not testing the database, we're actually just testing the Shiny app, so we need to try to isolate our tests to what we can control. Using this flag, we can turn that behavior on or turn it off. I think it's just really great as to how you can override your app's default behavior.
I think it's just really great as to how you can override your app's default behavior.
Testing production apps with shiny.testmode
Let's look at the app that we've been doing in the past two videos where we ask our name and it'll tell us the first letter of our name. Then let's just add in a third field of penguins. To lighten the mood a little bit, we're going to say, how many penguins are going to be coming for dinner? Let's just add this into our app. We have it here. I'm just going to run it for demonstration purposes. I click greet. It says, hello, first letter of your name is B, and there are 333 penguins coming for dinner. This is fun, but if I keep hitting greet, if we look as to where this penguin count is coming from, it's coming from this authenticated database request or something that I'm going to have return random data. If I click greet again, that's 330, 324, 336. This is not deterministic at all.
This is therefore not useful for testing because if you keep running this test over and over, it will fail. There will be no way for it to be correct because the data changes underneath. Instead, we can listen to our flag. I'm going to just wrap this one part and say, if we'll get an option of shiny.testMode, and if we'll default this value to false, but if it's true, then I want to return a test database request. This is something that returns static data and will only retrieve what I want it to have. Otherwise, if I'm not in test mode, then let's just do the authenticated database request. This will be stored into penguin data, and then the penguin data will count the number of rows, and then hopefully we have a consistent count.
Now, if I just run my app in reload app, this is not in testing mode, so we should still see our original behavior. I see Barrett. We see greet. It's something like 333, 321, a different amount of each time when I click greet. Let's run this just kind of looking at our application here. If I run this with the app, and I call app$view so that I have it, it opens up in the Chromium-based browser, and I have what's your name. We call set input Barrett. We call app greet. We can see that it updated, and here it says, hello, Barrett. First letter name is B, and there are 68 penguins coming for dinner. It's a funny phrase, but it's 68. It's not 300, and so if I click greet again and again and again and again, 68 is now constant, and it's still going to stay there.
If I look at the values to see what we have, app$get values, I have output penguins. There are 38 penguins coming for dinner. I could actually update that so that we have another exported test value of the penguin count. If I update with the penguin count, say penguin count equals a reactive expression where I export that penguin count, save it, and then I have to, I'm going to stop this app here, and then I'm just going to restart those interactive tests where I run app, and I click greet, and let's view it. I don't need to necessarily open up the viewer at the beginning. It's usually useful when debugging errors, but it still says 68. App$get value of export equals penguin count is 68. Perfect.
Now we can make assertions on this value, and it'll be consistent every single time. This is just so useful for getting around those database calls that take five, 10 minutes to execute, or you're asking a different API about something that is outside the control of Shiny. We want these unit tests to be consistent and fast. That way you want to do them, and you want to do them often.
We want these unit tests to be consistent and fast. That way you want to do them, and you want to do them often.


