Setting up your first frontend Unit Tests workflow with GitHub + React + CodeBeaver

Vittorio Banfi - Feb 12 - - Dev Community

Let’s face it – unit testing in frontend development often feels like trying to nail jelly to a wall. Many frontend developers have traditionally focused on crafting pixel-perfect UIs and smooth user experiences, leaving testing as that thing we’ll “definitely get to next sprint” 😅

But here’s the truth: solid unit testing isn’t just a nice-to-have anymore – it’s becoming as essential as that morning coffee ritual that powers our debugging sessions. In this tutorial, we’re going to transform your React project from “yeah, we should probably write tests someday” to having a professional, automated testing workflow that would make your backend colleagues jealous. To do so we will use CodeBeaver, the AI agent for Unit Tests.

Getting started

Before we dive into the technical setup, let’s address the elephant in the room: frontend testing has historically been… complicated. Between component lifecycles, state management, and asynchronous operations, there’s a lot to consider. But that’s exactly why having automated tools like CodeBeaver in your arsenal is a game-changer.

On average, engineering teams save 30 minutes per developer per day thanks to CodeBeaver. That’s not just coffee-break time – that’s significant bandwidth you can redirect toward building features that actually matter to your users.

What We’ll Build

We’re setting up a complete unit testing workflow that will:

  • Automatically run tests on every pull request
  • Generate missing tests to maintain 90% coverage
  • Help identify and fix bugs before they hit production
  • Integrate seamlessly with your GitHub workflow

The best part? Once we set this up, it practically runs itself. No more “I forgot to write tests” commits at 4:59 PM on a Friday.

Prerequisites

Before we start, make sure you have:

  • A GitHub account
  • Basic familiarity with git commands
  • Node.js installed on your machine
  • A desire to write better code (check ✅)

What’s Coming Up

In the following sections, we’ll:

  • Set up your repository with the right testing infrastructure
  • Configure CodeBeaver to automate your testing workflow
  • Create your first test-driven PR
  • Review and merge automatically generated tests

Think of this as your “testing zero to hero” journey. By the end, you’ll have a professional-grade testing setup that makes maintaining test coverage as natural as running npm start.

Setting Up Your React (or NextJS) project for testing

Alright, fellow code wranglers, let’s set up our repository to be test-friendly. Think of this as Marie Kondo-ing your codebase, but instead of asking “does it spark joy?” we’re asking “will this make our tests cry?” 😅

Creating Your GitHub Repository

If you’re starting from scratch, head over to GitHub and create a new repository. Here’s the TL;DR version:

  • Click that shiny “New repository” button
  • Name it something clever (but professional – sorry, definitely-not-another-todo-app will have to wait)
  • Initialize with a README because we’re not savages
  • Choose the Node .gitignore template – trust me, your node_modules folder thanks you
  • Setting Up Your Package.json for Testing Glory

Time to beef up your package.json with some testing superpowers. Here’s a complete package.json as an example:

