alexandria-reader / frontend

Alexandria reading app front end
https://tryalexandria.com/
GNU Affero General Public License v3.0
9 stars 1 forks source link

tests: improve frontend tests #286

Open eamon0989 opened 2 years ago

eamon0989 commented 2 years ago

The problem with our frontend tests is that the depend on the backend database being in a certain state. Currently, the tests do not pass and are skipped. Instead, we should mock the api responses and ensure everything is correctly rendered.

One example of how to do so is shown here: https://www.digitalocean.com/community/tutorials/how-to-test-a-react-app-with-jest-and-react-testing-library

mrchrmn commented 2 years ago

I agree. Testing is the area in where I had to level up and learn the most in my first couple of months. Especially how to mock dependencies away for pure unit tests,

eamon0989 commented 2 years ago

I don’t work with React at work, how do you generally go about doing testing? Do you test the components or the services? We also mock dependencies on the back end so that part shouldn’t be too hard.

medic-code commented 1 year ago

Hi Eamon and Marc, it's Aaron from Launch School.

Take everything below as just my own experience and that you guys have a lot more experience being devs, but thought I'd give you some of my own experience on testing with my own App.

Definitely sounds like you want to mock the api responses as it sounds like the tests are a little brittle. It's also worth considering some CI to only be able to push when specific tests/all tests pass. Its also possible to use husky for pre-commit testing and only commit when tests pass (but this can slow developer time down).

There's a couple of options for mocking

  1. Mocking with Jest - you can mock an entire module like axios, mock specific parts like get method
  2. Nock
  3. Mock Service Workers
  4. Use a test database instead of prod - setup the database prior to tests running (delete previous records and input select data into database)

Nock and MSW are mocking libraries they both work by monkey patching http requests, although MSW does intercept real network requests in the browser by service workers. This means that the app doesn't really know its a mock. Nock intercepts node's http request function and allows you to specify what gets returned, which is slightly more removed.

Using a test database is truer to a real request and so captures problems on a real database. The problem being is that the testing will be slower.

Personal Experience I've used nock mostly because it's slightly easier to set up, doesn't require loading up a server you can just install and go. Nock is one step removed from the source of the backend compared to Mock Service Workers. MSW is as close to the backend as you can to mimicking network requests. Personally using Nock + Testing library has been what I've used its been relatively painless for unit and integration type tests. Cypress for e2e.

It would be worth having a discussion about what you would want to test, are you unit testing heavy + e2e/integration testing heavy ? Whats your opinion on testing props/handlers being called. Are there things you don't want to tests ? What are they ?

Testing both components and features (either by e2e or an "integration" type test) seems reasonable but at a component level it can be quite easy to test implementation details. The line between testing from a user perspective and implementation details can get very blurred when testing components when I've been thinking about the component tests myself. Feature testing allows better spread of testing code so can detect more problems.

Some Resources https://www.lola.tech/blog/tech-we-love-msw-mock-library https://kentcdodds.com/blog/stop-mocking-fetch https://refine.dev/blog/mocking-api-calls-in-react/

I've tried to split my testing into individual components - what would a user do and how can I test that at a component level ? Then at a capability level test something a user would want to do.

So a good first step might be, what are the main user flows throughout the system ? What are the most critical things that need to be tested ? Go by each component and right down descriptions of tests at a component level that would a user would be interested in. This gives you a starting point to know what to test. You can then make some decision on actually what isn't important to test.