Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic Testting Setup #42

Merged
merged 9 commits into from
Nov 24, 2018
Merged

Conversation

arcticicestudio
Copy link
Contributor

Resolves #39

This commit implements the main configuration file of Jest. It follows
the "Setting up your environment" (1) guide of Gatsby and the Jest docs
about how to get started (2). The file is placed in the project root and
initially contains the following options:

- `coverageDirectory` - The directory where Jest should output its
  coverage files.
- `collectCoverageFrom` - To ensure only relevant files are included in
  the coverage stats this array of glob patterns matches files for which
  coverage information should be collected.
- `globals` - A set of global variables that need to be available in all
  test environments. The `__PATH_PREFIX__` variable is specific to
  Gatsby based projects which is necessary for some components.
- `moduleNameMapper` - A map from regular expressions to module names
  that allow to stub out resources, like images or styles with a single
  module. It is also used to set up "resolve aliases" that reflect the
  same setup like the ones configured for Gatsby's Webpack
  configuration.
- `modulePaths` - An array with paths to additional locations to search
  when resolving modules. This is useful to define test specific utils
  which can then be imported like an aliased module.
- `setupFiles` - The paths to modules that run some code to configure or
  set up the testing environment before each test. The `___loader` shim
  is a global function used by internal Gatsby APIs. Note that this is
  executed BEFORE the `setupTestFrameworkScriptFile` option!
- `setupTestFrameworkScriptFile` - The path to the module that runs to
  configure or set up the testing framework before each test. Note that
  this is executed AFTER the `setupFiles` option!
- `testPathIgnorePatterns` - An array of regexp pattern strings that are
  matched against all test paths before executing the test. If the test
  path matches any of the patterns, it will be skipped.
- `transform` - To write tests using the latest ECMAScript syntax and
  proposals, Babel must be in place and set up to transpile the sources
  before they are processed by Jest to run them. This mapping from
  regular expressions to paths of transformers will transpile matching
  files with the specified Babel config. See the Jest documentation (3)
  about how to use Jest with Babel for more details.
- `transformIgnorePatterns` - This is an important and required option
  for Gatsby based projects since Gastby includes un-transpiled ES6 code
  and by default Jest doesn't try to transform code inside
  `node_modules`, therefore the` gatsby-browser-entry.js` file isn't
  transpiled before running Jest so the `gatsby` module must be
  excluded. The array of regexp pattern strings that are matched against
  all source file paths before transformation. If the test path matches
  any of the patterns, it will not be transformed.

References:
  (1) https://www.gatsbyjs.org/docs/unit-testing/#setting-up-your-environment
  (2) https://jestjs.io/docs/en/getting-started
  (3) https://jestjs.io/docs/en/getting-started#using-babel

GH-39
To write tests using the latest ECMAScript syntax and proposals,
Babel (1) must be in place and set up to transpile the sources before
passing them to Jest to run them.
This step is documented in the sections "Creating a configuration file
for Jest" (2) of the Gatsby guide about the preprocess file and the Jest
docs about "Using Babel" (3).

The file is placed in the base `test` folder within the project root.
It initially uses the `babel-preset-gatsby` (4) preset package which
includes all necessary Babel plugins to write tests for Gatsby based
projects. This includes all plugins mentioned in the Jest Babel setup
guide and additionally adds useful syntax proposal plugins that are also
used in the project sources like e.g.
`babel-plugin-proposal-class-properties` (5) and
`babel-plugin-proposal-optional-chaining` (6).
The the custom transformer is exported using babel-jest's
`createTransformer` function (7) which takes the created Babel config
object as parameter.

References:
  (1) https://babeljs.io
  (2) https://www.gatsbyjs.org/docs/unit-testing/#2-creating-a-configuration-file-for-jest
  (3) https://jestjs.io/docs/en/getting-started#using-babel
  (4) https://www.npmjs.com/package/babel-preset-gatsby
  (5) https://babeljs.io/docs/en/babel-plugin-proposal-class-properties
  (6) https://babeljs.io/docs/en/babel-plugin-proposal-optional-chaining
  (7) https://jestjs.io/docs/en/tutorial-react#custom-transformers

