I'm learning about testing. So far, I kind of get the gist of it but it's still a bit confusing.

I thought about an app like Photoshop. Unit testing would be the developer testing the 'cancel' button. Integration testing would be the QA team testing all the buttons that have been combined into a menu and see how the change the entire program. Systems testing would be the team also testing how the app runs in a OS environment.

Is this accurate?

New contributor
Eric Hernandez is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

As always, the following is my personal opinion :-)

First a comment: I am talking about tests from the perspective of a software engineer and have primarily automated tests in mind.

Unit-Test A small code Unit, a function or a class. Quit a lot of people make the mistake and test a "functionality" with it.
For example if you expect that your button will validate an given input and then navigate to another page, this would be very likely 2 Units (maybe more). The Button that triggers a second Unit, the validation, and if the result is okay, triggers the navigation (may be a third Unit).
Therefore in Unit Tests we try to mock away the dependencies, because if we do not, then we test them also AND also the integration between them.

Integration Tests In general tests the communication between two modules. With module i mean it could be a whole application, a system, a package, a component, a Class, ...
Those tests should really be focused on testing the communication between the modules. If they also are used for testing the functionality IN a module, then this may be easily done, but its hard to pinpoint an error, because of the amount of code that is run. Therefore it should be combined with testing approaches for the single module.
For example you have a feature "Optimize photo". Which makes use of an algorithm for identifying optimization potential, and then applys multiple filters to the photo. The algorithm and the filters would be extra modules. And now you run a test which optimizes a photo. As its quite clear, it would test not two, but multiple modules. That is one of the problems of Integration Tests, that the scope gets big very fast. To encounter that, we could try to mock away all the modules that we do NOT want to test. This is more implementation work, but makes the tests faster and more precise.

System tests Take the above mentioned integration test of the "optimize photo" functionality, get rid of all mocks (each module is tested) and you get a system test. A system test is a test that will run through various modules of your system. It still focuses on the integration of the modules but now with a system wide scope.
Be aware, outer dependencies, like data from an external system should still be mocked away.

The bigger the scope of a test, the more easily it will break and at the same time, the harder it will be to find the source of the problem.

So, in a thoroughly tested system, you will have a lot of unit tests, quite some integration tests, and some system tests.
That way, the chance is high that an error is catched in test with a small scope. And that makes finding the error much easier :-)

And a final remark: You can write code to achieve a functionality and then apply tests to it.
Or you can think about testing your functionality, then write the code and the tests.
The difference is, that in the second case your code design will embrace testing. In the first case it is very likely that the code design makes writing tests really hard.

  • 1
    +1 The only things I would add: Unit tests are the ones most likely to be automated, followed by Integration tests. And System tests may sometimes be referred to as Regression tests.
    – JMekker
    Jan 13 at 19:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.