Madyson  Reilly

Madyson Reilly

1612247935

React Enzyme vs. React Testing Library

Comparing two contrasting libraries for testing React components

For a long time, when testing React components, we were stuck with Enzyme. There was no other choice. Recently, a new player called the React Testing Library joined the frontend testing realm. We have seen it start to gain some real traction.

So when should you use one vs. the other? What purpose does each one serve? Let’s compare Enzyme to the React Testing Library and see what they are both about. We will do a proper comparison by covering:

  • Basics: Warming up and learning a bit about each library.
  • Setup: How easy is it to install each one?
  • Different mindset: What is their take on testing?
  • Snapshot testing: What is it and why should you care?
  • Examples: Some actual code that reflects the difference between both libs.
  • Wrap up: Final thoughts.

#react #web-development #javascript #programming #testing

What is GEEK

Buddha Community

React Enzyme vs. React Testing Library
Autumn  Blick

Autumn Blick

1598839687

How native is React Native? | React Native vs Native App Development

If you are undertaking a mobile app development for your start-up or enterprise, you are likely wondering whether to use React Native. As a popular development framework, React Native helps you to develop near-native mobile apps. However, you are probably also wondering how close you can get to a native app by using React Native. How native is React Native?

In the article, we discuss the similarities between native mobile development and development using React Native. We also touch upon where they differ and how to bridge the gaps. Read on.

A brief introduction to React Native

Let’s briefly set the context first. We will briefly touch upon what React Native is and how it differs from earlier hybrid frameworks.

React Native is a popular JavaScript framework that Facebook has created. You can use this open-source framework to code natively rendering Android and iOS mobile apps. You can use it to develop web apps too.

Facebook has developed React Native based on React, its JavaScript library. The first release of React Native came in March 2015. At the time of writing this article, the latest stable release of React Native is 0.62.0, and it was released in March 2020.

Although relatively new, React Native has acquired a high degree of popularity. The “Stack Overflow Developer Survey 2019” report identifies it as the 8th most loved framework. Facebook, Walmart, and Bloomberg are some of the top companies that use React Native.

The popularity of React Native comes from its advantages. Some of its advantages are as follows:

  • Performance: It delivers optimal performance.
  • Cross-platform development: You can develop both Android and iOS apps with it. The reuse of code expedites development and reduces costs.
  • UI design: React Native enables you to design simple and responsive UI for your mobile app.
  • 3rd party plugins: This framework supports 3rd party plugins.
  • Developer community: A vibrant community of developers support React Native.

Why React Native is fundamentally different from earlier hybrid frameworks

Are you wondering whether React Native is just another of those hybrid frameworks like Ionic or Cordova? It’s not! React Native is fundamentally different from these earlier hybrid frameworks.

React Native is very close to native. Consider the following aspects as described on the React Native website:

  • Access to many native platforms features: The primitives of React Native render to native platform UI. This means that your React Native app will use many native platform APIs as native apps would do.
  • Near-native user experience: React Native provides several native components, and these are platform agnostic.
  • The ease of accessing native APIs: React Native uses a declarative UI paradigm. This enables React Native to interact easily with native platform APIs since React Native wraps existing native code.

Due to these factors, React Native offers many more advantages compared to those earlier hybrid frameworks. We now review them.

#android app #frontend #ios app #mobile app development #benefits of react native #is react native good for mobile app development #native vs #pros and cons of react native #react mobile development #react native development #react native experience #react native framework #react native ios vs android #react native pros and cons #react native vs android #react native vs native #react native vs native performance #react vs native #why react native #why use react native

Chumarat Pat

Chumarat Pat

1599639298

Interaction Testing with React Testing Library

Testing is complicated. I’ve certainly never been good at it. For the longest time, I’ve only been focused on basic function input-output unit tests. Why? Because they were easy — you didn’t need to render HTML, you didn’t need to query DOM elements, you didn’t need to interact with said DOM elements. But of course, React component testing is a necessity for any mature codebase. And it finally came time for me to sit down and figure it out.

That’s when I discovered React Testing Library. And suddenly, everything seemingly became much simpler. All the complexities that I’ve encountered, but not understood, that made me put off React component testing disappeared. Hopefully, the same will happen for you.

#react-testing-library #unit-testing #react #jest #interaction-testing

Alayna  Rippin

Alayna Rippin

1597168800

Test Driven Development (TDD) with React Testing Library & Mock Service Worker

Let’s step up our testing game with two useful libraries that lend themselves excellently to a TDD approach.

Setting up

Whenever I want to try out something React-related, I use the library create-react-app. It gives you a ready-to-work-with basic React application with no configuration needed. Recent versions also come bundled with React Testing Library, so if you use the latest create-react-app, you can start using React Testing Library straight away. If not — install @testing-library/react and @testing-library/jest-dom in your existing React application.

I am going to implement the following functionality: a simple recipe list with a search function. It will look something like this to a user in a mobile browser:

Image for post

Image credits: Burger Photo by Robin Stickel on Unsplash, French Toast Photo by Joseph Gonzalez on Unsplash, Salmon Photo by Casey Lee on Unsplash

Starting with a failing test

I want to use a TDD approach, so let’s start with a failing test. At this point, there is no component yet, so of course whatever test we write is going to fail. But let’s start small; I want a component named ‘Recipes’ that renders the expected heading text. Here is my test for that expectation:

	import React from 'react';
	import { render, screen } from '@testing-library/react';

	test('renders the heading', () => {
	  render(<Recipes />);

	  expect(screen.getByRole('heading')).toHaveTextContent('Recipe Finder');
	});

React testing library exports a render method, which will render a component and all of its child components. It also exports a screen object, holding a number of queries we can use to select different elements in our rendered component (and its child components too). The **getByRole **query lets me select the heading element and make an assertion on its text content.

Why select the heading element by its role and not for example a CSS class? The guiding principle of React Testing Library is “The more your tests resemble the way your software is used, the more confidence they can give you.” Therefore, we want to write our tests as close as possible to how the ultimate tester — the end user — will be using the application. Users don’t see CSS classes or data attributes; they interact with text, label text and semantic elements and roles. Using queries such as getByRole also encourages us to write accessible code, since these selectors are available to everyone, including users of screen readers.

Making the test pass

Our first test fails as expected.** Recipes is not defined.** But this is the first step in TDD — a failing test. Now, let’s make it pass by writing the simplest possible component with the correct heading and then importing it in our test file. Now, let’s re-run the test. It passes!

	import React from 'react';

	const Recipes = () => {
	  return (
	    <div>
	      <h1>Recipe Finder</h1>
	    </div>
	  )
	};

	export default Recipes;

Using further queries, we can make similar expectations for the input element and the “Find” button. The button also has a role, but for the input field, I will use the getByPlaceholderText query, since that is probably the closest query to how the user would find it on the page.

Start with a failing test…

	import React from 'react';
	import { render, screen } from '@testing-library/react';
	import Recipes from './Recipes';

	test('renders the heading, input field and button', () => {
	  render(<Recipes />);

	  expect(screen.getByRole('heading')).toHaveTextContent('Recipe Finder');
	  expect(screen.getByPlaceholderText('Enter an ingredient to find recipes...'))
	    .toBeInTheDocument();
	  expect(screen.getByRole('button')).toHaveTextContent('Find');
	});

… and implement the changes necessary to make it pass:

	import React from 'react';

	const Recipes = () => {
	  return (
	    <div>
	      <h1>Recipe Finder</h1>
	      <form>
	        <input 
	          type="text" 
	          name="ingredient"
	          placeholder="Enter an ingredient to find recipes..." 
	        />
	        <button type="submit">Find</button>
	      </form>
	    </div>
	  )
	};

	export default Recipes;

