- src/fooBar.js
 - src/fooBar.html
 - src/fooBar.scss
 - src/fooBar....
 - src/fooBar.test.js => 
npm run test - src/fooBar.test.e2e.js (if I have E2E tests - Puppeteer, Playwright...) => 
npm run test:e2e 
Tests should not be separated from the source code (think autonomous modules).
{
  "scripts": {
    "test": "NODE_ENV=test jest --verbose",
    "test:coverage": "jest --coverage",
    "test:e2e": "NODE_ENV=test jest --config jest-e2e.config.js"
  }
}As for the tests themselves, I follow the functions defined in the original source code (in the same order):
// fooBar.ts
export function fooBar1() {
  ...
}
export function fooBar2() {
  ...
}// fooBar.test.ts
import { fooBar1, fooBar2 } from './fooBar';
test('fooBar1()', () => {
  ...
});
test('fooBar2()', () => {
  ...
});If I have variations, I use describe() to re-group them:
// fooBar.test.ts
import { foorBar1, fooBar2 } from './fooBar';
describe('fooBar1()', () => {
  test('case 1', () => {
    ...
  });
  test('case 2', () => {
    ...
  });
});
test('fooBar2()', () => {
  ...
});Example: https://github.com/tkrotoff/fetch/blob/v0.5.1/src/Http.test.ts#L88-L172
I try to avoid describe(): most of the time they are unnecessary. Same for words like should, when, then...
=> just noise that brings no value
// MyComponent.test.tsx
import React from 'react';
import { MyComponent } from './MyComponent';
test('render', () => {
  ...
});
test('render without query param', () => {
  ...
});
test('render with query param', () => {
  ...
});
test('fetch error', () => {
  ...
});(With React class components, I was writing test('render()', () => { ... }) since there was actually a render() method; not anymore with hooks)
Examples:
- https://github.com/tkrotoff/MarvelHeroes/blob/8b8f4f93fb3d9a076830138ea6b821838e3fea46/src/Heroes.test.tsx
 - https://github.com/tkrotoff/MarvelHeroes/blob/8b8f4f93fb3d9a076830138ea6b821838e3fea46/src/utils/ErrorBoundary.test.tsx
 
I ensure that fooBar.test.ts fully covers fooBar.ts by running npm run test:coverage fooBar.test.ts.
If some stuffs are impossible to test, I use // istanbul ignore next => 100% code coverage :-)
Example: https://github.com/pmu-tech/stub-server/blob/v0.3.0/src/stubServer.ts#L84
Most of the time, fooBar.test.ts is way bigger than fooBar.ts, example:
- https://github.com/pmu-tech/stub-server/blob/v0.3.0/src/stubServer.ts => 164 LOC
 - https://github.com/pmu-tech/stub-server/blob/v0.3.0/src/stubServer.test.ts => 403 LOC
 
This is because I test not only the nominal case but the corner cases too. My principle is "what ain't tested ain't working".
npm run test performs jest --verbose, this way I ensures my tests description are OK:
$ npm run test
 PASS  src/Http.test.ts
  ✓ throw TypeError (2ms)
  defaults.init
    ✓ 201 Created + defaults (12ms)
    ✓ 201 Created + options + defaults (2ms)
  getJSON()
    ✓ 500 Internal Server Error (2ms)
    ✓ 204 No Content (1ms)
    200 OK
      ✓ 200 OK (2ms)
      ✓ 200 OK + options (2ms)
      ✓ 200 OK + options with method (3ms)
  postJSON()
    ✓ 201 Created (2ms)
    ✓ 201 Created + options (2ms)
    ✓ 201 Created + options with method and body (2ms)
  putJSON()
    ✓ 200 OK (1ms)
    ✓ 200 OK + options (1ms)
    ✓ 200 OK + options with method and body (3ms)
  patchJSON()
    ✓ 200 OK (2ms)
    ✓ 200 OK + options (2ms)
    ✓ 200 OK + options with method and body (2ms)
  deleteJSON()
    ✓ 204 No Content (1ms)
    ✓ 204 No Content + options (2ms)
    ✓ 204 No Content + options with method (2ms)
  parseResponseBody()
    ✓ application/json Content-Type (1ms)
    ✓ text/plain Content-Type (1ms)
  checkStatus()
    ✓ 200 OK (1ms)
    ✓ 400 Bad Request (5ms)
 PASS  src/HttpError.test.ts
  ✓ throw (2ms)