GH-39
`react-testing-library` provides a function to get elements by an test
ID using the `data-testid` property (attribute) that can be added to any
React component's JSX so it can be easily queried in tests. Note that
this only be done when there is no other way which is documented in the
guiding principles (1)!
Since this property is ONLY relevant for test purposes, this commit
configures the babel-plugin-react-remove-properties (2) to remove the
property from production builds. The plugin is added in Gatsby's
Babel configuration and loaded when in production mode.

References:
  (1) https://github.com/kentcdodds/react-testing-library#guiding-principles
  (2) https://github.com/oliviertassinari/babel-plugin-react-remove-properties

GH-39
The setup documentation (1) provides instruction for best practices on
how to configure the library for a optimal and easy developer workflow.
This includes a global configuration that has been placed within the
`test` base directory named `setup.js` and will be loaded via Jest's
`setupTestFrameworkScriptFile` option .
Initially it imports the `react-testing-library/cleanup-after-each`
script which will automatically execute `afterEach(cleanup)` for each
test which prevents unnecessary boilerplate per test file and possible
problems when the function is not called accidentally. It also imports
`jest-dom/extend-expect` to automatically extend the `expect` global
with jest-dom's custom matchers (2).

References:
  (1) https://github.com/kentcdodds/react-testing-library#setup
  (2) https://github.com/gnapse/jest-dom#custom-matchers

GH-39
>> Shims

Like documented in Gatsby's official testing setup guide (1) there are
some configurations that are specific to Gatsby projects. One is the
global `___loader` function used by Gatsby which this is mocked in this
commit using Jest's `fn()` mocking function. The `___loader.js` file
is placed in a folder called `__shims__` within the base `test`
directory.

>> Mocks

With Webpack, there are many loaders available to load any kind of file
type (2), e.g. CSS or Sass/Less for styles and images/videos of many
types. Jest doesn't know how to handle these when these are imported
within source files that are normally processed by Webpack so it'll
throw errors during the import.
A Jest mock (3) is a dummy module that is used instead of the real
module inside tests. It is good when there are something that you can't
or don't want to test. Almost everything can be mocked and the examples
are assets rather than code. For stylesheets, there is a package called
`identity-obj-proxy` (4) which is also already configured for this
project. For all other assets a manual mock has been created in a new
`__mocks__` folder within the base `test` directory.
To configure Jest to use these mocks the matching regex for the files
have been added to the `moduleNameMapper` option.

References:
  (1) https://www.gatsbyjs.org/docs/unit-testing/#setting-up-your-environment
  (2) https://webpack.js.org/loaders
  (3) https://jestjs.io/docs/en/manual-mocks
  (4) https://www.npmjs.com/package/identity-obj-proxy

GH-39
Since Jest makes use of the globally provided functions, ESLint's
environment must be configured to know that Jest is used in the project.

GH-39
This commit adds new NPM scripts to allow to run all tests with various
options:

- `test` - Run all tests with Jest.
- `test:cov` - Run all tests with coverage reports (1).
- `test:watch` - Run all tests in Jest's "watch mode" (2).

References:
  (1) https://jestjs.io/docs/en/cli#coverage
  (2) https://jestjs.io/docs/en/cli#watch

GH-39
This commit implements the first snapshot tests for all existing
components. The snapshots approach has been chosen by purpose because
all components are in initial implementation state and actually only
render a React `<Fragment>`.

It also fixes the resulting problems with `propType` violations for the
`Landing` (index/root) page which renders the `Root` component without
passing children. This has been fixed by using a `React.Fragment`.

GH-39
@arcticicestudio arcticicestudio merged commit 7a4d356 into develop Nov 24, 2018
@arcticicestudio arcticicestudio deleted the feature/gh-39-basic-testting-setup branch November 24, 2018 07:54
@arcticicestudio arcticicestudio removed their assignment Nov 27, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants