The Art of ‘Humble Views’: Testing React Native Apps the Smart Way

Rate this content
Bookmark

In this talk, we explore the divisive world of testing, where developers often find themselves torn between writing no tests and striving for 100% test coverage. Learn how to navigate these polarizing positions and adopt a more nuanced strategy that makes testing efficient and effective.We'll dive into the concept of 'Humble Views,' where we minimize untestable objects by extracting logic from UI elements into test-friendly parts of the codebase. This approach simplifies testing, focusing on business logic instead of UI complexities. Discover how the Model-View-Presenter (MVP) architecture helps achieve this, with presenters serving as a logical layer for testing and hooks aiding in separating logic from UI components.Throughout the talk, we'll discuss the trade-offs of this approach, the role of End-to-End (E2E) tests, and how to strike the perfect balance between too much and too little testing. Join us as we delve into the art of creating 'Humble Views,' ensuring that our React Native apps are scalable, maintainable, and effectively tested!

This talk has been presented at TestJS Summit 2023, check out the latest edition of this Tech Conference.

FAQ

Mo's talk focused on the concept of 'humble views' and how to architect React and React Native applications to make them easier to test and more scalable.

Mo is the head of the mobile team in the UK for Theodo, a global consultancy with over 700 digital experts. He specializes in React and React Native applications.

The two main architectural patterns discussed are the Humble Object model and the Model-View-Presenter (MVP) pattern.

The Humble Object model involves separating business logic from the component and placing it into its own module or file, making it easier to test critical components quickly.

The MVP pattern separates the GUI into three parts: the model (business logic and data fetching), the view (passive view that renders based on input), and the presenter (contains UI state and logic). This makes the view easier to test.

Testing is contentious because there are polarized views: some believe in aiming for 100% test coverage as a cornerstone of quality, while others claim that skipping tests can speed up development.

The 'one hook per screen' rule suggests that each screen or component should only call a single custom hook, which helps in organizing code and making it easier to test.

Mo suggests isolating business logic into humble objects and using a presenter layer to create easily testable passive views. This approach reduces dependencies and simplifies testing.

These architectural patterns help in reducing the complexity of testing, organizing code better, and making applications more scalable and maintainable.

Mo views his role as an educator and mentor, aiming to teach his team good practices and set them up for success rather than imposing strict rules.

Mo Khazali
Mo Khazali
32 min
07 Dec, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

This Talk discusses the challenges of testing in React and React Native applications, particularly with regards to barcode scanning. It explores the violation of separation of concerns in React and proposes the use of the HumbleObject model to simplify testing and improve code cleanliness. The MVP model is also introduced as a way to separate UI state and logic from the component. The importance of following patterns, standardization, and teaching principles is emphasized, along with the benefits of using custom hooks to share business logic. The potential of AI tools in code refactoring is mentioned as well.

1. Introduction to Humble Views and Testing

Short description:

Hello, everyone. Thank you so much, Nathaniel. That was honestly a very kind introduction. Today I'm excited to be in Berlin talking about humble views in React and React Native applications. I head the mobile team in the UK for Theodo, a global consultancy with expertise in React and React Native. Testing is a contentious topic with different viewpoints, from aiming for 100% test coverage to not testing at all.

♪♪♪ Hello, everyone. Thank you so much, Nathaniel. That was honestly a very, very kind introduction. I feel humbled. Come on. All right, dad jokes don't land very well here. Good to know.

All right, okay. So today I'm very excited to be in Berlin with you all. It's my first time in the city, and it is so aesthetically pleasing. The vibes are honestly immaculate, especially with the snow. I'm very excited to be talking about this concept of humble views. We're going to be looking at how you can architect your React and React Native applications to hopefully make it a bit easier to test and also make your applications more scalable.

A little bit about me. Like Nathaniel mentioned, my name is Mo. I head the mobile team in the UK for Theodo. So Theodo is a global consultancy with over 700 digital experts, 150 of which do React Native slash React. So we've been doing React and React Native from the very early days of when they came out. And as a result, we've kind of gone through phases of evolving and seeing different code bases and seeing different patterns and trying to find ones that last a long time and are scalable and hopefully we can share some of that with you today.

