React Testing Library – a quick overview

React Testing Library is a part of the Testing Library (@testing-library) family of packages.The Testing Library helps us test the UI of our applications in a user-focused way, with its core library being the DOM Testing Library from which all other libraries within that family branch out or interact with. It is not specific to a single framework, and it supports React and React Native, Vue, Angular, and many more, even providing a plugin for end-to-end tests in Cypress. The philosophy of React Testing Library “The more your tests resemble the way your software is used, the more confidence they can give you.” What differentiates React Testing Library from other similar tools is its user interaction-focused testing. It doesn’t care about the implementation details, but only about replicating the way a real-world user would interact with the component or application in question. It is about as close as we can get to having a real user test our code. It is also worth mentioning that React Testing Library is a replacement for Enzyme, with the goal of solving issues a lot of developers had with using Enzyme, including its complexity and encouragement of bad testing practices. A fun fact about Enzyme and React Testing Library is that a lot of Enzyme maintainers also participated greatly in the creation of the React Testing Library. Features of React Testing Library Asynchronous handling React Testing Library is made to handle asynchronous actions like data retrieval and updating state. It waits for them to finish before checking if the outcome is as expected. If the outcome does not match, it provides a detailed user-friendly message so we can instantly tell where we went wrong. Functions React Testing Library provides a set of queries and utilities, or query and utility functions, which allow us to select specific elements based on their labels or texts, or even accessibility attributes and then simulate user interactions to make sure the outcomes are what we expect. Virtual DOM use It uses React’s rendering capabilities to render components in a virtual DOM and then works with the actual DOM nodes. Using the virtual DOM removes the need for a browser so the testing takes less time. Jest integration React Testing Library also integrates with Jest, which gives us custom matchers, or assertion functions, to assert the code is behaving as predicted. Jest is a comprehensive testing framework that provides a structured and organized environment for writing tests. Its functionalities include test execution, assertion libraries, and reporting mechanisms. It provides snapshot testing, which works by taking a snapshot of the rendered components, and then comparing them in each of the next runs to look for any mismatches. One key Jest’s feature is its mocking capability, which allows us to isolate components during testing, so we know exactly where an issue pops up, and in which component. We provide a mock version of the data and behaviors around the component, to see how the component behaves. Integrating Jest with React Testing Library is fairly easy, and has only a handful of requirements: The jest-dom library actually provides the custom matchers and enables us to extend Jest. And don’t be fooled, jest-dom was not made for React Testing Library specifically; it can be used with any framework that returns DOM elements from queries. The importance of testing your code It is imperative to understand the importance of testing your code. For starters, yes, it is important to catch any bugs and errors in the code. By catching bugs while still developing the code, we make it less likely that they end up in production. In order to write the tests for individual components we need the code to be modular and isolated, which encourages us to improve the code quality, making the code cleaner and more maintainable. It also helps us identify overcomplicated and tightly coupled parts of code. By nature, tests have greater readability than the code itself. They tend to be smaller, focus on specific scenarios or behaviors, and state exactly what they expect to happen. That enables them to also serve as a form of documentation for the code. Another upside is that it makes it easier for new developers to get to know the code they’re just starting to work on. It also serves as a form of functionality protection for the existing code, because well-written thorough tests will catch a mistake in the code much easier. Tests might be a pain to write, but long term they make our code more trustworthy and us more confident in its success.
What is TypeScript?

TypeScript is a fairly new programming language. It was released in 2012 by Microsoft and since then it’s become widely used. It’s taken over a good portion of the frontend in large-scale applications, and all it is is a new and improved version of JavaScript. The nice thing about TypeScript is that it’s completely interchangeable with JavaScript. In fact, any TypeScript code you write can be translated into native JavaScript code. That means that you can use any JavaScript inside of TypeScript, and use all of the features of TypeScript as well. Then when it actually comes the time to run your code, it will get translated into a native JavaScript file which you can then run. This is really powerful because it means that if you want to change JavaScript files to TypeScript files, it’s really easy to do that, and the same goes for the other direction (TypeScript to JavaScript). When and how to use it TypeScript is best for large-scale projects and enterprise-level applications. Using it for small-scale projects with one or two JS files may be overkill. On the other hand, when you have a lot of code in your program, many things going on, and multiple people contributing, TypeScript really shines because of the features it adds to JavaScript. If you know JavaScript, you pretty much already know TypeScript. Anything you can write in native JavaScript, almost line for a line you can write the exact same in TypeScript. Then the core feature it adds is actually the ability to add static typing to JavaScript. So this does not change the fact that JavaScript is a dynamically typed language and it doesn’t change that when it comes to actually running this code. But it means that when you’re writing TypeScript code, you have type enforcement and you can choose if you want to declare the type of variables, method parameters, return types, or whatever it may be. Transpiling In order to use TypeScript, it first needs to be converted into JavaScript. We call this conversion transpiling. You may have already come across compiling, which is a general term for taking source code written in one language and transforming it into another language. Transpiling is a specific way of compiling, which takes source code in one language and transforms it into a language with a similar level of abstraction. When we’re talking about compiling, especially in languages like Java, we usually mean translating the source code into something more machine-readable, i.e. something that the computer understands and can work with. When we’re talking about transpiling and similar levels of abstraction, that means that the level to which we are translating the code doesn’t change that much in terms of how machine-readable it is. There are multiple ways of transpiling TypeScript into JavaScript, all done in the background. One way is to let your IDE do that for you, usually via an extension to the IDE. The way you use the extensions can vary greatly. They can provide a UI to configure the various options, or they can use a tsconfig.json file to do so. And they can also provide a button for the conversion, do it automatically on save with their own file watchers, or provide a command to use it via the command line. Another way is to use TypeScript’s utility called tsc with which you can both create a tsconfig.json file, which contains the configuration for the transpiler, and also transpile the code. The last way is using a 3rd party tool like Babel. Babel is a popular transpiler for JavaScript code. It checks what code was written, which browsers we want to support, which features are working in which browsers, and what code needs to be transpiled. The importance of static typing The reason static typing is so important is that it comes with so many different advantages. When you have static typing and you have type enforcement, the first thing that’s a really big deal is that catching errors becomes a lot easier and writing bad code a lot harder. In a language like Python or JavaScript, that’s dynamically typed, almost all your errors are happening at runtime. Now, that’s not a good thing. You often don’t want to get your errors at runtime, because that means, first of all, that you have to figure out what exactly is happening at runtime. Which is more complicated than while compiling, but there are also chances that you may miss errors because they just haven’t run yet. With TypeScript, most of the errors that you’re commonly getting at runtime in a dynamically typed language are gone, because now these errors are being shown to you before you can run the program, so you are forced to fix them if you want to run the code. If you’re debugging something at runtime, you probably need a debugger, which you might not have access to or fully understand how to use, so it’s much harder to do that at runtime, with so many other things to consider. You have to track down where in your code that is actually happening from, and there are so many possible issues when you’re not catching these bugs while compiling. And when you’re working on large-scale software that’s going out to clients and users, you want to make sure that you caught and fixed all those bugs, and that you’re getting them in your IDE before you actually go to the software. Work smarter, not harder The idea is that if you give your IDE more information about your code, it can do more work for you. If you can have your IDE carry a lot of the weight and do a lot of the work, you’re saving yourself both time and money, to actually code. You want to get that done as fast and precise as possible, and that is the core advantage of TypeScript. Optional typing TypeScript comes with a lot of other really great features too,