Hi, this is the second lecture about testing. In this lecture, we'll talk about the three types of tests that we can perform on a software system. And they are, white box testing, black box testing, and also, regression testing. And we will start with white box testing. And in the last lecture we have already covered what is basic path testing. And in this lecture we will focus on, conditional testing, loop testing, and also data flow testing. So some of you may ask, why do we want to perform condition testing on conditional statements that we have within the program? And the reason is that, it's easy to make mistakes on conditional statements. And that's why we want to focus testing on those statements that we can easily make mistakes on. And in conditional testing we try to execute the true and false values of each simple logical condition in a component. And we focus on conditional statements that we have within a program, for example a simple condition, compound condition, relational expression or brilliant expression. And again we want to focus on testing conditional statements. Because they are the places that we can easily make mistakes due to incorrect, missing, or extra boolean operator, boolean variable, parenthesis, relational operator, or arithmetic expression. And if we have a compound statement within our program, for example some condition and another condition. Then we should test every simple condition that we have within the compound statement. And notice that basic path testing already called for these cases. Now let's take a look at the example. Now let's say we have a compound statement within our program. For example statement number six is a compound statement, and we have like if A and B, then we perform statement number seven, and then out we're going to perform something else. And now let's say we have this program, and we want to derive the photograph of this program. What we're going to do is that, we're going to separate the compound statement into two simple conditions which are 6a for the condition A, and then 6b for the condition B. Now, once we execute statement number six we got the first double check the condition 6a. If 6a is true, what we're going to do? We're going to double check the condition for 6b. Okay, then if 6b, is also true, what we're going to do? So both 6a and 6b, they are true, that means the entire compound statement is going to be true. So we're going to execute statement number seven. What if 6a is false, then we're going to execute the else statement, which is statement number eight. What if 6a is true, and then 6b is false, then again, we go to the else statement, because it's going to make the compound statement false. So that's why we go into the else statement. So if you have a compound condition in your program, then eventually you will have a triangle like this in your flow graph. And you're going to double check all the simple conditions that you have within your flow graph using basic path testing. And all the simple conditions that we have within the compound statement will be covered by basic path testing, because we treat each simple condition separately. And then, we will also perform domain testing, for example, let's say we have E1 is going to to be bigger than E2, let's say X is bigger than four in our program, then we do something. Then what we're going to do is that, we have to test the statement using values that is going to make E1 greater than E2, E1 equal to E2, and E1 Less than E2. And let's say, we want to double check whether X is bigger than four in our conditional statement. Then we need some x which is less than four, for example two, and we need some x which is equals to four. And then also we need some x, which is bigger than four, for example six, to test out the conditional statements. So in this case we need three inputs, to test out the conditional statement, for example, x is bigger than four. Then for loop testing, we focus on testing, executes loops at and within their bunks. For example that, in a loop you're going to have n iterations, then what you need to test is that you need to test the loop with 0,1, or two passes or m passes where m<n. And then n-1,n, and n+1 passes through the loop, just to make sure that the loop is going to work well at the minimum number of passes and the maximum number of passes. And also some normal number of passes within the range. Now if we have nested loop, then we're going to conduct simple loop tests for the innermost loop while holding the outer loop at their minimum iteration values. That means for the inner loop, we're going to apply simple loop testing. That means, we have to test the loop using 0,1 and 2 passes, and passes, and also n-1,n and n+1 passes. And then for the outer loop we keep it at its minimum iteration values, for example just 0 or 1 passes. Why do we do that? We want to focus on, for example, testing the inner loop while making the outer looks simple. Okay then the next thing that you should do is to work outward. Okay, that means you're going to make the inner loop simple with 0 or 1 passes. And then apply simple testing on the outer loop, and then you will continue on until all the loops they have been tested. And notice that test grow geometrically with level of lasting. So that means, if you have one loop within another loop, within another loop, within another loop, you will need more time for testing. And what if we have like contaminated loops? That means one loop followed by the other. If the two loops, right, they don't depend on each other, then we can apply simple loop testing on each of them. If they are dependent on each other, then you can apply natural loop testing. That means you test one of the loop while making the other loop at its minimum number of passes. And what if we have like unstructured loops in our program, and notice that we should not have any unstructured loops in our program. If they exist, right, then you should refactor the code and improve the structure of your source code. So that's the rule that we want to keep in our mind. We want to come up with some tests that have the highest chance of uncovering errors with the minimum efforts. And another type of white box testing, that we can perform on a program is data flow testing. In data flow testing, we try to ensure that the value of a variable is correct at certain points of execution in the code. So what is a defition use chain? For example, if you have a variable x, then the defition use chain of x. It's going to be the place that you define x up to the point, where you use, or consume x. So in data flow testing, we focus on the path where we define x, and then later on, where we use x, and we focus on those paths. And then in our program, every defition use chain must be covered at least once. And for every variable, do a test along the path from where the variable is defined, to the statements where the variable is used. In this test, they can be combined with basic path testing.