This way, we know what we expect from our code and more importantly — we will know if we break any functionality if the previously passing tests suddenly fail.

An important step in TDD is the refactor step, where we improve our code to for example make it easier to read, become more efficient and remove any duplication. The test should still pass after we refactor.

Setting up our mocks

When the application first renders, I want to display a list of all my recipes, just like in the visual design above. This requires some kind of communication with an API. We are going to use Mock Service Worker to mock the HTTP-requests, so that we can control the response data. Install Mock Service Worker with npm like this:

npm install msw --save-dev

With Mock Service Worker, we are not mocking a specific module (unlike if we were to use Jest.mock), which means that it makes no difference if I use fetch or a third-party library such as axios to get the data. This makes it incredibly flexible. Let’s add the following imports to our test file:

import { rest } from 'msw';
import { setupServer } from 'msw/node';

Here is how I set up mocking a call to the recipe list endpoint:

	import React from 'react';
	import { render, screen } from '@testing-library/react';
	import Recipes from './Recipes';
	import { rest } from 'msw';
	import { setupServer } from 'msw/node';

	const allRecipes = [
	  { id: 1, title: 'Burger' }, 
	  { id: 2, title: 'French toast' }, 
	  { id: 3, title: 'Salmon' }
	];

	const server = setupServer(
	  rest.get('/api/recipes', (req, res, ctx) => {
	    return res(ctx.json({ recipes: allRecipes }));
	  })
	);

	beforeAll(() => server.listen());

afterAll(() => server.close());

If you have worked with NodeJS and Express, the syntax looks very familiar. GET requests to ‘/api/recipes’ will respond with JSON containing the allRecipes array, just like a real API would. These two lines make sure the server starts listening (intercepting) before the tests run and closes its connection when the tests in this file have finished running:

beforeAll(() => server.listen());
afterAll(() => server.close());

#tdd #react-testing-library #react #test-driven-development #testing

Jeremy  Reilly

Jeremy Reilly

1603955580

Simulate Browser Interactions with Testing Library’s UserEvent

My Journey

Like most, when I first started using Testing LibraryI used Fire Event to test component interactions. After all, this API shipped with the library itself and was used in the test examples in the documentation. But I soon discovered that Fire Event had serious limitations. I would try clicking something and the expected effect did not happen. Why?

Browser Events

To understand this issue, we need to better understand browser events. When a user clicks something in their browser, multiple events are triggered — mouseDownmouseUpclick, and focus. Similarly, when typing something, the keyDownkeyUp, and keyPress events all trigger! Because a single user interaction could trigger multiple events, developers have multiple options for implementation. This is where I ran into my issue.

Fire Event

Fire Event, unfortunately, requires you to use the method for the corresponding event handler to trigger. If an element has an onClick event handler, I have to use fireEvent.click; if an element has an onMouseDown event handler, I have to use fireEvent.mouseDown. In other words, I need to know the exact implementation of the event handler to successfully use fireEvent.

#react #jest #integration-testing #unit-testing #react-testing-library #react native

Lilyan  Streich

Lilyan Streich

1605680732

Performing Unit Testing With React JS Components Using Jest &amp; Enzyme

In this tutorial, we will be looking into how to set up and add unit tests to React components using Jest and Enzyme. Jest and Enzyme are different tools, both together to provide flexible and creative testing abilities.

What is Jest?

Jest is a JavaScript-based framework for testing React, React Native and other JavaScript-based applications. In many cases, unit tests don't provide accurate results when run on the frontend of any software. Jest reduces this issue by allowing you to write faster, more effective front-end tests.

What is Enzyme?

Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output. You can also manipulate, traverse, and in some ways simulate runtime given the output.

Before we start to write the test, we need to set up the react application. Here I have used create-react-app for setting up the React application.

$ npm install create-react-app

Now we can create the react app using the following command,

$ npm init react-app my-react-app

Now we can change the directory to the new React app directory created and start the development server like following,

