Starchart: 1,2,3, Testing!
Tags: javascript, prisma, opensource, vite
Published: 2023-03-24 16:30:32

## What is it?
After having [created a test database](https://dev.to/cychu42/starchart-mocking-a-database-part-2-2a88) for the [Starchart project](https://github.com/DevelopingSpace/starchart), I went on to working on tests for functions relate to Prisma API calls. (See [PR](https://github.com/DevelopingSpace/starchart/pull/415))

We use [Vitest](https://vitest.dev/) for unit testing, which is very similar to [Jest](https://jestjs.io/). A test suite looks something like this:

```
describe('createUser()', () => {
  let user: User;

  beforeAll(async () => {
    user = await createUser(
      'jsmith',
      'John Smith',
      'jsmith@myseneca.ca',
      'mycustomdomain-students'
    );
  });

  afterAll(async () => {
    await prisma.user.deleteMany().catch(() => {});
  });

  test('creates an User row with expected fields', async () => {
    expect(typeof user).toEqual('object');
    expect(user.username).toEqual('jsmith');
    expect(user.displayName).toEqual('John Smith');
    expect(user.email).toEqual('jsmith@myseneca.ca');
    expect(user.group).toEqual('mycustomdomain-students');
    expect(user.createdAt).not.toBe(null);
    expect(user.createdAt).toEqual(user.updatedAt);
    expect(user.deactivated).toBe(false);
  });
```

`describe()` is a test suite, which can include many related individual `test()`s. Both let you include a string to state what it's for, which will show up in a formatted display when you run tests.
`beforeAll()` is a block of code that executes **before** all tests of a suite is ran, which can be handy for setting up things, like creating an user for testing.
`afterAll()` is a block of code that executes **after** all tests of a suite is ran, which can be handy for clean-up, like deleting all existing user.

Each `expect()` is a condition that must be satisfied for a test to pass. The code is more or like like plain English language, such as `expect(user.createdAt).not.toBe(null);` really means expecting `user.createdAt` to not be null. You can find all the syntax in [their documentation](https://vitest.dev/api/expect.html).

You can put code, such as variable declaration an function calls, under `describe()` or `test()`. It's just a matter of scope for what you want to do.

--------

Assuming you already setup the tool properly (see [official guide](https://vitest.dev/guide/)), you can run the tests via `npx vitest`. A result can look like this:
![npx vitest results](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f6slp0pbnae76nwf7843.png)

For seeing test coverage, run `npx vitest run --coverage`.
![coverage result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hvynxd6jozoirs66thqr.png)
As you can see, it tells you how much of the files are covered by tests, in terms of statements, branching paths, functions, and lines. It also shows uncovered lines.

## Why do this?
1. This provides repeatable and standardized tests that are easy to run and view. You don't have to risk making mistake or forgetting a test like when one does manual testing of codes. The tool also provide good feed back by showing you what tests fail and what files aren't covered.
2. It's also something that can be shared in a repository and make collaboration easier.
3. An interesting way to use this is to write out some tests and have them act as technical requirements that guide the development of code. Essentially, you write out tests that tells developers what the software is supposed to do, and the developers write codes that would satisfy these tests that act as technical requirements.