Testing your Expo app with Jest
This blog is annotated with material from Steve Kinney’s Introduction to Testing course on Frontend Masters.
My degree is in Professional Writing, specifically technical writing from an ancient Greek rhetorical perspective—basically all that means is the first question I ask before starting anything is why?.
So, why do we test software? Junior Dev me would ask, hey, we already test our code thoroughly while we write it, why should we have to double-check our work? To which Senior Dev me would reply, that’s why you didn’t get into Michigan.
The answer is, without snark or condescension, according to Steve Kinney, so we can sleep at night. But here are a few more in case you sleep fine shipping untested code:
- it's another way to document design
- forces the engineer to deeply understand every line of the application and how integrations fit together
- protect against unwanted changes
- can actually enhance developer productivity by catching errors immediately and by not introducing bugs that will need to be fixed on production
Steve’s software testing principles
1. Writing tests isn’t hard
- but it’s easy to write hard-to-test code
“The moment you know you need tests is when you get that existential dread in your heart when you go to change a piece of the code and you do not know what else you are going to break or what regressions you’re introducing.”
How do we refactor? First, surround it with tests. The goal of testing is to minimize that fear that you messed something up. Why do we test? So we can sleep at night.
2. Someone is always testing your code.
- Hopefully it’s you
3. Your tests don’t pass because your code works. They pass because they didn’t fail.
4. No one has ever broken their code into too many, small, well-named, easy-to-test functions.
Types of testing
static
- Type systems and linters to catch errors while you write
- No written tests required, only configuration
unit
- Units are any functional part of your program. They can be a functional component, class, or just a plain function
- Tests prove the validity of a unit's logic and component API: given the same parameters, always return the same output and have no side-effects
- For our purposes we'll lump snapshot testing into the unit test category because they both isolate and make assertions about basic functionality—in the case of snapshots that functionality is the render method
integration
- Testing calls to external services & storage in a controlled environment
- Ensures that component collaborations work correctly
End-to-end
- Tests the whole system
- Can be time-consuming and resource-intensive to get started and maintain but provides the closest test coverage to actual user activity
What do we test?
It’s easy to get dogmatic and philosophical about test coverage, but the fact of the matter is things will break and it’s our job to dictate what happens next.
Steve Kinney’s takeaways on errors and edge cases:
