Unit tests ensure that individual components or modules of a software application function correctly in isolation. Unit testing is a type of developer-driven testing. “Developer-driven” means that unit tests are primarily created by software developers as part of the software development process.
Isolation is a key characteristic of unit tests. In a unit test, external dependencies such as databases and web services are usually excluded so that the unit test focuses only on the functionality of the unit in a controlled environment.
What is a unit, really?
There is a lot of confusion about what a “unit” is. As mentioned earlier, unit tests verify that individual components or modules of a software application function correctly in isolation. Most developers have a clear idea of what a “class”, “function”, or “method” is. However, the definition of a “component” or “module” is not as clear. It seems that a lot of the confusion about unit tests stems from not having a clear definition of what a component or module actually is.
A component generally refers to a distinct, reusable part of a software system that has a specific functionality or responsibility. Components hide the complexity of their inner workings and only interact with other components through well-defined interfaces. You can think of components as the building blocks that can be combined to create a software application. Examples of components include classes in object-oriented programming, functions in functional programming, or UI elements in web development.
So what is a module? A module is a collection of related components that form a higher-level unit of organization within a software application. In many programming languages, modules can be imported or included in other parts of the application to enable code reuse and separation of concerns. Examples of modules include Python packages, JavaScript modules, or namespaces in C++ or C#.
Given the definitions above, we can surmise that a “unit” is not necessarily limited to a single function, method, or class. A “unit” may be a single class, a single function or method, a group of functions or methods, or even a group of related classes. In general, a “unit” may comprise a single component or group of components. Some people strongly disagree with this viewpoint and will tenaciously insist that a group of classes does not count as a unit. However, one thing that most people agree on is that your unit tests should execute faster than any other kind of tests you have.
What, then, is an integration test?
So when does a test stop being a unit test and start being an integration test? Again, there are many opinions on this. A unit test becomes an integration test once it crosses the line between two components that require some form of data serialization and deserialization to communicate with each other. According to this school of thought, examples of integration tests include those that verify interactions between two web services, interactions between code and a database, and other similar interactions that require data serialization and deserialization between components. Tests that verify behavior across one or more components without any data serialization and deserialization still qualify as unit tests.