Find the Commit that Broke the Tests with `git rebase –exec`

Nice tip by Kamran Ahmed:

If you want to go back X commits use a regular HEAD~X:

git rebase HEAD~3 --exec "yarn test"

Testing React Hooks With Enzyme and React Testing Library

Solid intro to test your React apps with either Enzyme or React Testing Library:

In this tutorial, we will look at how to do that by making use of a to-do application built with hooks. We’ll cover writing of tests using Ezyme and React Testing Library, both of which are able to do just that.

Note that not the hooks themselves are tested, but their outcome is.

Testing React Hooks With Enzyme and React Testing Library →

Tests and types

Brent has some thoughts on strong and weakly typed programming languages. Starting point: a simple function that needs testing:

rgbToHex(red, green, blue) {
    // …
}

Testing the result the function should return is easy. But what about edge cases?

What happens though if we pass doubles instead of integers? Or numbers outside of the allowed range? What about null? Or strings Or the wrong amount of arguments? Or a combination of the above?

Ah, the starting point for a nice article … (and no, requiring ints is not a bulletproof solution)

Tests and types →

🔥 Be sure to also check out Brent’s podcast Rant With Brent.

Speeding up Your PHPUnit tests

Some nice tips by Tim MacDonald on how to speed up your PHPUnit tests!

Having a fast test suite can be just as important as having a fast application. As a developer, getting feedback quickly about the state of your code allows for a much quicker development turnaround. Here we are going to run through some tips you can implement today to make your tests run faster.

Tips to Speed up Your Phpunit Tests →

(via Freek)

Run your tests using Jest & Puppeteer with jest-puppeteer

With jest-puppeteer – and its included expect-puppeteer assertion library – it’s possible to use Puppeteer within your Jest tests.

Writing integration test can be done using Puppeteer API but it can be complicated and hard because API is not designed for testing.

To make it simpler, an expectPage() is automatically installed and available, it provides a lot of convenient methods, all documented in expect-puppeteer API.

describe('Google', () => {
  beforeAll(async () => {
    await page.goto('https://google.com')
  })

  it('should display "google" text on page', async () => {
    expectPage().toMatch('google')
  })
});

With expect-puppeteer it’s also easy peasy to click buttons, complete forms, etc.

// Assert that a form will be filled
await expectPage().toFillForm('form[name="myForm"]', {
  firstName: 'James',
  lastName: 'Bond',
})

jest-puppeteer

Automatic visual diffing with Puppeteer

A few years ago we got Wraith and Huxley to perform visual regression testing. Monica Dinculescu has created a likewise thingy, powered by Puppeteer:

I did a little song-and-dance that sets up Puppeteer, takes screenshots of your app (like, all the routes you care about), and then compares them to the “golden” ones. If they match, your test passes!

The diffing can be integrated in your current testing setup, as the testing scripts themselves are written using Mocha and Chai. The core of the script is the compareScreenshots function, which checks all pixels of both screenshots, taking an allowed treshold/variance into account.

function compareScreenshots(fileName) {
  return new Promise((resolve, reject) => {
    const img1 = fs.createReadStream(`${testDir}/${fileName}.png`).pipe(new PNG()).on('parsed', doneReading);
    const img2 = fs.createReadStream(`${goldenDir}/${fileName}.png`).pipe(new PNG()).on('parsed', doneReading);

    let filesRead = 0;
    function doneReading() {
      // Wait until both files are read.
      if (++filesRead < 2) return;

      // The files should be the same size.
      expect(img1.width, 'image widths are the same').equal(img2.width);
      expect(img1.height, 'image heights are the same').equal(img2.height);

      // Do the visual diff.
      const diff = new PNG({width: img1.width, height: img2.height});
      const numDiffPixels = pixelmatch(
          img1.data, img2.data, diff.data, img1.width, img1.height,
          {threshold: 0.1});

      // The files should look the same.
      expect(numDiffPixels, 'number of different pixels').equal(0);
      resolve();
    }
  });
}

Automatic visual diffing with Puppeteer →

End-to-end Tests that Don’t Suck with Puppeteer

Good introduction to using Puppeteer for your e2e tests:

One of the most popular tools for e2e testing is Selenium, which is a tool for automating web browsers. Selenium sounds cool in theory: write one set of tests that run on all browsers and devices, woohoo! Jk. In practice, Selenium tests are slow, brittle, and costly. So, on Ropig we are using Puppeteer – the official headless Chrome library.

[…]

We are using Jest as our test runner, but you can use any testing tools you want with Puppeteer.

An example test would be this:

test('can create new user account', async () => {
    await page.goto(routes.public.register);
    await page.waitForSelector('[data-testId="userAccountForm"]');
    await page.click('[data-testId="userRegisterInputWithEmail"]');
    await page.type(user.email);
    await page.click('[data-testId="userRegisterInputWithPassword"]');
    await page.type(user.password);
    await page.click('[data-testId="userAccountSubmitButton"]');
    await page.waitForSelector('[data-testId="userSettingsForm"]');
})

Yes, you better get your async/await mojo on for this 😉

End-to-end Tests that Don’t Suck with Puppeteer →

Gremlins.js – Monkey testing library for web apps and Node.js

gremlins.js is a monkey testing library written in JavaScript, for Node.js and the browser. Use it to check the robustness of web applications by unleashing a horde of undisciplined gremlins.

I especially like the syntax to start a test:

var horde = gremlins.createHorde();
horde.unleash();

And oh, make sure you don’t run any tests after midnight 😉

Gremlins.js →

Related: Chaos Kong by Netflix also is inspired by the simian chaos theory 😉

Detox: E2E Testing in React Native

High velocity native mobile development requires us to adopt continuous integration workflows, which means our reliance on manual QA has to drop significantly. Detox tests your mobile app while it’s running in a real device/simulator, interacting with it just like a real user.

Here’s a sample test for a login screen:

describe('Login flow', () => {
    
  it('should login successfully', async () => {
    await device.reloadReactNative();
    await expect(element(by.id('email'))).toBeVisible();
      
    await element(by.id('email')).typeText('[email protected]');
    await element(by.id('password')).typeText('123456');
    await element(by.label('Login')).tap();
      
    await expect(element(by.label('Welcome'))).toBeVisible();
    await expect(element(by.id('email'))).toNotExist();
  });
  
});

wix/detox (GitHub) →
Testing in React Native — Jest & Detox →