Black Box Testing and White Box Testing Characteristics
When we test a software by using its interface (that is generally graphical user interface), it is called black box testing. In other words, when you download and run an app, you are doing black box testing. In black box testing, we are not at all concerned with the internal functionalities and code. We are just concerned with inputs and outputs. It is called black box, as we do not see inside the software. We just interact with the software with the provided interface.
When you purchase a car and take a test drive, you are doing black box testing. As you are not a technician and you don’t know about the internal wiring and functionalities. Therefore, in black box testing, the product looks like below diagram.
Black Box Point of View Or External Quality Characteristics
The black box point of view is actually the user’s perspective. It is how a user or client perceives a software product.
The correctness here does not mean the correctness according to the universal rules. Rather it should be correct according to the client’s wishes. Say if a client says 2 + 2 = 5 is correct then 2 + 2 = 4 would be incorrect. Therefore, the core purpose of the software industry like any other business is client’s satisfaction.
Usability means the product should be used as it was intended to be used. We can achieve this goal only if the interface of the product is very much intuitive. The best usability would be if a product could be used without reading the user manual. So what is the best usability? In a remote village of India, an experiment was conducted. They put computer inside a cabin like ATM machine. Only mouse, keyboard and monitor screen were reachable. People in that village were mostly illiterates. Nobody taught them how to use a computer. However, after few months, many persons in the village became expert in using the computer. It means the GUI of computer has very good usability. Let us analyze it.
As I already stressed on the intuitive feature of graphical user interface. The intuitive feature depends upon what we learn unconsciously while growing up. When human baby starts crawling, the first thing he/she learns is the distinction between door and the wall. He learns that the door is an entry point. You can understand the computer’s graphical user interface with same analogy. The icons are doors. We knock the door (double click) to enter into a house. There we see further doors and that recursive activity helps us exploring the whole computer.
When computers were new in the market, many funny incidents happened. A woman called to a compute shop and reported that her computer’s teacup stand got out of order. You know what! She was referring to the CD ROM player as its shape was very much suitable to place a teacup. The best solution of this problem is not to add it in the user manual. Rather we should change the shape of the CD ROM player so that no one confuses it with teacup stand.
In short, if you want to enhance the usability of a product, you should develop it according to human intuition or instinct so that the user could use it without reading the user manual.
What is efficiency? The following picture can explain it a little.
He is trying to achieve maximum possible output by using his available resources. That is efficiency. In other words, achieving maximum by using minimum possible resources is efficiency. A software product is efficient if it consumes minimum possible resources (CPU cycles and memory) but has very high response time. This property of the software products make them more popular. A product would be less popular if it needs high-speed computers to run on. You know, we humans have a threshold of patience. If a website or application makes us wait more than that threshold, we cannot bear it. We tend to search for a better website or application, which can respond more quickly.
They say that life is not reliable. Why is it like that? The answer is quite simple. If we add 200 years to our current ages, it is for sure that no one of use would survive on this planet earth. That is the issue of reliability. Your software product should give the same results no matter at what time it is tested.
Time zone issues are the sources of so many bugs. A bug may occur at 3:00 am in the morning only and the rest of the time the application may run quite fine. Therefore, when the software testers report the bug, they usually attach the screen shot of the bug along date, time and time zone.
The integrity of a software product ensures that the private information of the software is secure. No one should be able to break into the product.
It is the prime concern of every client that no one should be able to steal the company data. The attackers try to breach the integrity of an application by many methods. For instance, they can use SQL injection to steal the private data. To understand the SQL injection, let us see a scenario. Say there is a website that shows the results of the students with following fields.
Session : _________________
Roll Number: _____________
The user enters the Session and Roll Number to find out the results. A hacker can use SQL injection to modify the hidden SQL theory. Say the SQL theory is
Select from table where session = “2017” and rollnumber=”abc”.
If the user enters in the value “2017//” in first field and keeps the second field as blank. The query will be as
“Select from table where session = “2017//” and rollnumber=””.
It means, the commenting line would comment out everything after 2017 and the query would fetch the results of all students of 2017 session. The software product should have the integrity level high enough to withstand all such malicious attacks.
Software needs to be adaptable. Every client wants to get maximum possible by spending minimum possible. If a software product is adaptable, the customer can use it for different purposes. For instance, the student management system (Moodle) is very adaptable. That is why it is so much popular universities. Do you know what actually the WordPress is? It is a merely a website. However, it is very adaptable website. Everyone can customize it according to the specific needs. When we do Black box testing, we do check the adaptability feature of the software product.
Accuracy and Precision
The following picture beautifully explains the concept of accuracy and precision. In short, the accuracy is more about the correctness of the result and the precision is more about consistency of those results.
The following picture explains the concept of robustness.
The long and strong roots make a tree robust enough to withstand every windstorm. The software product should be robust enough that it should not crash in any situation. When a software application crashes, it imparts very negative impact on client. The concept is very easy to understand, if some mobile app crashes repeatedly, we simply tend to uninstall it. The software should not crash at any cost even if the input is quite stupid or illogical.
However, when we try to increase the robustness; we have to compromise on accuracy or correctness. Let us understand the concept by a very simple example. Say you open your Facebook account in web browser. As soon as the internet connection is disconnected, the web browser would go blank. You will not be able to browse Facebook. However, if you open the Facebook app from your smart phone, you will see the olds feeds there. Although, the feeds at the top are not the recent ones, but the application is very robust. It simply does not go blank. However, it does compromise a little on correctness as it show the old posts on top. On the other hand, the web browser does not compromise on correctness. It shows only the most recent post on top. However, its problem is, it goes blank when there is no internet connection.
The bottom line is, we may or may not compromise on correctness, but there should be no compromise on robustness.
White Box Point of View or Internal Quality Characteristics
The white box point of view is actually the coder’s perspective. It is how a coder looks at a software product. As the following image shows, in the white box testing, our focus is on internal coding not the front-end graphical user interface.
The coder has usually following concerns.
How can you easily maintain a code? The answer is simple. The code is maintainable if it is not complex. So, what is complexity of a code? Here, by complexity we do not mean what you might have studied in your analysis of algorithm course. Here the complexity is actually the cyclomatic complexity.
Before going into technical nitty – gritty, let us try to understand the actual concept by a simple analogy. If you have to explain your address to your friend. You may need to draw a map or you may simple tell him the lefts and rights from his current position. The address will be the easiest if there is no left or right. As the count of lefts and rights increases, the address would start complicating.
Now guess! What part of the code can be considered as lefts rights? Our code undergoes simple statement-by-statement execution unless there comes any decision point. This decision point may be an if-else or switch-case statement or loop conditions. Hence, the decision points of the code are equivalent to the lefts rights of the road. The more decision points, the more complexity and it is more difficult to maintain the code.
There are different formulas to calculate the cyclomatic complexity. We would discuss the concept of cyclomatic complexity in more detail in next tutorials. To keep it simple, you may take the cyclomatic complexity as the count of binary decision points plus one. So, if there are ten ifs in your code, the cyclomatic complexity is 10 + 1 =11. Another formula to calculate the cyclomatic complexity is E – N + 2. For this method we draw the control flow graph for the given code. E stands for edges and N stands for nodes.
Now, the next question is, how to get rid of decision points. The if-else code design has always been prone to mistakes. The initial attempt to replace if-else code was the switch-case code. However, if you analyze the switch-case syntax, it is the same thing just dresses up in different way. The switch-case statement is also problematic and a cause of human mistakes. Finally, the polymorphism of object-oriented design replaced the switch-case syntax. In polymorphism, as you know, the reference of the parent class automatically calls the method of the concerned object depending upon the value.
In short, if you want to make your code maintainable, decrease the count of decision points.
Flexibility is very important not only in coding but also in attitude and in our body. The more flexible body means less tense brain. In white box testing perspective, the flexibility means the code should be flexible enough to modify for new requirements. As you know, the requirements keep changing. It may be due to non-technical background of the client or it may be due to the universal rule that change is inevitable.
Therefore, we should always be ready for the change. It means, we should design the software in such way that it is easy to be modified. As you know, the software engineering is quite a new field when we compare it with mechanical, civil or other classical engineering fields. Its design techniques are still not as mature as other fields. If we analyze the products of other engineering fields, we observe modularity, cohesiveness and decoupling. We should apply these techniques in software engineering fields as well. These concepts make the product very flexible and easy to modify at later stages.
Let us take the example of a car. If somehow the headlight goes out of order, the car will not stop and if we the replace the headlight, it will have no ripple effects or repercussions on other parts of the car. It is the beauty of mechanical design of the car where the engineers kept in mind the concept of modularity. Modular design means, we divide the given product into modules and if we change one module the rest of the product remains intact.
In software engineering, there is a funny saying, “There was a bug in my code, I fixed it and now there are hundred bugs.” It happens when the code is entangled in haphazard way. Hence, to make the software product flexible, we need to keep in mind the following concepts.
We should design product by using modular approach. Instead of developing the product as single giant module, divide it into smallest possible modules. This approach not only makes a better design but it also helps in work assignment to the development team. We may assign different modules to different developers.
The cohesiveness means keeping the interrelated parts together. Say, A, B, C, D are four parts in your application. The part A needs C for some processing and the part B needs D for some processing. In this case we should keep A and C together and similarly B and D together. In other words, the inter-dependent parts should be in the same module.
Decoupling means, the modules should be independent of each other. Decoupling and cohesiveness are related to each other. If we achieve cohesiveness, we also decouple the modules.
Humans hate repetition. It seems very laborious re-work when we code the same thing repeatedly just because the change of platform. Portability means, you write a code once and run it on all platform. When Java came to market, the foremost reason of its popularity was its portability. I could be run on Windows as well as other platforms. Therefore, software developers choose such technologies that are independent of platforms.
You know the best developer is the one who knows who to copy and paste. Copy and paste does not mean cheating at all. It means the skill to reuse the old modules in new systems. It not only saves time but also increases the profit. These days there are so many open source libraries. In old days, it was a common practice in software houses to build their own libraries and reuse them in new product. It is the best practice for the software developers that they should develop any application in modules and that modules should be reusable in other products.
We can put it this way that whenever you develop a new product, you should make sure that its modules are completely decoupled and can be used as plug and play in other product. For instance, in almost all the web applications, we see the sign up and sign in module. If we design these modules in such a way that they are decoupled and flexible enough to be customized for new products, it would be a good example of reusability.
You know it from school days that you always get better marks if you have good handwriting! Similarly, the code readability is very important. If the code is not properly indented and commented, we cannot understand even our own code. Code readability and proper documentation make it easier to maintain and update the code at later stages. For any big software application, there are usually more than one developers involved. Therefore, if the code is not readable and does not follow the coding standards, the developers will not be able to understand each other’s code.
We can test a code only if it is testable. While coding we should make sure, that each statement is testable and reachable. Sometimes, some flow of the applications are not at all reachable by the provided interface. Here, in white box testing, interface does not mean the graphical user interface. Rather it means the interfacing methods of the class that help the outer world to communicate with the inner logic of the application. For instance, say you develop an API. The interfacing methods should be able to test all the business logic of the API. Another example may be, say a method or routine is fired only on February 30. And, you know that date would never come in the life of the software application.
Every software product has a life. We have to redesign and recode it after its life is over. Now the question is, how can we increase the life of a software application? Definitely, emerging software and hardware technologies are a reason why Softwares are outdated after few years. In addition to that, another factor is the lack of understandability. It is because we need to incorporate the changes in the software with changing scenarios of business. These changes keep on complicating the design and coding structure. The repeated cycles of upgrades and changes make the code so complex that with the passage of time, the code becomes incomprehensible. There comes a point where the product owner decides to redesign and recode the whole application. This decision definitely involves lot of budget. Therefore, it is imperative that we design the application that it is quite understandable and incorporating changes does not complicate it much. This goal is not an impossible thing. We can achieve it by making the product modular where every module is much decoupled. In this modular design, making change in one module will not affect other modules. In addition to that, we can assign each module to each developer to develop complete understanding. A developer can understand a single module quite easily. However, it is almost impossible for him to understand the whole product. It is only possible if we use the modular approach.