So testing is a contentious topic. People typically fall into two camps. If you go down the software crafts person route, you get the likes of Bob Martin, who deeply believed that you need to be aiming for 100% test coverage, that high test coverage is the cornerstone of a good quality code base. So this is the traditional view, and this is the view that the software crafts person will tell you. More recently, on the other side, though, you've got YouTube influencers in the coding space who will tell you, you know what? I've not been testing for years and I've been so fast, you can never catch up with me. I worked at Twitch, trust me, bro. And so you get these like different viewpoints and you get people that are vehemently anti-testing and you get people that are very, very protesting. And so, as with many things in life these days, things get polarized to the very, very extreme. On the left, you've got the people that say, don't test. And if you test, don't ever talk to me again. And then on the right, you've got people saying, your code is bad, you should be testing every single bit of it.

2. Challenges with Barcode Scanner Testing

Short description:

You've got this testing no man's land in the middle where all nuance is lost. I'm aiming to annoy both parties with one talk. Let me set the scene: a React Native project in the fashion industry. A developer wanted to test the barcode scanner but faced challenges with setup. Multiple contexts and mocks were required for testing.

And really, what happens is you've got this testing no man's land in the middle where all nuance is lost. And they sometimes throw tomatoes at each other from either side. But really, you don't get much nuanced conversations around a pragmatic testing approach. And I fancy myself a bit of a centrist. I don't stand for anything. So I'm aiming to annoy both parties with one talk. We'll see how this goes.

Let me set the scene a little bit. So a couple years ago, I was working on a React Native project in the fashion industry. The app was going to be used in warehouses where they were going to scan items of clothing with a barcode scanner inside of the app. And it would store some information. They could enter in some information about the article of clothing. And it was being used by the back office, effectively. There was a developer on my team who was working a lot on the front end stuff. And she came to me at one point and was like, I'm trying to write a test for the barcode scanner. Basically, what I want to test is every single barcode has a checksum. The last few digits will be a sum of some of the values in the middle in some sort of mathematical formula. So I want to test that. But the challenge that she found was that she was needing to do so much setup before she could actually test that by rendering the screen. And what do I mean by that? I've actually went and extracted the code and you'll see how horrifying it is in just about a second. But this screen initially had a bunch of different contexts. And we didn't really need them for the screen itself. But it needed to be mocked so that they could go ahead and test it. Cool. So that's a bunch of mocks. Then some of the clients needed to be mocked for the fetch requests. Expo's barcode scanner, which was an external library that uses the native device, needed to be mocked as well because you don't have access to that in unit tests. Your navigation framework on the native layer needed to be mocked. All right. That's more mocks.

