AVA is a fast, simple JavaScript test runner. It runs tests concurrently, supports modern JavaScript, and keeps testing simple with a clean, focused API.
AVA gives you isolated test environments, snapshot testing, and built-in assertions. This makes it great for testing both front-end and back-end JavaScript code.
This guide shows you how to use AVA's core features to write and run tests effectively.
Prerequisites
You need Node.js version 20.0 or higher.
You should also be familiar with JavaScript basics and understand basic testing concepts.
Step 1 — Setting up the project
Before you can write and run any tests with AVA, you need to set up a basic Node.js project. This step will guide you through creating a new folder, setting up your package.json file, and installing all the necessary dependencies to get started with testing.
First, create a new directory and go into it:
Set up a new npm project:
This creates a package.json file for your project's settings and dependencies.
Enable ES Modules support:
Install AVA as a development dependency:
Add a test script to your package.json:
AVA doesn't look for test files in any specific folder by default. Tell AVA where to find your tests by adding this to your package.json:
Now let's create a simple function to test. Add this to a new file called utils.js:
This function takes a string, capitalizes its first letter, and makes all other letters lowercase. Now let's write a test for it.
Step 2 — Writing your first test
Unit tests verify that your functions operate correctly in various scenarios. Instead of testing manually, AVA helps you automate this process.
Create a test folder:
Inside this folder, create a file called utils.test.js:
In this file, you:
- Import the
testfunction from AVA - Import your
capitalizefunction - Create a test with a clear description
- Use
t.is()to check if the function returns the expected result
The t object gives you methods to make assertions about your code.
Step 3 — Running your tests
Now run your test with this command:
This works because your package.json file has' "test": "ava" '. It's the same as typing:
AVA finds and runs your test files based on your package.json settings. You'll see output like this:
This means your test ran and passed.
Unlike some testing tools, AVA does not automatically monitor file changes. To enable this, add a watch script to your package.json:
Now you can run tests in watch mode:
With watch mode enabled, AVA reruns your tests whenever you modify your code, providing instant feedback.
Step 4 — Writing multiple test cases
Let's make our tests more complete by checking different situations:
Each test focuses on a specific behavior of the capitalize function. One test checks that the first letter of the string is correctly transformed to uppercase.
Another ensures that the rest of the string is converted to lowercase. There's also a test to verify how the function handles empty strings, and finally, a test confirms that non-string inputs like null, undefined, or numbers return an empty string.
Writing small, focused tests makes your test suite easier to maintain. When something breaks, you'll know exactly what failed.
Run all the tests:
You'll see all tests pass:
Step 5 — Running specific tests
As your test suite grows, you won’t always want to run every single test. Sometimes, you’ll just want to focus on a specific test while fixing a bug or trying out a new feature. AVA makes this easy with a couple of handy tools.
Using test.only to focus on specific tests
If you’re working on a specific issue, you can use test.only() to run just that one test. This helps you stay focused and avoid noise from unrelated tests.
Add the highlighted code below:
Now when you run tests, only the test with .only runs:
This is extremely helpful when you need fast feedback while working on a single piece of logic.
Using test.skip to exclude tests temporarily
Let’s say one of your tests is broken or not relevant right now, and you want to ignore it for the moment. You can use test.skip() to instruct AVA to skip the test:
Now that test will be skipped:
Skipping a test like this is excellent for keeping your test suite green while you work on fixes or updates.
Filtering tests with command line arguments
You can also run tests by matching their names. This is useful when you don't want to change your test files:
This command runs only tests with "lowercase" in their name:
The double dash (--) separates npm's arguments from AVA's arguments. The stars (*) match any text before or after "lowercase".
Step 6 — Testing asynchronous code
In modern applications, asynchronous code is everywhere, whether you're fetching data from an API, reading a file, or querying a database. AVA is built to handle async code smoothly, so you can write tests that wait for promises to resolve or reject without extra setup.
In this step, you'll create a simple async function and test it. Let's simulate a user data fetch with a fake delay.
In your project’s root directory, create a new file called users.js and add the following code:
This function mimics a typical async operation: it waits for a short delay and either returns fake user data or throws an error if no ID is provided.
Now let’s test this function. Create a new file called users.test.js inside your test folder and add the following:
The first test waits for fetchUserData(1) to return and then checks if the data is correct. The second test uses t.throwsAsync() to make sure the function throws an error when no ID is provided. Since AVA understands how to handle promises, it automatically waits for async functions to finish before running assertions.
If you only want to run the tests from this file, you can use one of the following command:
If everything works, your test output will look something like this:
You're now successfully testing asynchronous code. In the next section, you'll learn how to mock your code using AVA.
Step 7 — Mocking with AVA
When testing your code, it's often a good idea to mock external dependencies, such as APIs, databases, or file systems. Mocking means replacing those real components with fake ones so you can test your code’s behavior in isolation.
AVA doesn’t include mocking out of the box, but it works smoothly with libraries like Sinon.js.
Let’s say you have a service that uses an API client to fetch a user’s name:
This method fetches a user and returns their name. If something goes wrong, it throws a custom error.
Now create a test file at test/userService.test.js:
These tests simulate both success and error cases using mocked behavior. You’re not calling any real APIs; instead, you're controlling the behavior of the fetchUser method using sinon.stub().
Now run the userService.test.js file:
Both commands will run only the tests in this file. This is super helpful when you're working on one specific part of your app.
If all goes well, you should see something like:
With this, you've learned how to mock dependencies in AVA and isolate your logic for accurate, reliable testing.
Final thoughts
This guide walked you through AVA’s key features, including setting up a project, writing tests, handling async code, and using mocks. AVA is simple yet powerful.
For more advanced use, visit the official docs. Most importantly, testing helps you build confidence in your code so you can make changes without worry.