Introducing Earl — a modern assertion library for TypeScript

Piotr Szlachciak
L2BEAT
Published in
3 min readApr 12, 2023
Earl logo on a fancy gradient. Gets you excited for the library doesn’t it? https://earl.fun

Have you ever found yourself frustrated with the status quo of testing libraries in the JavaScript ecosystem? Look no further; we’re excited to introduce Earl, a powerful, type-safe, and user-friendly assertion library for TypeScript!

With the release of version 1.0.0, we have completely rewritten the library to deliver a testing experience that is not only fast and robust but also intuitive and enjoyable. Earl is available on npm at https://npmjs.com/package/earl with the documentation hosted at https://earl.fun.

To kick things off, let’s dive into an example that showcases some of Earl’s best features:

import { expect } from "earl";
import { api } from "./api";

interface User {
id: number;
name: string;
email: string;
}

// Earl works alongside Mocha. It's great, so why reinvent the wheel?
describe("api", () => {
it("returns the user information", async () => {
const user: User = await api.getUser(1);
// Because toEqual is type safe you will get
// editor completions for user properties!
expect(user).toEqual({
id: 1,
// Earl provides powerful asymmetric matchers.
name: expect.notEmpty(),
email: expect.includes("@"),
});
});

it("throws for nonexistent user", async () => {
// Testing async errors has never been so easy.
await expect(api.getUser(2)).toBeRejectedWith("User not found");
});
});

Even in such a short piece of code you’ve already gotten a taste of Earl: full type safety, powerful deep equality, asymmetric matchers and stress free async tests. But that’s just the tip of the iceberg.

Core principles

When we designed Earl we wanted to set a new standard for what a testing library can be. That is why we’ve settled on a few guiding principles that affect the way the library was built an will be used:

Type Safety

Earl ensures that validators, like toEqual, are type-safe, preventing mistakes and enhancing the developer experience with editor completions. This focus on type safety guarantees that the assertions in your tests align with the expected types and values, leading to robust and reliable test code.

Clarity

Earl is designed to be clear and expressive. We’ve crafted an API for writing assertions that are self-explanatory and easy to understand. Additionally, we’ve put significant effort into creating helpful and informative error messages that help developers identify and resolve issues quickly.

One exciting feature is a custom algorithm for deep equality checking that seamlessly integrates with object formatting. Because of this even hard to spot differences like mismatched prototypes are brought to light when assertions fail.

Uniformity

The Earl API is consistent and predictable, making it easy to learn and use.

We took extra care to make sure that there is exactly one way to write any assertion. With earl, you won’t need to decide between to.be.true to.equal(true) and eq(true). It’s always going to be just toEqual(true).

We’ve also ensured that the API is consistent across all validators, so you can easily switch between them without having to learn a new API for each one.

Composability

Earl promotes a modular approach to writing tests by combining and reusing different components, such as matchers and validators. Matchers can be used alongside validators to create flexible and tailored assertions, allowing users to fine-tune their test cases to be as loose or as specific as desired.

Exciting features

Earl offers a wide array of features to make your testing experience even better. These include:

  • Validators and matchers for every occasion: From numbers, strings, arrays and sets to mocks, types and references Earl has got you covered.
  • Mock functions: Built-in support for creating mock functions, streamlining the process of testing interactions between functions and components.
  • Mock objects: Create lightweight and customizable objects for testing purposes.
  • Snapshots: Capture the output of your components or functions at a specific point in time to track changes and detect unexpected regressions.
  • Support for Zod: Seamless integration with the Zod validation library.
  • Extensibility: Extend Earl’s core functionality by adding custom validators and matchers.

With these powerful features and a focus on the core principles, Earl aims to become a go-to solution for TypeScript developers looking for a modern and reliable testing library. So, don’t wait any longer, and give Earl a try today!

https://earl.fun

npm install --save-dev earl

Special thanks

  • To Baptiste Lafontaine for agreeing to transfer ownership of the 11 year old earl npm package to us!
  • To L2BEAT for providing resources for maintaining Earl and dogfooding development versions.
  • To Kris Kaczor and Piotr Szlachciak for tirelessly working on Earl!

--

--