So today what we'll cover in three hours is React Native Testing Library and Jest Native, which is a helper library for making assertions against React Native code. What we're not going to cover is Jest basics, I mean you'll see some of Jest testing basics as we go, but it's not mainly an introduction to Jest and also we're not going to cover end-to-end testing today with either Detox or Appium or anything like that, and I'll kind of explain the difference as we go along, but really it's specifically on React Native Testing Library. Afterwards, this URL, this is the same URL that's in the footer down here, so you can see it on any slide when the slides are up. You can go there from, I'll have links for more resources you can follow and also links to I have a Discord community with a bunch of folks that join on the livestream and talk about React Testing, React Native Testing. I'd love to field questions for you there afterwards if you have any more questions about testing. Anytime, please reach out. Okay, so we're going to start, that was the intro, Session One. This is Session Two, which is component tests focusing on rendering. So let's dive straight in and maybe about halfway through the three hours, we'll try to take a break. Maybe that will coincide with some exercise time as well, so people get dual time for that.
All right, let me make sure I see the chat on here. I'm going to keep, as we go, I'm going to keep an eye on the Zoom chat and on the Discord chat as much as I can. Actually, you know, I have my notes when we're in the code exercise. Those are going to be up on my phone. So anyone is welcome to come off mute to ask a question, anytime, but whenever I'm back on the slides, I'm going to pop back over to Discord. So I'll mainly watch Discord, but I'll try to keep the Zoom chat in front of me as well. Basically what I'm saying is, please interject and ask questions, because I'm happy to just help with whatever would be helpful to you.
All right. So let's talk about rendering and really the basics of getting started with component tests. So what is a component test? When you think about React or React Native, your application is organized into components, and in the component test, you are testing a component directly. You're not testing a whole application altogether. In the component itself, you actually write JSX to render out a component in the context of the test, independently of the rest of the application. So it lets you isolate the components. By default, all the children, like the child components of the component, are rendered out and included as well, but the rest of the application you're separated out from. And so you can focus on, does this component do its job with regard to the rest of the application? The library we're going to be using is called React Native testing library. The NPM package is under the At Testing Library organization, and if you've used React testing library on the web, it has a very similar philosophy. The code base is totally independent, because it emerged separately and because there's so many differences about the native environment, but they have exactly the same philosophy and are trying to converge on the APIs. Here's the URL for it, but also, these slides will be up later, but basically if you Google React Native testing library, you will get their docs. And from, when we do get to the exercises together, I have a link to my testing website with more information, and it in turn has links to the React Native testing library docs. So from there, you're going to be able to get to whatever you need in the exercises today or in the future.
So what do you test when you're testing a component? Some of these questions come to mind and especially kind of a few years ago before the testing tooling had evolved, you started to say, well, my component is a function and it's got other functions in it. Can I call them? Can I test a hook? Can I test a memoized property? Can I check state values that are set to see if they have the appropriate value that I would expect? And so these are the questions that people tend to ask. A common phrase is how do I test this line of code? And in some senses, like yes, you want the test to run through there, you want the test to make sure this line of code works. But the focus when it comes to writing a test, I have found that focusing on how do I test this line of code can tend to not be the most productive, it can leave you confused. How do I test the line of code? Instead, I would like to argue for a different way of thinking about tests. And none other than Dan of the React core team has a great quote that I think is very helpful in this regard. In a tweet in 2019, in the before times, he said, we don't encourage reading implementation details like state variables themselves. Instead, test observable behavior, i.e. what your component renders or does. Test from outside the component. And I think that's exactly right. That's exactly the kind of test philosophy that leads to robust, maintainable, helpful, useful tests. There's another way you can think about this concept, and it's called testing the contract. This term, maybe it comes from elsewhere, but I know of it from a book, called Testing View.js Applications. A different frontend framework, actually. Ed Yerber wrote the book, and he said, A component contract is the agreement between a component and the rest of the application. It's not something concrete in code, it's just the concept. It's, what is the concept of the agreement between a component and the rest of the application? He goes on. Other components can assume the component will fulfill its contractual agreement and produce the agreed output if it has provided the correct input. So that is what the rest of your application thinks about when it thinks about a single component, or what it is built in light of. It is assuming and relying on a given component doing what it guarantees, doing what it was built to do. That's what we can focus our tests on. If a component gets the right inputs, or for a given set of inputs, what are the outputs that the component produces? So I wanted to go to a question now, before I tell you what I think the inputs and outputs of a component are. I have four main ones that I want to talk through together. I'm sure I haven't thought of everything. I would love to hear from your perspective if you're willing to share in the chat. What are some of the kinds of inputs and outputs that the components have? There's no wrong answers. I just want to get your understanding. I'm pulling up the two different chats now so I can see your thoughts, but let's just take a minute or two to think about it. What are the inputs and outputs of components? I won't force you, but I encourage you to be bold, share your thoughts on what the inputs and outputs of the component are. In just a minute or so, we'll continue.
All right, Salvo says, input props and context data. Great, that totally makes sense. I wonder if you might have output queued up. So I'll give just a second in case you want to share some output. Salvo says, props input, output snapshot. Yeah, it makes sense. Salvo says, output rendered component on the screen. Makes sense? Cool, yeah. The way you all are thinking about this is spot on. So let's go and look at the way that I kind of structured it. You'll see a lot of familiarity. I kind of break it down to, as far as the things that I teach in this workshop, inputs are props. And in this workshop currently, I don't call out context separately. I guess it's a content. Values from context are not props, they're coming from a hook. So I think it could be helpful for me to call that out separately in the future. But yeah, data coming from a context, absolutely applies as well. Actually, you might not intuitively have thought of this, but I list user interaction events as inputs as well. The user is inputting a click, a tap here, or typing text there. And that results in, yeah, changes to the component. When the user does this, puts this in, something comes out. Outputs include the rendered UI and also calls to function props. So if a prop is past, sorry, if a function is passed in as a prop, or from a context or from a hook or something like that, if the component calls that function, that's a call, a method call, a function call going out into the rest of the application. And as we go through testing these, you'll see how we can assert that when certain input comes out, a function call comes up the other side, potentially with arguments that go along with it. Yeah, it occurs to me that actually web service return values should go in here as well. So we'll look at that as we go. So these couple of inputs and outputs are going to form the structure of what we focus on for most of the workshop together. So let's go ahead and start diving in and seeing how we can use React Native Testing Library to test inputs and outputs like this. First, we're going to start with rendered UI.
Comments