ReactApp Typescript with TDD and BDD(jest, Enzyme, Sinon, and cypress), linting and pre-commit hooks(using husky) [Part-1]
Tags: react, redux, docker, webdev
Published: 2021-05-31 05:00:48

Hi all, from this material we are going to create a sample react app from scratch, which will include the concepts from setting up a proper project with TDD and BDD approach along with linting.

**New to React?** Please check [Basics](https://raghavendrank.medium.com/react-is-simple-32bfb4f9233) to get to know the basics.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ny2idz8vi5j4n0cbbzn.png)

In this **Part-1** we are going to use the below libraries and tools to set up our project.
* React
* For E2E testing will use Cypress, Jest, Enzyme, Sinon, and Istanbul for code coverage
* We will use Typescript to follow OOPS concepts like enums, interface, types, etc.,
* Storybook to document components for reuse and automatically visually test components.
To maintain code quality will use ESLint, Prettier, and SassLint.
* And will call these e2e tests and linting rules in the pre-commit hook using husky, so before the developer wants to push his changes to the repository they can fix the coding standard errors, and make better code.

So let's start with setting up the project by following below steps:
1. Create a react app using create-react-app with template typescript, later we will eject it to follow our standards.
**“npx create-react-app react-typescript-jest-cypress — template typescript”**
2. Now run the **“npm run eject”** to eject and segregate the dependencies and devDependencies like mentioned in [package.json](https://github.com/RaghavendraNK/react-typescript-jest-cypress/blob/main/reactapp/package.json)
3. We will use Sass in our application so we can use variables, mixins, nested rules and functions to make well-organized and theming across the projects. To install sass package run **“npm install node-sass -D”**
4. Now we will install and use cypress for E2E tesing with cross-browser compatibility, so we can see visually the flow, debug and fix the bugs. **“npm install cypress -D”**. Update the package.json with cypress test commands.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abam8gnv2q065aphub66.png)

Now let's run cypress, using **“cypress-test”** command.

*Note*: Some of you can face issues in some versions: Using `babel-preset-react-app` requires that you specify `NODE_ENV` or `BABEL_ENV` environment variables. Valid values are “development”, “test”, and “production”. Instead, received: undefined. When the app is created using create-react-app. To overcome this issue go to package.json and remove the below code snippet.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3zca5qco8ksid0j00d3z.png)
 

And update the cypress.json file in the root folder like below:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/veztfco0rl1gaa37gm6g.png)

Now we will use package @cypress/code-coverage for code-coverage.
4.1 Update babelrc like below and install the required packages
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lnlnyhexed1zyyib1i6m.png)
 
4.2 Update the cypress/plugins/index.js file:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yzcc4ahbikgdkx2h8vux.png)
 
4.3 Add the code-coverage summary commands in the package.json scripts section.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vj2dsqsh3dwxq4uxsuwh.png)
 
5. Lets install storybook by running **“npx sb init”**. Once it got installed we will [customize](https://storybook.js.org/docs/react/configure/theming) it like below.

5.1 Create theme.js in the .storybook folder where you can mention the title, theme, and brandURL.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iryumc4k94galp37cmt8.png)
 
5.2 Call this theme in .storybook/manager.js
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2r2xnm51joa5gshsag0c.png)
 
5.3 Update package.json with storybook commands.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d79x6ostmawbkkmcfzl7.png)
 
6. We will configure our unit testing with jest, enzyme, sinon and chai tools.

6.1 For snapshot testing we are going to use react-test-renderer, so let's install it **“npm install react-test-renderer -D”**
6.2 We will configure jest.

6.2.1 Create a jest.config.json in the root folder and specify the [options](https://jestjs.io/docs/configuration)
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/202zwilq6d90ewti8bwa.png)[Link](https://github.com/RaghavendraNK/react-typescript-jest-cypress/blob/main/reactapp/jest.config.json)

6.2.2 Now we will install enzyme, adapter, sinon and chai. **“npm install enzyme @types/enzyme sinon @types/sinon chai @types/chai enzyme-adapter-react-17-updated -D”**

6.2.3 Create a file setupTests.js in root folder for specifying enzyme adapter.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oxjxhtkc6o362vq82lnb.png)
 
Then specify the path in jest.config.json
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qcrcpug49pdoppyqqirv.png)
 
7. We will use istanbul for code coverage and set some threshold in jest.config.json to maintain quality of code
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rrwqfww7rga0mb5stxjf.png)
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qm9gcdnrhd1ax6h85z5c.png)

8. [Prettier](https://prettier.io/): Will use this for code formatting by creating [.prettierrc.json](https://github.com/RaghavendraNK/react-typescript-jest-cypress/blob/main/reactapp/.prettierrc.json) in root folder. And install package **“npm install prettier -D”**
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0njnr9zmogsyjh8id1oj.png)
 
9. Will use [“husky”](https://typicode.github.io/husky/#/?id=recipes) as our pre-commit hook and we will specify the commands which are to be executed when the developers commits the code, if all rules are getting passed will allow him to push to the repository. **“npm install -D pretty-quick husky”**

9.1 To add any commands run **“npx husky add .husky/pre-commit <Command>”** to update .husky file.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1585fy1p8trj8lvhw5r9.png)
 
So by doing this whenever the developer tries to commit the changes it will check and give the status of it by that developer can fix the issues if any.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aiwod8kds6ku7fqv8qum.png)
 
10. Linting: will use to analyse code for potential errors
     10.1 Scss-Lint: Create a [.sasslintrc.json](https://github.com/RaghavendraNK/react-typescript-jest-cypress/blob/main/reactapp/.sasslintrc.json) in the root folder and specify the sass rules, and call it in the package.json. **“npm install scss-lint sass-lint-auto-fix -D”**
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xg8u37zf9zxlygxkcu7g.png)
 
     10.2 Typescript-ESlint: Install **“npm i -D eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin”** then create a [.eslintrc.js](https://github.com/RaghavendraNK/react-typescript-jest-cypress/blob/main/reactapp/.eslintignore) and [.eslintignore](https://github.com/RaghavendraNK/react-typescript-jest-cypress/blob/main/reactapp/.eslintignore) in root folder. [eslintignore](https://github.com/RaghavendraNK/react-typescript-jest-cypress/blob/main/reactapp/.eslintignore) will ignore the paths/files from linting.

Finally, update the .husky file with the below commands:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9kyx7pxpf77hkw4v89zg.png)
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gejq3sia5cxdpslplcab.png)
  
So now we are ready with the proper project setup, in the next part, we will dockerize it along with CI/CD pipeline using Docker and Jenkins.

**Part -2**: [Contains the Docker containers for MongoDB, NodeJS API, and ReactAPP using Docker-Compose. Along with NVM.](https://raghavendrank.medium.com/mern-with-docker-container-setup-part-2-93cf34912445)
**Part-3**: [Contains setup “i18next and redux, saga” and “axios” configurations. And also we are going to use Figma to create our wireframes, which we are going to develop.](https://raghavendrank.medium.com/react-redux-with-i18n-and-building-the-wireframes-using-figma-part-3-e250fac4cbf4)
**Part-4**: Contains Jenkins setup and connecting with nodeJS API with MongoDB to get the articles from the database and performing the CRUD operations.
**Part-5**: We will publish our app on the Heroku server using ci/cd pipelines.
Please find here the complete project setup & Storybook with core component package: [Link](https://github.com/RaghavendraNK/react-typescript-jest-cypress.git)