Imagine a world where developers write code and it always works perfectly. Sounds like fantasy? Unfortunately, that's not reality — bugs are inevitable. Our job is not just to write pretty code, but to make sure it behaves the way we expect.
Main goals of testing:
- Reducing the chance of bugs. Even an experienced developer can make mistakes. Tests help catch and fix them before the code hits production.
- Ensuring application quality. The app should behave predictably. No one wants the "place order" button to suddenly start deleting users.
- Confidence when changing code. When you add new features, tests let you make sure the old code still works correctly.
- Saving time on manual testing. Manually checking the app every time gets exhausting. Tests automate that process.
Types of testing
Now let's break down what types of testing exist and what they're for.
Unit tests
- These are tests for individual components of your application, usually functions or methods.
- They're isolated from other parts of the system and don't require interaction with external resources (for example, a database).
- Unit tests are fast and cheap to write.
Integration tests
- They check how different components of the application work together.
- Here we interact with real resources like databases or external APIs.
- They're less isolated than Unit tests but give a better sense of the system's real behavior.
Functional tests
- They verify a specific feature of the application from the user's perspective.
- For example, testing the payment flow from adding an item to the cart to receiving confirmation.
- They often require automated tools to simulate user actions.
System tests
- They test the application as a whole, as a single system.
- They reveal issues in configuration, integration, and interaction between all parts of the system.
The testing pyramid
To organize tests people often use the testing pyramid:
/ Functional Tests \
/---------------------\
/ Integration Tests \
/-----------------------\
/ Unit Tests \
- The base of the pyramid — Unit tests (~70% of tests). They're the cheapest and fastest, so there should be the most of them.
- The middle level — Integration tests (~20%). They check component interaction.
- The top of the pyramid — Functional tests (~10%). They're harder to set up, so there are fewer of them.
The pyramid follows the principle speed-quality-cost. The higher up the pyramid, the more effort required, but the wider the coverage of the application.
Where and when do we write tests?
The earlier, the better
The earlier a bug is found, the cheaper it is to fix. If a bug is discovered in production, it's harder to fix and can negatively impact users.
That's why it's important to write tests right when developing a new feature. This approach is called TDD — Test Driven Development (development through testing). We'll dive deeper into this in future lectures.
The right timing
- Unit tests are written during the development of a specific method or class.
- Integration tests are created after integrating all parts of the feature.
- Functional tests are added at the final stage of testing, before releasing to production.
The real value of tests. Do we really need them?
Maybe some of you are already wondering: "Can't we do without tests? QA will check everything anyway." Good question! Let's break it down.
- QA testers will find defects in the app, but their job is to check the finished product. Automated tests help developers catch errors earlier.
- Tests reduce risk. You're confident that a change in one part of the code won't break another. For example, if you change API logic, your Unit test will immediately tell you if something broke.
- Increasing trust. In team development, having tests allows everyone to be confident in the code's stability.
The big picture
Imagine a large project with several development teams. Each team writes their own features, makes changes, and fixes bugs. But how do you make sure the app works in the end? The answer is obvious: through testing. It's like insurance for developers — you get confidence that things are going according to plan.
What we learned today:
- Tests are a necessary part of the development process, and they save time finding bugs.
- There are several types of tests, from Unit tests to functional ones.
- The testing pyramid helps allocate effort: more Unit tests, fewer functional tests.
- Tests are not just about bugs, they're about confidence in product quality.
In the next lectures we'll dive into practical testing. We'll start by writing simple Unit tests using JUnit 5 and get familiar with powerful libraries like Mockito, then move on to integration tests. Get ready for interesting examples and hands-on practice!
GO TO FULL VERSION