An application can be conceptualized as a combination of many small, individual modules. In order to test the entire system thoroughly, it is imperative to thoroughly test each component or the smallest unit, since a component is the smallest unit in an application. So, Component Testing, as its name implies, focuses on testing of the smallest or lowest parts of an application.
Let’s dig a little deeper into this to understand this practice in more depth.
Normally, components are individual elements of an application that can be integrated to form the application as a whole.
Component testing is a type of white box testing where you validate an individual component of the application before testing the entire application.
As a consequence, component testing finds bugs and verifies the functionality of software modules/programs which are individually testable. Component testing is also known as program or module testing. It results in the detection of defects in software modules and checks the functioning of the software.
ISTQB defines component testing as testing each individual hardware or software component separately and efficiently for a given application. Suppose, for an instance, that an application contains five components. Testing each component separately is termed as component testing.
Below are the objectives of component testing:
Component testing is divided into two parts, based on the depth of testing: Component Testing in Small (CTIS) and Component Testing in Large (CTIL). Component testing in small means doing component testing in isolation with other components. This does not require other components for integration. On the other hand, Component testing in large is done when there is a dependency of other components and we can not segregate the two dependent components.
While performing component testing in large, two components can not be isolated and are dependent on each other and either of them is undeveloped. Stub and driver helps in replacing this dependency.
In the context of code, Stubs describe code snippets that receive inputs and respond to the top module. A stub is invoked by the component that needs to be tested. A driver calls the component that needs to be tested. In case the calling function of the lowest module does not exist, drivers acting as a dummy program are used to call its functions.
Single components/units are tested when component testing is performed. In component testing, certain characteristics of system components may be verified, such as their functionality as well as non-functional parameters.
Component testing can include functional aspects (for example, checking for computed errors), non-functional characteristics (for instance, identification of memory leaks), or structural aspects (for instance, testing for decision-making processes).
A component test takes place prior to integration testing. It is the first level of testing the system goes through. Depending on the development life cycle model selected for that particular application, component testing may take place in isolation from the rest of the system.
Usually the component testing process is performed after the unit testing process. It is an ideal process to test components or modules once they are created.
The reasons for this are that if a component is thoroughly tested, then significant defects will be less likely to appear in later phases. The applications we develop today are highly complex, and it is very challenging to test all aspects of them which results in a gap in test coverage. Therefore, component testing is conducted before moving on to higher testing levels, given that the software comprises multiple units/modules.
Error detection is easier and less time consuming in these units. Nevertheless, outputs produced by one unit may serve as inputs to another unit. Therefore, if a wrong output is created by one unit, but is utilized by a second unit, that unit will also create an incorrect output.
Unless the initial unit is tested independently using component testing, any subsequent integrating components may produce unexpected results. Consequently, all software units must be tested independently using component testing to avoid this issue.
There are several fundamental points that need to be taken into consideration when performing component testing. Developers or QA Engineers can perform component testing as White box or Black box technique. As components are tested early in the development process when they are created, there is a possibility that the results retrieved from a component under test may be dependent on other components that are not yet developed. A Stub and Driver replaces the missing pieces of software and simulates their interaction seamlessly.
In this type of testing, debugging tools or unit test frameworks are used since the programmer is directly involved in the execution of the code. A development environment is used to track and fix errors as soon as possible once they are discovered.
Defects are not formally recorded in bug tracking tools. Individual modules or units are tested independently. Each module receives some input, performs some processing and produces an output.
In order to increase quality and minimize business risks, several automated frameworks are available to facilitate component testing, including Jtest, Junit, JMockit, EMMA.
Junit tests the data before inserting it into the code snippet, whereas Jest provides tools that help speed up the development of Java software, such as static analysis, unit testing, and code coverage.
While JMockit is an open-source component testing tool that provides line coverage, route coverage, and data coverage metrics, EMMA is also a code coverage toolkit for analyzing code.
Developers who write the particular component or module perform Component testing. Usually they perform testing in their local environments before publishing the code to higher environments. At times, depending on the appropriate risk level, a separate programmer may perform the component testing. Occasionally if necessary, QA Engineers can also perform component testing.
Basically, a component level testing is primarily driven by four inputs: Project Test Plans, System Requirements, Component Specifications, and Component Implementations. Detailed design for each component needs to be appropriately structured. Moreover, it is essential that each component’s code blocks are clearly defined.
A data model is properly discussed and designed that provides details about how the downstream component will receive data from the upstream component. Furthermore, it should take into account how the data will be passed onto the downstream integrating component. The test basis to write test cases and test analysis also included Component Specifications, which provide details about the architecture of the component.
Code developers generally perform component testing. This should be performed before moving into developing another component. A test-driven approach, such as Test-Driven Development (TDD), consists of writing the test first and then implementing it.
Using TDD, the first step is to create a failing test case, run it, and verify it fails. Because the coding is still incomplete, the test case will fail upon execution. The developer completes the coding to guarantee the test case passes. Upon passing a test case, a developer moves on to the next feature; otherwise, he refactors the code. If a test case fails, the code needs to be modified. It can also happen that the test case passes, but there are performance issues which require further refactoring. This process repeats until the developer passes the test case with the code refactorings.
The component testing is a method of evaluating the correctness of a particular unit of source code produced during software development. Typical test cases possible are as follows:
The lowest unit of an application is the component, and it is independently tested. These are tested after unit testing.
The interface acts as the link between two components. Basically it is a layer that joins the two components. Interface testing evaluates the interface between the two components or the platform on which they interact.
Generally, API or Web Services are tested in interface testing. So, we can not use Black Box testing techniques to test these interfaces, but instead, we would use SOAP UI or some other tool to test API or Web Services.
Integration testing is conducted after interface testing is passed. We combine and test each component one by one in a sequential manner during the Integration test. As a result of Integration testing, we confirm that the individual modules behave as expected when combined individually and that no data is changed as a result of passing from one module to another. All components of the application are integrated and tested prior to the systems testing stage.
As soon as all the components have undergone integration testing, we take part in System testing, which tests the entire application/system as a whole. The primary purpose of System testing is to validate whether the business requirements match the implementation of the software.
Component testing is crucial in finding the defects. As a preliminary step to integration testing, we should always conduct component testing to ensure each module works correctly and according to specifications. By now, you should have a clear understanding of component testing and its importance to ensure product quality. Component testing ensures that everyone owns quality, not just the testing team and therefore overall quality is guaranteed.
Related posts: