Some notes from the Frontendmasters' workshop Testing Fundamentals
by Miško Hevery.
Theory
- We test because it is the path of least resistance.
- Micro development model: develop - test - develop - test, etc. The question becomes: are tests are automated?
- The magic of testing is how I design my code so it is easy to test. It is not about the tools or knowledge.
Kind of tests
- Testing level: unit tests, integration tests (functional), system test (e2e), acceptance tests.
- Automation: automated tests, manual tests.
- Functionality: functional, performance, security, usability, a11y.
- Other: regression (add tests when a bug is found and fixed to avoid the regression again), smoke (large system but running all tests takes hours, so you select a subset of tests for a sanity check).
Code
Unit testing (tools, TDD, mocking, dependencies, coverage, benchmark)
- They use
vitest
in the course, but I guess it is a similar test runner to sayjest
syntax-wise. - You may have a function to test that calls an external service. It would work if you make the api call in the test, but it will get expensive (what if you are testing a card transaction..) and flaky (what if the service is down..). So
mocking
is like inserting a collaborator on the other side of the api call that returns the stuff you want for your test. - So to test
fetch
, instead of importing and calling it in the function, you pass it to the function so you can mock that function. Like:
const functionToTest = async (arg1, fetch) => {
const response = await fetch(whatever)
return response
}
So the test will have:
it('whatever', async () => {
// This is the "pretend" fetch, but it doesn't know what to do yet
const mockFetch = jest.fn<Type>()
const response = functionToTest(whatever, mockFetch)
expect(response).toWhatever()
})
- You can do
it.todo()
while you are writting tests, they won't error out. -
expect(object).toMatchObject(anotherObj)
I think it is similar to theexpect.objectContain(anotherObj)
. << TBD, I forgot the exact syntax.