$ cd my-react-app/
$ npm start

Now you can see the confirmation message of a compilation of app and port number of React application, using this port number we can access the react application.
 

Setting up Jest and Enzyme

Add the following npm packages into the package.json file to set up the jest and enzyme.

"babel-jest": "^25.1.0",
"jest": "^25.1.0",
"jest-cli": "^25.1.0",
"enzyme": "^3.11.0"
"enzyme-adapter-react-16": "^1.15.2"

Now you can run npm install to install the packages in our application. After installing now we need to update package.json file like following,

...
"scripts": {
   "start": "react-scripts start",
   "build": "react-scripts build",
   "test": "jest"
},
…

Now we can create a __test__ folder under src directory to write all the testings.

Snapshot Testing with Jest

Snapshot tests are a very useful tool whenever you want to make sure your UI doesn’t go unexpectedly. Jest takes the component for testing, renders it, and then takes a snapshot of what the component should look like.
When you run the tests for the first time, notice that a new snapshot file is created inside a __snapshots__ directory. Since here the test file is named Title.test.js, the snapshot file is appropriately named Title.test.js.snap that looks like this:
Consider the following Title.js component.

import React, { Component } from 'react';
export default class Title extends Component {
 render() {
 return (
  <h1 style={{textAlign: 'center'}}>{this.props.text}</h1>
  )
 }
}

Title.test.js

import React from 'react';
import renderer from 'react-test-renderer';
import Title from '../Title';
describe("Title Component", () => {
 it('should render the component correctly', () => {
  const tree = renderer.create(<Title text="Employees List" />).toJSON();
  expect(tree).toMatchSnapshot();
 });
});

When we run the test first time, it will create the snapshot file (Title.test.js.snap) under __snapshots__ directory with the following code.

/exports[`Title Component should render the component correctly 1`] = `
<h1
 style={
  Object {
  "textAlign": "center",
  }
 }
>
 Employees List
</h1>
`;

When continuing to work on your project, every time you run your test suite, Jest will do the process over again and compare the old snapshot to a new one. If the snapshots do not match, then it shows an error message in the terminal and highlights the parts that do not match. For example, now I will change the Title.test.js component like following,

import React from 'react';
import renderer from 'react-test-renderer';
import Title from '../Title';
describe("Title Component", () => {
 it('should render the component correctly', () => {
  const tree = renderer.create(<Title text="Employee Information" />).toJSON();
  expect(tree).toMatchSnapshot();
 });
});

Then we run the test it will return the error like following,
unit testing react js
Now, we have updated the title text, it’s reasonable to expect changes in the snapshot for this component. Our snapshot test case is failing because the snapshot for our updated component no longer matches the snapshot for this test case.
To resolve this, we will need to update our snapshot. You can run Jest with a flag that will tell it to re-generate snapshots:
$ jest src/__tests__/Title.test.js –updateSnapshot
It will update the snapshot file and run the snapshot test successfully.
output unit testing react js components

Testing Component Render with Enzyme API

To test the component rendering and get the specific element of the component we need the enzyme API. The following three different methods we can render the React component,

  1. Shallow rendering
  2. Full rendering
  3. Static rendering

Now we can configure the enzyme adapter to use the enzyme APIs, create a file setupTests.js under src directory and add the following code,

import Enzyme from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
Enzyme.configure({ adapter: new Adapter() })

Now you can create jest.config.js file under the root directory and add the following line,

module.exports = {
  "moduleNameMapper": {
    "\\.(css|less|scss)$": "identity-obj-proxy"
  },
  "setupFilesAfterEnv": ["/src/setupTests.js"]
}

Shallow rendering

When writing unit tests for React, shallow rendering can be helpful. We can use the shallow rendering to an initial state of component testing. It renders a component “one level deep” and enables the inspection of the component’s contents as well as the simulation of user interaction. Shallow render does not worry about the behavior of child components, which are not instantiated or rendered. Shallow rendering does not require the DOM.
For example, consider the App.js component on my example,

import React from 'react';
import EmployeeList from './EmployeeList';
import Title from './Title';
function App() {
  const data = [
   { id: 'INC001', name: 'John', role: 'CEO' },
   { id: 'INC002', name: 'Ragavi', role: 'Director' },
   { id: 'INC004', name: 'Peter', role: 'Junior Engineer' }
 ];
const columns = [
 { Header: 'Employee ID', accessor: 'id' },
 { Header: 'Name', accessor: 'name' },
 { Header: 'Designation', accessor: 'role' }
];
return (
 <div>
   <Title text="Employees List" />
   <EmployeeList data={data} columns={columns} />
 </div>
 );
}
export default App;

Now we can assert the component like following (App.test.js)

import React from 'react';
import { shallow } from 'enzyme';
import App from '../App';
import Title from '../Title';
let wrapper;
beforeEach(() => {
  wrapper = shallow(<App />);
});
describe("App Component", () => {
  it('It should render Title Component Once', () => {
    expect(wrapper.find(Title)).toHaveLength(1);
  });
 it('should have one <h1> tag', () => {
   expect(wrapper.find('h1')).toHaveLength(1);
 });
});

Now we can open the terminal and navigate to the project root directory and run the App.test.js file,

$ jest src/__tests__/App.test.js

Now we can see the result like below,

Shallow_rendering

We can see 1 test has passed, which is to check the rendering of <Title> component, because <Title> is a child of <App> component. But the check to render of <h1> failed because it is a child of Title component. The shallow method does not render the <h1> element inside <Title> component, which is why this test fails. As earlier the shallow is not worried about the child components’ behavior.

Full Rendering (mount)

The full rendering is the only way to test the React component lifecycle methods (componentDidMount, etc). It will render the full DOM including the child components of the parent component of running the tests.
Full DOM rendering requires that a full DOM API be available at the global scope. This means that it must be run in an environment that at least “looks like” a browser environment. If you do not want to run your tests inside of a browser, the recommended approach to using mount is to depend on a library called jsdom which is essentially a headless browser implemented completely in JS.
Now we can change the App.test.js component like following and running the test it will pass all the test cases.

import React from 'react';
import { mount } from 'enzyme';
import App from '../App';
import Title from '../Title';
let wrapper;
beforeEach(() => {
  wrapper = mount(<App />);
});
describe("App Component", () => {
  it('It should render Title Component Once', () => {
    expect(wrapper.find(Title)).toHaveLength(1);
  });
  it('should have one <h1> tag', () => {
    expect(wrapper.find('h1')).toHaveLength(1);
  });
});

full_rendering

Now the 2 test cases are passed because the mount renders all the child components. Unlike shallow or static rendering, full rendering actually mounts the component in the DOM, which means that tests can affect each other if they are all using the same DOM. Keep that in mind while writing your tests and, if necessary, use unmount() or something similar to cleanup.

Static Rendering

Enzyme’s render function is used to render React components to static HTML and analyze the resulting HTML structure. It only calls render but renders all the children. The render function behaves the same as shallow and mount but render does not have access to React lifecycle methods.
Now we can change the App.test.js like following,

import React from 'react';
import { render } from 'enzyme';
import App from '../App';
import Title from '../Title';
let wrapper;
beforeEach(() => {
  wrapper = render(<App />);
});
describe("App Component", () => {
  it('should have one <h1> tag', () => {
    expect(wrapper.find('h1')).toHaveLength(1);
  });
});

Now we can run the test, then we will see the result like below,
render_result
We can see the test has passed because the render method only returns the plain HTML content.
We have looked at how to set up the jest in react application, writing the snapshot testing and integrating the Enzyme for unit testing the React component. You can get all the code from Github to run the test locally.

Originally published by Arjunan Subramani at agiratech.com

#react js #jest & #enzyme #react #react app