QnA

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Test Effective Development
TestJS Summit 2021TestJS Summit 2021
31 min
Test Effective Development
Top Content
This Talk introduces Test Effective Development, a new approach to testing that aims to make companies more cost-effective. The speaker shares their personal journey of improving code quality and reducing bugs through smarter testing strategies. They discuss the importance of finding a balance between testing confidence and efficiency and introduce the concepts of isolated and integrated testing. The speaker also suggests different testing strategies based on the size of the application and emphasizes the need to choose cost-effective testing approaches based on the specific project requirements.
We May Not Need Component Testing
Vue.js Live 2024Vue.js Live 2024
26 min
We May Not Need Component Testing
Component testing is a gray area between integration and unit testing. The demo app focuses on the cart component and writing test cases for Playwright component test and VTest. The first cart test encounters a bug with the invisible method in View Test.
Component Testing With Vitest
TestJS Summit 2023TestJS Summit 2023
29 min
Component Testing With Vitest
This Talk explores the challenges of choosing and learning testing frameworks, emphasizing the importance of planning, automation, and prioritizing unit testing. The VTEST framework is introduced as a fast and stable option for unit testing JavaScript and TypeScript code, with a focus on logic and mocking external dependencies. The Talk also covers testing React hooks, integration testing with TestingLibraryReact, component testing, and achieving code coverage. Best practices include performing accessibility tests, planning tests before coding, and using data test IDs for stability.
It's a (Testing) Trap! - Common Testing Pitfalls and How to Solve Them
TestJS Summit 2021TestJS Summit 2021
20 min
It's a (Testing) Trap! - Common Testing Pitfalls and How to Solve Them
This Talk explores the pain points and best practices in software testing, emphasizing the importance of simplicity and comprehensibility in test design. It discusses techniques such as the three-part rule for test titles, the triple-A pattern for test structure, and the use of clear and descriptive names in tests. The Talk also highlights the traps of testing implementation details and using fixed waiting times. The speaker encourages teamwork and learning from experience to improve testing practices.
How to Catch a11y Defects During Unit and E2E Testing
TestJS Summit 2021TestJS Summit 2021
7 min
How to Catch a11y Defects During Unit and E2E Testing
This Talk provides ways to catch accessibility defects during testing, including adding accessibility testing to a website for Studio Ghibli using React, NX, Jazz, JazzX, Cypress, and CypressX. The importance of unitizing components and conducting end-to-end testing with Cypress and CypressX is emphasized to ensure accessibility. The process of setting up CypressX testing is explained, highlighting the use of typings and the CypressX support file. These tools make it easier for developers to avoid accessibility bugs during development.
Unit Testing Angular Applications
TestJS Summit 2022TestJS Summit 2022
24 min
Unit Testing Angular Applications
This talk explores unit testing in Angular applications, covering topics such as testing front-end applications, specifics of testing Angular, best practices, and educational resources. It discusses the anatomy of a unit test in both Jasmine and Jest, the setup and initial tests in Angular, testing user interaction and event handlers, testing rendered output and change detection, and unit testing parent components with child components. It also highlights best practices like using test doubles, testing components with dependency injection, and considerations for unit testing. Code coverage is emphasized as a metric that doesn't guarantee bug-free code.

Workshops on related topic

Learn To Use Composables: The Swiss Army Knife Of Vue Developers
Vue.js Live 2024Vue.js Live 2024
163 min
Learn To Use Composables: The Swiss Army Knife Of Vue Developers
Workshop
Juan Andrés Núñez Charro
Juan Andrés Núñez Charro
Composables (composition functions) are stateful/stateless functions that can leverage Vue's reactivity API, decoupling it from components.This shift in perspective opens the possibility for tackling common scenarios in a new and creative way. In this workshop, you will learn how to solve typical problems every Vue developer faces, using composables:
- Data store;- Component cross-communication;- Utility functions (DOM, API, etc);And more.
Best Practices and Advanced TypeScript Tips for React Developers
React Day Berlin 2022React Day Berlin 2022
158 min
Best Practices and Advanced TypeScript Tips for React Developers
Workshop
Maurice de Beijer
Maurice de Beijer
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.
In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
Introduction to React Native Testing Library
React Advanced Conference 2022React Advanced Conference 2022
131 min
Introduction to React Native Testing Library
Workshop
Josh Justice
Josh Justice
Are you satisfied with your test suites? If you said no, you’re not alone—most developers aren’t. And testing in React Native is harder than on most platforms. How can you write JavaScript tests when the JS and native code are so intertwined? And what in the world are you supposed to do about that persistent act() warning? Faced with these challenges, some teams are never able to make any progress testing their React Native app, and others end up with tests that don’t seem to help and only take extra time to maintain.
But it doesn’t have to be this way. React Native Testing Library (RNTL) is a great library for component testing, and with the right mental model you can use it to implement tests that are low-cost and high-value. In this three-hour workshop you’ll learn the tools, techniques, and principles you need to implement tests that will help you ship your React Native app with confidence. You’ll walk away with a clear vision for the goal of your component tests and with techniques that will help you address any obstacle that gets in the way of that goal.you will know:- The different kinds React Native tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting text, image, and native code elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RNTL tests and how to handle them- Options for handling native functions and components in your JavaScript tests
Prerequisites:- Familiarity with building applications with React Native- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Native Testing Library- Machine setup: Node 16.x or 18.x, Yarn, be able to successfully create and run a new Expo app following the instructions on https://docs.expo.dev/get-started/create-a-new-app/