Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI Tests with Jest and Storybook #19

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

virtuous-cat
Copy link
Member

Includes a stub of an intro to tests page and an in-depth beginner-friendly guide to UI tests with Jest and Storybook.

I'm not sure if we want Testing to be it's own folder, or part of the Knowledge Base, or what?

Comments on this welcome from everyone. Please let me know if anything is incorrect or unclear, if the structure needs tweaking, if I've gone mad with the power to create Admonition blocks, etc.

Also, I sort of accidentally made a Choice™ stylistically, with my uses of "we" and "you", and I'm not totally sure how I feel about it. :|

@virtuous-cat virtuous-cat mentioned this pull request Feb 23, 2022
9 tasks
@riazaia
Copy link
Member

riazaia commented Feb 27, 2022

Disclaimer that my perpective might be even more begginer than most people's... o<-<

I think ideally the Testing Basics page would also somehow answer questions like:

  • What actually are tests? As a complete newbie the concept of a test wasn't even in my head. For a while I assumed it was some devtool in the browser or in your code editor. I thought it was a button you pressed, the idea that tests involved writing actual code yourself was completely lost on me. I know the tip in the box uses the word 'written' in regards to tests, but I think it could be mentioned earlier/in the main text.
  • Why write tests? Why not manually test your code? Are tests faster, slower? Do they make things easier for other developers? Are they more reliable than manually testing? That's the kinda thing I'd like to read when being introduced to the concept. It's obvious to me now why tests are pretty cool and useful, but the little JS thingies I've written I did without tests and nothing catastrophic happened, so I think talking about the why would give a good perspective on it. I'd also give an example. Something very simple like the jest getting started example would suffice. It can help explain how testing a sum() function manually would mean typing in bunch of combos and hoping your cover your bases, but with tests you can actually describe the expected behaviour when you submit two positve numbers, two negative numbers, a number and a letter, etc. (I don't know much about tests... do you write tests for the errors you hope to give out? I'd assume so.)

Also, I dunno if TDD is worth mentioning here, but I remember Ms. Boba linked me an article about that when I had to write tests for another project so maybe?

@riazaia
Copy link
Member

riazaia commented Feb 27, 2022

Previous disclaimer still applies o<-<. Plus additional disclaimer that I feel like some of the things I mention aren't meant to be answered in this page and are probably already answered elsewhere in the bobadocs, but figured this could simply count as feeback to add links to other places in the docs later.

Reading the Jest and Storybook page makes me think either there or Testing Basics should make some mention of different kinds of tests. I think the idea of testing UI sounds very foreign to me, and I don't understand how that would work at all. To be clear, my familiarity with tests is entirely of the 'expect this from that function' so yeah. I'd also give some brief mention of tools in the basics section as well, so we (me) aren't intimidated by the all the new terms.

I also think this page would benefit from some sort of introduction paragraph, though I'm not sure exactly what it should say. I'm noticing a pattern within myself, because I wanna say that it would be good to explain why Jest and why Storybook and why UI tests. Not even anything high level, just "Writing tests for the UI components to make sure they work, they're accessible, they look as intended. We're gonna use Jest as a testing framework for this because of X. We'll use Storybook for this as well because Y." (IDK if "looks ok, works and is accessible" is actually what we're testing, I'm just giving an example, I genuinly have no clue.)

I think a lot of this one is going over my head because I just don't understand some words and I can't tell if they're words I should understand from the bobadocs, jest docs, storybook docs or just general programming or life knowledge. Some of the terms I'm not 100% sure about, for reference: components (don't really get the scope of this, is it a button or is it a the whole sidebar?), stories, business logic, src code (I assume my local copy of the code but I dunno), props.

I went digging and here's how the The Odin Project brings up testing in the Fundamentals course, and later in the JavaScript Course, btw. Dunno if it's useful but I figure there's cool links to check out at least.

@virtuous-cat
Copy link
Member Author

I have made some revisions in response to Riazaia's comments, in particular explicitly stating the baseline knowledge assumed at the beginning of the UI testing guide, and linking to resources for those subjects.

The Testing Basics intro is intended to be a base to be expanded on, and should eventually include more of the points outlined in this issue: #12

@essential-randomness
Copy link
Collaborator

As a broad comment, we need to provide resources on tech writing to help ease people into the style, which is more terse than they might be used to. This is not just about this PR, but something I've noticed in general with fandom people making the jump into technical documentation.

I'm going to point out areas of improvement in the code review itself (I'm not a perfect tech writer, but I do have formal education in it). In the meantime, I suggest reading these resources before a second a draft:

These sites that might be worth perusing more broadly, but I think those sections will help on their own.

Copy link
Collaborator

@essential-randomness essential-randomness left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment with links to tech writing style guides.

title: Testing Basics
---

Tests are code that we write, which we can run on our application code to make sure it's behaving as we are expecting, and that any changes we've made don't have unintended consequences. The goal of tests is to catch bugs before they get to the production site and break things.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests help ensure code behaves correctly at the time of writing, and that future changes to the codebase don't introduce unexpected errors. Because the difficulty and time of debugging and fixing code errors increases further along the development process, the goal of tests is to catch bugs as early as possible. While tests are a fundamental part of writing any software, they become more important as applications grow.