{
  "name": "your-awesome-project",
  "version": "1.0.0",
  "scripts": {
    "test": "jest",
    "test:coverage": "jest --coverage",
  },
  "jest": {
    "testEnvironment": "jsdom",
    "setupFilesAfterEnv": [
      "<rootDir>/src/setupTests.ts"
    ],
    "moduleNameMapper": {
      "\\.(css|less|scss|sass)$": "identity-obj-proxy",
      "^@/(.*)$": "<rootDir>/src/$1"
    },
    "collectCoverageFrom": [
      "src/**/*.{js,jsx,ts,tsx}",
      "!src/**/*.d.ts",
      "!src/index.tsx",
      "!src/reportWebVitals.ts"
    ],
    "coverageThreshold": {
      "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80,
        "statements": 80
      }
    }
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^5.16.5",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^14.4.3",
    "jest": "^29.3.1",
    "jest-environment-jsdom": "^29.3.1",
    "identity-obj-proxy": "^3.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

If you already have a project, your package.json may look a lot different, and you may need to update it. To make updating easier, let’s break down the important sections of the JSON above.

"scripts": {
  "test": "jest",
  "test:coverage": "jest --coverage",
},
Enter fullscreen mode Exit fullscreen mode

This is important as it declares how to test your code. As you see, for this tutorial we are using Jest.

After that, you can find some Jest own settings. You can remove them or not have them altogether, but they are useful in setting up how you want Jest to test your code:

"jest": {
    "testEnvironment": "jsdom",
    "setupFilesAfterEnv": [
      "<rootDir>/src/setupTests.js"
    ],
    "moduleNameMapper": {
      "\\.(css|less|scss|sass)$": "identity-obj-proxy",
      "^@/(.*)$": "<rootDir>/src/$1"
    },
    "collectCoverageFrom": [
      "src/**/*.{js,jsx,ts,tsx}",
      "!src/**/*.d.ts",
      "!src/index.tsx",
    ],
    "coverageThreshold": {
      "global": {
        "branches": 80,
        "functions": 80,
        "lines": 80,
        "statements": 80
      }
    }
  }
Enter fullscreen mode Exit fullscreen mode

Woha this a lot! Let’s break down this Jest configuration like we’re reviewing a PR at 4:55 PM on a Friday (but with actual attention to detail 😉).

"testEnvironment": "jsdom"
Enter fullscreen mode Exit fullscreen mode

First up, we’re telling Jest to use jsdom – think of it as a browser simulator for your Node environment. Without this, your DOM-related tests would throw more tantrums than a project manager during sprint planning.

"setupFilesAfterEnv": ["<rootDir>/src/setupTests.ts"]
Enter fullscreen mode Exit fullscreen mode

This is where you put your test setup code that runs before your test suite kicks off. Perfect for importing @testing-library/jest-dom and setting up those sweet custom matchers. It’s like the pre-workout routine for your tests! 💪

"moduleNameMapper": {
  "\\.(css|less|scss|sass)$": "identity-obj-proxy",
  "^@/(.*)$": "<rootDir>/src/$1"
}
Enter fullscreen mode Exit fullscreen mode

Here’s where we handle those pesky imports that Jest would otherwise get stuck on:

The first line handles your style imports (because let’s face it, Jest doesn’t care about your CSS-in-JS prowess)
The second line maps your fancy @/components absolute imports to their actual locations. No more ../../../ nonsense!

"collectCoverageFrom": [
  "src/**/*.{js,jsx,ts,tsx}",
  "!src/**/*.d.ts",
  "!src/index.tsx",
]
Enter fullscreen mode Exit fullscreen mode

This tells Jest which files to include in coverage reports. Notice those ! patterns? That’s us saying “hey, let’s not waste time testing TypeScript declaration files and boilerplate code.” Because life’s too short to test index.tsx.

"coverageThreshold": {
  "global": {
    "branches": 80,
    "functions": 80,
    "lines": 80,
    "statements": 80
  }
}
Enter fullscreen mode Exit fullscreen mode

The money maker! 🎯 This sets the bar at 80% coverage across all metrics. It’s like setting a high score for your codebase – miss these thresholds, and your CI pipeline will give you the same look your tech lead gives you when you push directly to main.

In essence, this configuration turns Jest from a simple test runner into a sophisticated testing powerhouse that would make even your backend colleagues nod in approval. And with CodeBeaver watching your back, maintaining these coverage thresholds becomes less of a chore and more of an automated victory lap! 🏃‍♂️🏆

File Structure

There are a lot of ways of organizing your test files, depending on the language and framework in which you are writing your code. In this case, since we are writing a Typescript and React project, my folder structure will be something like this:

src/
├── components/
│   ├── Button/
│   │   ├── Button.tsx
│   │   ├── Button.test.tsx
│   │   └── index.ts
│   └── Dropdown/
│       ├── Dropdown.tsx
│       ├── Dropdown.test.tsx
│       └── index.ts
├── utils/
│   ├── formatters.ts
│   └── formatters.test.ts
└── setupTests.ts
Enter fullscreen mode Exit fullscreen mode

In this case, I’m keeping my test files right next to their implementation. It’s like keeping your coffee cup next to your keyboard – it just makes sense!

Adding some components (Optional)

Note: Do this step only if you are starting from an empty project!

Let’s add a main page and some components to get it started. I open-sourced a repository to get you started. My suggestion is to copy/paste some files into your project. It’s a great way to gain familiarity with the structure above.

  • Add Button.tsx in src/components/Button
  • Add Button.test.tsx in src/components/Button
  • Add Dropdown.tsx in src/componenets/Dropdown

You can of course check how I set up my repository here on this Pull Request. Feel free to copy any file to your project!

The GitHub PR Template (Optional)

You don’t actually need this, but it’s super useful. It adds a template to the Pull Request, so that every time you add a new Pull Request, its description will start from the template itself. This way, all of your Pull Request’s descriptions will contain a similar structure.

To add the template, open your text editor and add a file at this path: .github/pull_request_template.md

You can now add any markdown, for example:

## 🎯 What does this PR do?

<!-- Quick bullet points about the changes -->

## 🧪 Testing Instructions

<!-- How can reviewers test your changes? -->

## 📸 Screenshots (if applicable)

<!-- Drop some visual goodness here -->

## ✅ Checklist

- [ ] Tests added/updated
- [ ] Documentation updated
- [ ] CodeBeaver checks passed
- [ ] No coffee was harmed in the making of this PR
Enter fullscreen mode Exit fullscreen mode

For more info, check out the GitHub documentation on this topic.

Monorepo or subfolder examples (optional)

If your project is a monorepo, or if your React project is not on the root, you will also need a codebeaver.yml configuration file. For example, let’s say that your repository has the react project in projects/react.

You will add a new file in the root of your repository called codebeaver.yml. It’s a YAML file that tells CodeBeaver where your React project is. This will work also with NextJS. This is how it looks like:

workspaces:
  - path: projects/react
    name: frontend
    from: jest
Enter fullscreen mode Exit fullscreen mode

You will need to replace projects/react with the path of your React project relative to the root of your repository. You can check the full documentation on the codebeaver.yml file if you want more information about it.

The Final Boss: Push to Main

Now that we have everything, time to commit these changes to main:

git add .
git commit -m "chore: add testing infrastructure (and hopes and dreams) 🚀"
git push origin main
Enter fullscreen mode Exit fullscreen mode

And there you have it! Your repository is now ready to embrace tests like a Java developer embraces design patterns. In the next section, we’ll connect CodeBeaver and watch it work its magic.

Remember: The best code is tested code, and the second-best code is the one that passes the tests we forgot to write. But with CodeBeaver, we won’t have to worry about the latter! 😉

Installing CodeBeaver: Where the Magic Gets Real 🪄

Alright, let’s get CodeBeaver installed and running. This is where your repository transforms from “tests? what tests?” to “look at my beautiful test coverage” in less time than it takes to explain why we need semantic versioning to product managers.

Step 1: The Grand Login 🔐

Head over to the login page codebeaver.ai and look for those magical words: “Sign up with GitHub”. Click that faster than you click “Mark All as Read” in your work email. You can also use CodeBeaver with GitLab or Bitbucket!

Image description

Great! Now CodeBeaver needs to access your GitHub repository in order to start writing tests. You will see a screen like this:

Image description

Click on Install CodeBeaver. You can give CodeBeaver access to the repositories of a GitHub organization you have access to, or to your personal Repositories. You can choose some repositories only or some of them. Don’t worry, you can add or remove repositories later at any time.

Step 2: Repository Selection 🎯

Now you can select the Repository you want to activate CodeBeaver for. The screen will look like this (this is mine, I have a lot of repos!)

Image description

As before, you will be able to change this selection later, so don’t worry. For the sake of this tutorial, pick the repository we created!

Step 3: CodeBeaver auto-configures itself 👽

Once you’ve added your repository, CodeBeaver will start analyzing your codebase and see if it can auto-configure itself. If you started from a blank project or if you added a codebeaver.yml file, the autoconfiguration should run smoothly and you will be ready to go. If it did not end up configuring itself, don’t worry! Check out the last chapter to see what to do from there.

Otherwise, you will see something like this:

Image description

Pick the option you prefer to try out CodeBeaver.

The “It’s Working!” Moment 🎉

Alright fellow code warriors, we’ve set up our testing infrastructure and got CodeBeaver watching our repository like a QA engineer after their fifth espresso. Now comes the fun part – let’s see this automation ballet in action!

Creating Your First Feature Branch 🌿

First, let’s create a branch that would make our git history proud:

# Create and checkout your feature branch
git checkout -b feat/add-user-avatar-component
Enter fullscreen mode Exit fullscreen mode

Let’s add a simple Avatar component that we’ll intentionally leave untested (don’t worry, CodeBeaver’s got our back!):

// src/components/Avatar/Avatar.tsx
import React from 'react';

interface AvatarProps {
  imageUrl: string;
  alt: string;
  size?: 'sm' | 'md' | 'lg';
  status?: 'online' | 'offline' | 'away';
}

export const Avatar: React.FC<AvatarProps> = ({
  imageUrl,
  alt,
  size = 'md',
  status
}) => {
  const dimensions = {
    sm: 'h-8 w-8',
    md: 'h-12 w-12',
    lg: 'h-16 w-16'
  }[size];

  return (
    <div className="relative inline-block">
      <img 
        src={imageUrl}
        alt={alt}
        className={`${dimensions} rounded-full object-cover`}
      />
      {status && (
        <span 
          className={`absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-white
            ${status === 'online' ? 'bg-green-500' : 
              status === 'away' ? 'bg-yellow-500' : 'bg-gray-500'
            }`}
        />
      )}
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Now, let’s commit this beauty:

git add .
git commit -m "feat(components): add Avatar component with status indicator"
git push origin feat/add-user-avatar-component
Enter fullscreen mode Exit fullscreen mode

Watching CodeBeaver Do Its Thing

Head over to your GitHub repository. You will see a dialog to create a new Pull Request. Go ahead and create a Pull Request. If you added a Pull Request template, you will see that as well! Once you click on “Create Pull Request”, here’s where the magic starts happening. You will see CodeBeaver working like this in GitHub:

Image description

CodeBeaver working on your GitHub Pull Request - Screenshot
What will happen is:

  • CodeBeaver will detect your new PR
  • It’ll notice there’s no test file for our Avatar component (tsk tsk!)
  • Start analyzing the component’s props, behavior, and edge cases
  • Generate comprehensive tests that would make TDD purists weep with joy

Reviewing the Generated Tests 🔍

CodeBeaver will add a comment to your Pull Request. It will look something like this:

Image description

If you click on the Pull Request link in the comment you will go to the Pull Request opened by CodeBeaver. You will notice that it’s a Pull Request opened on top of your original Pull Request:

Image description

To review the files, you can check out the diff in GitHub (same as any other Pull Request). Click on “Files Changed”

Image description

You can now review the code that CodeBeaver wrote for you.

Once you are ready, you can merge the Pull Request opened by CodeBeaver by clicking on the “Merge pull request”

Image description

Conclusion

Well, fellow code warriors, we’ve come a long way from “we should probably write some tests” to having a fully automated testing workflow that would make even the most zealous TDD advocate nod in approval. Let’s take a victory lap and see what we’ve accomplished! 🏃‍♂️

What We Built Together 🏗️

We didn’t just set up tests – we established a complete testing ecosystem that:

  • Transforms your React codebase from test-optional to test-mandatory (in the best possible way)
  • Automates the tedious parts of testing (because life’s too short to write edge cases at 4:59 PM)
  • Integrates seamlessly with your GitHub workflow (like a well-configured git hooks, but actually useful)

The Real MVP: Your Future Self 🦸‍♂️

Remember that feeling of dread when you had to modify a component and all its tests started failing faster than a junior dev’s first production deploy? Well, those days are now officially in your git history. With CodeBeaver watching your back:

Your tests evolve with your code (no more “it worked on my machine” moments)
Coverage stays high without manual intervention (like your coffee intake, but automated)
Bugs get caught before they can make it to production (and before your PM can schedule an emergency meeting)

The Path Forward 🛣️

Remember: CodeBeaver isn’t just a test writer – it’s your partner in maintaining code quality. When tests fail, it’ll help you:

  • Identify if it’s a bug in your new code (before your code reviewer does). Check out an example here.
  • Determine if existing tests need updates (because your awesome new feature changed the game). Check out an example here.
  • Maintain that sweet, sweet test coverage without breaking a sweat

The Bottom Line 💯

We’ve transformed your React project from “tests are optional” to “tests are automatic” – and did it without sacrificing your development velocity or your sanity. That’s not just a win; that’s a paradigm shift in how we approach frontend testing.

Remember: The best code isn’t just the code that works – it’s the code that proves it works through comprehensive tests. And now, thanks to CodeBeaver, you can have both without doubling your coffee budget! ☕

Happy coding, and may your tests be ever green! 🚀

P.S. If your team starts wondering how you became a testing guru overnight, just wink and let them think it’s all those extra hours you’ve been putting in (instead of CodeBeaver doing the heavy lifting) 😉

. . . . .