Test Suites: 2 passed, 2 total
Tests:       25 passed, 25 total
$ npm run test
 PASS  src/Layout.test.tsx
  ✓ render (47ms)
 PASS  src/PageNotFound.test.tsx
  ✓ render (56ms)
 PASS  src/utils/ErrorBoundary.test.tsx
  ✓ render children if no error (45ms)
  if an error occured
    ✓ render message + report button (33ms)
    ✓ user clicks on report button (21ms)
  withErrorBoundary()
    ✓ displayName (3ms)
    ✓ render children if no error (4ms)
    ✓ render a message if an error occured (8ms)
 PASS  src/Router.test.tsx
  ✓ HeroesPagination route (90ms)
  ✓ Hero route (10ms)
  ✓ PageNotFound route (5ms)
 PASS  src/Hero.test.tsx
  ✓ render (179ms)
  ✓ fetchCharacter() error (43ms)
 PASS  src/api/Marvel.test.ts
  ✓ getQueryParams() (4ms)
  fetch*()
    ✓ fetchCharacters() success (4ms)
    ✓ fetchCharacters() error (6ms)
    ✓ fetchCharacter() success (1ms)
    ✓ fetchCharacter() error (2ms)
 PASS  src/utils/useErrorBoundary.test.tsx
  ✓ useErrorBoundary() (29ms)
 PASS  src/utils/fakeFetchResponse.test.ts
  ✓ fakeFetchResponseSuccess() (4ms)
  ✓ fakeFetchResponseError() (1ms)
 PASS  src/utils/getPackageNameFromPath.test.ts
  ✓ getPackageNameFromPath() (4ms)
 PASS  src/Heroes.test.tsx
  ✓ render (564ms)
  ✓ render "No results found :(" (6ms)
  ✓ fetchCharacters() error (21ms)
 PASS  src/HeroesPagination.test.tsx
  ✓ render without page query param then change page (581ms)
  ✓ render given a page query param (104ms)
Test Suites: 11 passed, 11 total
Tests:       27 passed, 27 total
$ npm run test
 PASS  bin/stub-server.test.ts
  ✓ correct config param (313ms)
  ✓ correct config and port params (309ms)
  ✓ network request (179ms)
  ✓ incorrect config param (146ms)
  ✓ incorrect port param (152ms)
 PASS  src/stubServer.test.ts
  ✓ delay (20ms)
  ✓ unknown route (2ms)
  files
    ✓ file without HTTP status (48ms)
    ✓ json file does not exist
    ✓ png file does not exist (1ms)
    ✓ json (10ms)
    ✓ png (10ms)
    ✓ ts (8ms)
    ✓ js (6ms)
    ✓ html (5ms)
  HTTP status codes
    ✓ invalid HTTP status code (6ms)
    ✓ 400 Bad Request (5ms)
    ✓ 500 Internal Server Error (5ms)
    ✓ 204 No Content (5ms)
  HTTP verbs
    ✓ unknown HTTP verb (1ms)
    ✓ GET (4ms)
    ✓ compatibility with lower case (5ms)
    ✓ POST (8ms)
    ✓ PUT (5ms)
    ✓ PATCH (5ms)
    ✓ DELETE (5ms)
    ✓ multiple verbs (20ms)
  proxy
    mocked, no network request
      ✓ URL redirection with param (5ms)
      ✓ URL redirection to unknown host (12ms)
      ✓ POST multipart request (9ms)
    not mocked, performs real network requests, might fail
      ✓ URL redirection with param (116ms)
      ✓ URL redirection to unknown host (24ms)
      ✓ POST multipart request (394ms)
  express request handler
    ✓ js (6ms)
    ts
      ✓ res.send() (6ms)
      ✓ res.send() async (506ms)
      ✓ res.status()
      ✓ res.end() (5ms)
      ✓ do nothing"
      ✓ without param (4ms)
  get stub name from function
    ✓ no response property (5ms)
    ✓ with response property (5ms)
Test Suites: 2 passed, 2 total
Tests:       42 passed, 42 total