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.
What is Component Testing Or Module Testing
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.
Objective of Component Testing
Below are the objectives of component testing:
- Verify components functionality: The aim of component testing is to ensure that the test object’s inputs and outputs are working correctly as specified. It ensures that the object’s functionality is working correctly as well as being in harmony with the desired specification.
- Reducing risk: A developer finds out the errors in the code and fixes them. As a result, it reduces the chances of risk at a fundamental level.
- Finding errors: Its primary objective is to find errors in the source code of the application. In addition, it validates the function call flows, control flow, data structure, etc used in the program.
- Confidence building in component’s quality: The majority of errors are detected and corrected while coding since component testing is done at the unit level. In this way, the product is developed with a greater assurance that it will have fewer errors in further testing.
- Escape defects to higher level: The developers detect and eliminate all coding errors in Component testing before escalating to higher levels of testing.
Understanding Stubs and Drivers
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.
What is tested under Component Testing
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).
When do we need to perform the Component Testing
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.
Why component testing is performed
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.
How component testing is performed
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.
Who performs component testing
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.
Component Testing Process
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.
How to write component test cases
Component test cases should be written such that individual components as well as integrated components are tested.
- Components, Units or Modules: Each component or module should be done by each developer to ensure that his or her work doesn’t break any other components that share code.
- Code and Data Structures: This could mean incorporating best coding practices, and making sure that code won’t cause harm to other components.
- Classes: In order to ensure Object-Oriented Principles are followed, it is necessary to test each class and use encapsulation, so that another class cannot directly access data inside a class. As a result, the application is less vulnerable to security threats.
- Database modules: A database stores information entered into a User Interface (e.g., a new customer registration). Therefore, it is necessary to test the database in component testing along with the front end.
Component Testing Techniques
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.
Example Test Cases for Component Testing
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:
- Functionality of component: Test the functionality of component/module as per the business requirements. Example, If a component is tested that should return the discount value whenever a customer applies a coupon on the E-commerce website should return the correct value.
- Data flow: It is common for components to pass data on to another integrating component, and that data flow should behave as expected. Example, a discount component that returns a discount value is restricted to alphanumeric characters and the discount coupon creating component should not allow special characters too. Hence, if the discount component is integrated with discount coupon creating component, it will not cause any data flow problem.
- Code logic: Test the code logic for the edge cases. Example, In an E-commerce application, Buy two get one free logic should handle cases when four items are in the cart.
- Performance of component: Test if the particular component is not causing any performance related issues. Test for no memory leaks.
Component Testing Vs Unit Testing
- The principle of component testing is similar to that of unit testing, with the exception that the developer might use real data instead of dummy data for component testing.
- A major difference between component testing and unit testing is that the former is done by the testers, while the latter is conducted by developers or SDET professionals.
- Unit tests are performed at granular levels whereas component tests are carried out at the application level.
- As part of unit testing, an individual program or code piece is verified if it is getting executed as specified. In component testing, individual objects of the software are tested either separately or as a set with other objects/components.
- Component testing is performed at a higher level of integration and in relation to the entire application while unit testing is performed in the context of just a single unit/program.
Component Vs Interface Vs Integration Vs Systems testing
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.