In general, tests run:

  • During development (brief explanation)
  • Before pull requests are merged (brief explanation)
  • Before the code is deployed to production (brief explanation)

Make sure to run existing tests (and add new ones) whenever you're changing existing code or working on a new feature.

At the moment, there are many existing parts of the Boba codebase that need tests written for them. If you're a beginner looking to get involved, writing tests for the existing code can be a great way to get a sense of how things work while contributing critical infrastructure.
:::

We use a number of techniques and tools for testing different parts of the codebase. The following pages will outline how to write different kinds of tests, but many tests center around making an assertion that an outcome matches our expected outcome. A good example of this are [Jest](https://jestjs.io) tests, whose assertions use the basic format:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than making an example with Jest here, I'd write about the Arrange-Act-Assert framework and give a pseudocode example of a test.

I realized I had written something to this effect in the server test guide (it shouldn't have been there): https://bobadocs.netlify.app/docs/engineering/boba-server/apis/testing-endpoints/#test-cases

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that it's important to split things in sections, so I would make sure to start a new one for this.

expect(value).toBe(expectedValue);
```

We explicitly set the `expectedValue` to the outcome we want, and the `value` may be a value that was returned from a function we are testing, as in [the basic example the Jest docs provide here](https://jestjs.io/docs/getting-started), or a more complicated stand-in for the workings of our application, like an HTML element in the case of UI tests - which will be covered in detail on the next page, UI Tests with Jest and Storybook.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After the Arrange-Act-Assert section, I think it might be nice to introduce a small section on different types of tests as a general overview. In particular Boba has:

  • Unit tests (Jest)
  • Integration tests (Jest + React Testing Library + Storybook, Cypress, Jest+Supertest on the server)
  • End to end tests (we don't currently do these)
  • Manual tests (just to mention it. We can callout storybook.)

I'm uncertain whether we should explain the libraries here. We might want to do so closer to where they're used, though we use Jest everywhere, and RTL and Cypress in every frontend codebase.

title: UI Tests with Jest and Storybook
---

This guide will cover how to write tests for the bobaboard-ui codebase. It assumes that you have some familiarity with Bobaboard as a user of the site, have taken at least a brief look at the file structure of the [bobaboard-ui codebase](https://github.com/essential-randomness/bobaboard-ui), and have a basic understanding of javascript, [Typescript](https://www.typescriptlang.org/docs/handbook/typescript-from-scratch.html), and React components and props. If you would like to brush up on React, the React docs offer a number of great [resources for learning](https://reactjs.org/docs/getting-started.html#learn-react).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand why this is here, but I think we need a more concise way to express this. Maybe we can do a custom callout that says:

::: prerequisites
- Basics of testing (link to doc)
- Jest (I'd write this as a separate guide since we use it on the backend too, and that has no storybook)
- React (I would say typescript and JS are a prerequisite of React). 
:::

We can have an intro page for React with resources, and link that here. You can also link the last bulletpoint to the react guide for now.

If you want to see how to create a callout, refer to this: https://github.com/essential-randomness/bobadocs/blob/main/docusaurus.config.js#L146

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that if we write Jest as a separate guide, there's still Jest assertions that only make sense in this context (e.g. toBeVisible, so we can keep those for this guide and simply mention it from the Jest guide.

});
```

### Determining What to Test
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should go in the general testing guide.


import { render, screen, waitFor, within } from "@testing-library/react";

import React from "react";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't introduce imports before they're necessary. If we want to have a full testing template, this should be in the UI tests codebase, not in the documentation (though we can import it in the documentation from there). As a rule of thumb, the further away from the code something like this is, the less likely it is to be updated when changes happen.

I don't think a test template is necessary as of now.

- [@storybook/testing-react](https://storybook.js.org/addons/@storybook/testing-react) - Lets us use our stories in Jest tests.
- [Actions](https://storybook.js.org/docs/react/essentials/actions) - Lets us rig buttons and the like (that would normally interact with things outside of the current component) to tell us a certain thing happens when triggered.

## Stories
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me wonder whether an explanation of storybook stories should be its own document, since it exists unrelated to testing. You can add a TODO to add a standalone intro and move some of this content here.


Similar tests are run on the Pinned Menu, and then the following tests are run on the whole Side Menu:

```typescript title="tests/20-SideMenu/SideMenu.test.tsx"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are too long examples, and I don't think they're adding much. If you want to give examples, I'd simply point out what you might test as a list, without code.

You might say something like:
For example, for a board menu section (link to storybook) we might test:

  • That the regular section is displayed
  • That a board with updates is displayed
  • That the current board is displayed

We should also tests that this is displaying correctly in context, without repeating the bulk of tests. For example, in Side Menu, we can write the following tests:

  • Sections are displayed correctly
  • Pinned menu is not rendered when turned off
  • ...

(the language above sucks, but that's the idea)

@enigmalea enigmalea self-assigned this Aug 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants