Automating Testing in Next.js: Ensuring Code Integrity with Jest and GitHub Actions
Tags: webdev, nextjs, testing, javascript
Published: 2024-04-11 17:51:01


Often, you work with fellow developers for a company, your small project, or any other contribution. You need to ensure that the code you've written is all right, and performs the intended functionality before pushing and merging to github. However, this process is quite tedious, as you have to first check if the code works all right, and after you've merged the changes into the main/master (production) branch, you need to verify if it works as it is supposed to. This blog will help you eliminate that process by automating testing in the NextJS app so that you can only merge the code once it passes the intended functionality specified by yourself.

## Setting up a NextJS app
Create a folder on your device, name it anything you want i.e NextJs-testing, open your favourite IDE i.e VSCode, and type this command in the terminal.
`npx create-next-app@latest --example with-jest with-jest-app`
You can also follow the documentation to explore how to setup NextJS app with Jest and customizations
[Setting up Jest with Next.js](https://nextjs.org/docs/app/building-your-application/testing/jest)

## Creating a repository on Github
Go to github.com, and create a new repository. Name it anything you want, i.e Nextjs-test.

![GitHub repository creation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jqxv7fcr5yk95ohfvtmm.png)Click on proceed after you've provided the name and an optional README file.


## Setting up a file to test
After you've created your next app, create a components folder inside your app folder. If you've opted not to have the app router, in which case you will not have this folder in your source code, you can create a _components folder in your root directory.
Inside your components folder, create a file as ComponentA.jsx. You can name it anything apart from test.jsx. 

![File Structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9bqpc82s1ribdlc9q7ys.png)
You can copy this code inside your ComponentA.jsx 

```
function ComponentA() {
  return <h1>Testing</h1>;
}

export default ComponentA;



```
 


## Adding a test case
The next step is to create a file where you'll write your test cases. If you have a \__tests\__ folder, create a page.test.jsx file. If you donot have this folder by default, you can create one manually as well. Once you've created the file, you can copy this code inside your page.test.jsx



```
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import ComponentA from "../app/components/ComponentA";

describe("Page", () => {
  it("renders a heading", () => {
    render(<ComponentA />);

    const heading = screen.getByRole("heading", { level: 1 });

    expect(heading).toBeInTheDocument();
  });
});

```



This code tests the rendering of a _**h1**_ tag in the ComponentA.jsx.

## Update package.json
In your package.json, add 

```
"test": "jest",
"test:watch": "jest --watch"
```
 inside scripts object.


## Create workflow for automated testing
In your root directory, create a folder and name it as .github. Inside it, create another folder .workflows, and inside it create a file **main.yml**. Copy this code inside your main.yml 

```
name: Tests for Next.js app

on:
  pull_request:
    branches:
      - main

jobs:
  NextJS-Tests:
    name: Tests for Next.js app
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Setup Node.js
        uses: actions/setup-node@v2
        with:
          node-version: "20"

      - name: Install dependencies
        run: |
          npm install

      - name: Run Jest tests
        run: npm test

```
This workflow executes the jobs specified on pull request to the main branch. 
_Note: If you have the master branch instead of main, you can replace main with master in main.yml_.

## Add branch protection rules
In your github repository, navigate to the settings tab, and from the sidebar, select Branches under Code and automation. Specify the name of the branch i.e main/master.

![Branch Protection tab](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkjhj808z1zrl95rz63n.png)
Next, you've to specify some settings for your branch under the Protect matching branches.

1. Check **_Require a pull request before merging_**. 
2. Check **_Require status checks to pass before merging_**. 
3. Search for the status checks in the search bar provided below. This should be the name specified for jobs in main.yml ![Branch Protection rules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/egls2tjbi4yi13xnje29.png)
4. Check **_Do not allow bypassing the above settings_**. This will make sure that not even the repository owner is allowed to directly push onto the branch, or bypass these rules. If not checked, only the repository owner can directly push to the main/master branch without making a pull request.
5. Click on Save Changes button.

## Merging dev branch into main
Create another branch from main i.e dev. In ComponentA.jsx, replace the h1 tag with h2 tag.

![ComponentA.jsx code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ast1avonfxbt7iv28w94.png)

Commit changes locally and push the code to github repository. Create pull request from dev to main. 
![Pull Request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ys77dx85bxr5u23nxtkz.png)
After creating a pull request to main, our test cases will execute as we specified the trigger to be on pull request to main.

![Workflows](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpohhwxl5ujfmzcj51ra.png)
However, you will be unable to merge dev into main since our test cases have failed, resulting in the status checks not being passed. This is due to the fact that we replaced h1 tag with h2 tag, however in our _**page.test.jsx**_, we specified that there should be a level 1 heading. 
Since our test cases have not passed, we will be unable to merge dev into main.

## View Workflows
You can view what went wrong when your test cases failed, by clicking on the Actions tab, and selecting the workflow from there.

![Workflows](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3gykfgsn4hqgjanmbpa2.png)



## Correcting the code to pass test cases
Go to ComponentA.jsx file on your local dev branch. Replace h2 with h1 tag as before. Commit changes locally and push the changes to remote dev branch. 
Navigate to pull requests tab on the tab, and you'll see test cases executing again. 

![Pull Request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v8miqvsrxjndz221rnb2.png)


In a few moments, you'll see successful execution of the test cases, and you'll be able to merge dev into main now.

![Test cases](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnq6bv6nbcrt9ti9b4ur.png)


## Conclusion
In this way, you can write test cases for your NextJs app, and automate them using github actions so that you don't have to worry about any breaking changes that may occur after merging the code to the main/master branch. If the test cases fail, you can always go back and correct the code before pushing the code again to dev/feature branch.

Do let me know if I've missed anything, or if you feel anything is incorrect or can be improved.