npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-test

v0.21.1

Published

Expressive testing library for React to make sure your code works as expected. Write better code, ship fewer bugs.

Downloads

229

Readme

React Test npm install react-test test badge gzip size

Expressive testing library for React to make sure your code works as expected:

import $ from "react-test";

it("increments when clicked", async () => {
  const counter = $(<Counter />);
  expect(counter).toHaveText("0");
  await counter.click();
  expect(counter).toHaveText("1");
});

The react-test syntax follows a similar schema to jQuery so it's very easy to write expressive tests. It also adds some Jest matchers (if you are using Jest) for convenience.

Early package! We are looking for beginner Open Source contributors! ❤️

Getting Started

First you'll need a working React project. As an example you can start a working React project with Create React App:

npx create-react-app my-app
cd my-app

Then install react-test. It is only needed for development:

npm install react-test --save-dev

Finally you can write tests. Let's say you have the <Counter /> component from this example and you want to test it to make sure it works as expected:

// src/Counter.js
import React, { useState } from "react";

export default function Counter() {
  const [counter, setCounter] = useState(0);
  const increment = () => setCounter(counter + 1);
  return <button onClick={increment}>{counter}</button>;
}
// src/Counter.test.js
import React from "react";
import $ from "react-test";
import Counter from "./Counter";

describe("Counter.js", () => {
  it("is initialized to 0", () => {
    const counter = $(<Counter />);
    expect(counter.text()).toBe("0");
  });

  it("can be incremented with a click", async () => {
    const counter = $(<Counter />);
    await counter.click();
    expect(counter.text()).toBe("1");
  });

  it("can be incremented multiple times", async () => {
    const counter = $(<Counter />);
    await counter.click();
    await counter.click();
    await counter.click();
    expect(counter.text()).toBe("3");
  });
});

Finally run the tests with Jest:

npm run test

Basics of testing

React applications are divided in components, and these components can be tested either individually or in group. Self-contained components are easier to test, document and debug.

For example, a plain button can be defined with a callback function, and change colors depending on the primary attribute:

import React from "react";

export default function Button({ primary, onClick, children }) {
  const background = primary ? "blue" : "gray";
  return (
    <button onClick={onClick} style={{ background }}>
      {children}
    </button>
  );
}

Then we can test it with react-test by creating a Button.test.js file and adding some assertions:

import React from "react";
import $ from "react-test";
import Button from "./Button";

describe("Button.js", () => {
  it("has different backgrounds depending on the props", () => {
    const $button = $(<Button>Hello</Button>);
    expect($button).toHaveStyle("background", "gray");
    const $primary = $(<Button primary>Hello</Button>);
    expect($primary).toHaveStyle("background", "blue");
  });

  it("can be clicked", async () => {
    const fn = jest.fn();
    const $button = $(<Button onClick={fn}>Hello</Button>);
    expect(fn).not.toBeCalled();
    await $button.click();
    expect(fn).toBeCalled();
  });

  // FAILS
  it("cannot be clicked if it's disabled", async () => {
    const fn = jest.fn();
    const $button = $(
      <Button onClick={fn} disabled>
        Hello
      </Button>
    );
    await $button.click();
    expect(fn).not.toBeCalled(); // ERROR!
  });
});

Great! All of our tests are working except for the last one. Now we can go back to our component and fix it:

import React from "react";

export default function Button({ primary, onClick, children, ...props }) {
  const background = primary ? "blue" : "gray";
  return (
    <button onClick={onClick} style={{ background }} {...props}>
      {children}
    </button>
  );
}

Concepts

Matched nodes

When we talk about "the first element" or "the elements matched" we always refer to the top-level element (unless specified differently). So in this example:

const list = $(
  <ul>
    <li>A</li>
    <li>B</li>
  </ul>
);

The first element, which is the same as the matched nodes, is the ul and not the . We can always "go down a level" with the proper DOM navigation methods:

const list = $(...);  // The node <ul>
const items = list.children();  // An array of <li> nodes

In this case the matched nodes of list is an array containing only the <ul>, while the matched nodes for items is an array with both of the <li>.

This is very important for many things, e.g. if you are trying to .filter() the <li> you need to use items and not list, same as if you want to get the first <li>'s Node:

list.get(0); // <ul>...</ul> ~> The whole thing
items.get(0); // <li>A</li>   ~> The first item
items.get(1); // <li>B</li>   ~> The second item
items.get(-1); // <li>B</li>   ~> The last item

FAQ

Is this an official Facebook/React library?

No. This follows the community convention of calling a library related to React as react-NAME. It is made by these contributors without any involvement of Facebook or React.

How can I contribute?

Thanks! Please read the Contributing Guide where we explain how to get started with the project. Right now there are some beginner-friendly issues so please feel free to implement those!

I will try to help as much as possible on the PRs.

I have a problem, how do I fix it?

Don't sweat it, just open an issue. React Test is in an early phase with incomplete documentation so feel free to read the code or ask directly in the issues.

This will change once the library is more stable, there's more documentation and if the community grows (maybe a chat, or reddit group, or ...).

How did you get react-test?

I've written a blog post about this, but the gist of it is that the npm package was taken by Deepstream.io before but not used. So I asked politely and they allowed me to use it.

How is this different from React Testing Library?

This is a difficult one. First, React Testing Library, the documentation and the work from @kentcdodds and other collaborators is amazing and I've learned a lot from it. The main differences are:

The syntax follows jQuery-style chaining:

// react-test
import $ from "react-test";
test("Increments when clicked", async () => {
  const $counter = $(<Counter />);
  expect($counter).toHaveText("0");
  await $counter.click();
  expect($counter).toHaveText("1");
});

// react testing library
import { render, fireEvent } from "@testing-library/react";
test("Increments when clicked", () => {
  const { getByRole, container } = render(<Counter />);
  expect(container).toHaveTextContent("0");
  fireEvent.click(getByRole("button"));
  expect(container).toHaveTextContent("1");
});

React Test is a work in progress, so if you are writing tests for production right now please use one of the better known alternatives.

jQuery syntax, ewwh

That's not really a question! But if for some reason you deeply despise those dollars, perhaps because they remind you of PHP, you can avoid them altogether:

import render from "react-test";

test("Increments when clicked", async () => {
  const counter = render(<Counter />);
  expect(counter).toHaveText("0");
  await counter.click();
  expect(counter).toHaveText("1");
});

We obviously love React, but let's not forget that jQuery also has some great things as well. This library brings some of these nice things to react testing.

When will the 1.0 be ready?

To launch the version 1.0, I'd like to finish a few tasks:

  • Write more documentation and normalize it
  • Normalize code, specially across testing
  • Add some more event-based functionality, like extending native events (if possible).
  • Write 5 working examples in total. Counter, Signup, MovieList, CRUD and Swipe (names TBD).

I don't know how long that'll take, right now I'm normalizing the code and documentation.