UNIVERSITY OF EDINBURGH COLLEGE OF SCIENCE AND ENGINEERING SCHOOL OF INFORMATICS
INFR10057 SOFTWARE TESTING
April 2020 13:00 to 15:00
INSTRUCTIONS TO CANDIDATES
Answer QUESTION 1 and ONE other question. QUESTION 1 is COMPULSORY.
All questions carry equal weight.
This is an OPEN BOOK examination.
Year 3 Courses
Convener: S.Ramamoorthy
External Examiners: S.Rogers, S.Kalvala, H.Vandierendonck
THIS EXAMINATION WILL BE MARKED ANONYMOUSLY
1. THIS QUESTION IS COMPULSORY.
Given a string, the task is to encrypt this string using alternate blocks of ! and @ symbols. For each character in the string, the encryption must repeat the symbol as many times as the letter position in alphabetical order (same for lowercase or uppercase). For example,
Input 1: string = “Ab”
Output 1: !@@
Explanation: Within the input string, ‘A’ is in an odd position. So it is encoded using a block of ‘!’ symbols. Position of ‘A’ in alphabetical order is 1 so we use one ‘!’ as output encryption for character ‘A’.
Within the input string, ‘b’ is in an even position, therefore encoded with a block of ‘@’ symbols. Position of ‘b’ in alphabetical order is 2, resulting in two ‘@’ as encryption for ‘b’.
The resulting output is thus “!@@”
Input 2: string = “CAE” Output 2: !!!@!!!!!
// Java program to Encrypt the String using ! and @
1 public class StringEncrypt
2{
3 public static void encrypt(char input[]) 4{
5
6
7
8
9
10 11 12 13 14 15 16
17 18 19 20 21 22
i < input.length;
i++) {
// Get the number of times the character // is to be repeated
ascii = input[i]; if(ascii >= 97)
repeat = ascii – 96; else repeat = ascii – 64; for (int j = 0;
final char evenPos = ’@’, oddPos = ’!’; int repeat , ascii;
for(inti=0;
} }
}
j < repeat;
j++) {
// if i is odd, print ‘!’ // else print ‘@’ if(i%2==0)
System.out.printf("%c", oddPos); else System.out.printf("%c", evenPos);
QUESTION CONTINUES ON NEXT PAGE
Page 1 of 7
23 24 25 26 27 28
public static void main(String[] args) {
char input[] = {’A’, ’b’};
encrypt(input); }
}
(a) (b)
(c)
(d)
(e)
(f)
Draw the intra class control flow graph for the StringEncrypt Java class .
Calcuate the maximum achievable branch coverage for the encrypt method, which may be less than 100%. Provide tests, with inputs and expected outputs, that achieve the maximum Branch coverage.
Compute Loop Boundary and Boundary Interior coverage achieved by the tests you developed to answer question 1 (b). If maximum achievable cover- age is not achieved by these tests, write additional tests (with input and ex- pected output) to achieve maximum achievable Loop Boundary and Bound- ary Interior coverage. Show tests and coverage achieved seperately for Loop Boundary and Boundary Interior coverage. Feel free to re-use tests between the two criteria.
For the encrypt method, show tests with input and expected output that achieve All DU pairs coverage. Write out the DU pairs for the variables in the method, using the line numbers shown, and calculate coverage achieved.
Show Reach equations (used for computing reaching definitions) for Line 11 using its predecessor nodes (or statements). Show Reach and ReachOut equations for the predecessor nodes of Line 11, and their predecessors (2 iterations).
For the following program, name one control flow and one data flow coverage criterion that would help in assessing adequacy of tests. Explain why you chose these two criteria for the given program. Discuss an example program mutation, for each criterion, that can be detected by tests achieving full coverage of that criterion.
[4 marks ]
[4 marks ]
[5 marks ]
[4 marks ]
[4 marks ]
[4 marks ]
// Driver code
QUESTION CONTINUED FROM PREVIOUS PAGE
int count_greater(int arr[], int n) { int min = INT_MAX;
int counter = 0;
for (int i = n - 1; i >= 0; i–) {
if ((arr[i] > min) && (min >= 0)) counter ++;
if (arr[i] <= min) min = arr[i];
}
return counter; }
Page 2 of 7
2. You should either answer this question or question 3.
(a) What is functional testing? Name and describe two techniques for functional testing. Briefly explain why these techniques are preferred over random testing.
(b) For the following function, explain how concolic testing would work for a concrete input of
checkLeapYear(204).
Show the recorded path constraint. Show two possible new path conditions that can be generated from the recorded path constraints, which may be used to query the SMT solver for new inputs.
void checkLeapYear(int year) {
boolean leap = false; if(year % 4 == 0) {
if( year % 100 == 0) {
// year is divisible by 400, hence the year is a
leap year
if ( year % 400 == 0) leap = true;
else
leap = false;
}
else
leap = true;
}
else
leap = false;
if(leap)
System.out.println(year + " is a leap year.");
else
}
[5 marks]
[4 marks]
System.out.println(year + " is not a leap year.");
QUESTION CONTINUES ON NEXT PAGE
Page 3 of 7
} }
[10 marks]
} }
QUESTION CONTINUED FROM PREVIOUS PAGE
(c) For the following specification, illustrate steps involved in TDD. As part of the steps, the code that you write can be in the form of pseudo-code or a programming language of your choice. For the purpose of the exam, do not worry about the syntactical correctness of the code. You only need to focus on program logic and their correspondence to tests developed.
Take two integer arrays (int a[] and int b[]) as inputs.
a[] list contains marks (0 -- 100) achieved by different students
and b[] list the corresponding student ids (two digit number format).
Assume the contents of a[] and b[] adhere to the given input format.
The lists are organised such that, for any index i in the lists,
a[i] is the grade for student with id as b[i].
Spec 1: If size of either list is 0 or greater than 50,
print an error message and return empty list.
Spec 2: If size of one list is different from size of the other list,
print an error message and return empty list.
Spec 3: If sizes of both lists are equal and 0 < size of each list < 50,
then arrange the elements in the a[] and b[] lists so they are
sorted in decreasing order of grades. Note the arrangement
should respect the constraint that, for any valid index
i of the list, a[i] and b[i] belong to the same student.
Return the re-arranged list, b[], that
ranks student ids based on grades.
Hint: change the following bubblesort method (sorting in decreasing order) to take two arrays as inputs. Sort the first array and re-arrange contents of second array accordingly to help implement Spec 3.
void bubbleSort(int[] arr) { int n = arr.length;
int temp = 0;
for(int i=0; i < n; i++){
for(int j=1; j < (n-i); j++){ if(arr[j-1] < arr[j]){
//swap elements
temp = arr[j-1]; arr[j-1] = arr[j]; arr[j] = temp;
QUESTION CONTINUES ON NEXT PAGE
Page 4 of 7
}
[6 marks]
QUESTION CONTINUED FROM PREVIOUS PAGE
(d) The isPalindrome method should return 1 when all of the following condi- tions are satisfied, 1. length of the string is more than 1, 2. the given string only contains lowercase letters, and 3. the given string is a palindrome. The method should return −1 when conditions 1 or 2 are violated. The method should return 0 when condition 3 is violated. Provide tests using the mutation-based fuzzing technique. Explain how these tests differ from tests produced using generation-based fuzzing. You do not need to show actual generation-based fuzz tests. Which technique is better suited for this example and why?
static int isPalindrome(String str) {
int i = 0, j = str.length() - 1; if (j < = 0) then return -1; while (i < j) {
if (str.CharAt(i) < ’a’) || (str.CharAt(i) > ’z’) return -1
if (str.charAt(i) != str.charAt(j)) return 0;
i++;
j–; }
// Given string is a palindrome
return 1;
Page 5 of 7
3. (a)
Why is testing concurrent programs more difficult than testing sequential programs? Show a piece of code (or pseudocode) to illustrate a scenario where the code works correctly when executed in a sequential setting but may be incorrect when executed concurrently. State clearly which parts of the code are executed by multiple threads and which variables are shared between the threads. Name one concurrency bug that may occur in your code.
(b) Figure 1 shows a system composed of 5 components – {A, B, C, D, E}. Components A and B are connected in parallel. This parallel composition is then serially connected to component C which is serially connected to a parallel composition of D and E. Provide two minimal sets of components
Figure 1: System with 5 components
whose functioning ensures functioning of the system. Given the reliability of the components to be: RA = 0.95, RB = 0.85, RC = 0.98, RD = 0.92, RE = 0.9, compute the reliability of the system.
(c) Consider the specifications below with updates for extra functionality listed under New Extra Specs. Numbering of specifications is indicative of its priority, lower Spec # indicates a higher priority.
[4 marks]
[5 marks]
Take an integer as input.
Spec 1: If input is negative print ”error”.
Spec 6: Print ”fizzbuzz” if the number is a multiple of both 5 and 7. Spec 7: Print ”fizz” if the number is a multiple of 5.
Spec 8: Print ”buzz” if the number is a multiple of 7.
Spec 9: Print the number if it is not a multiple of 5 or 7.
New Extra Specs:
Spec 2: Print ”fizzbuzzwizz” if the number is a multiple of 5, 7 and 8. Spec 3: Print ”fizzwizz” if the number is a multiple of both 5 and 8. Spec 4: Print ”buzzwizz” if the number is a multiple of both 7 and 8. Spec 5: Print ”wizz” if the number is a multiple of 8.
QUESTION CONTINUES ON NEXT PAGE
Page 6 of 7
}
QUESTION CONTINUED FROM PREVIOUS PAGE
Updated implementation (comments show location of updates), inclusive of the new specifications, is given below –
void fizz(int input) {
if (input < 0) System.out.print("error");
// code for handling new specs
// ------------------------- starts here else if (((input % 8) == 0) &&
((input % 5) == 0) && ((input % 7) == 0)) System.out.print("fizzbuzzwizz");
else if ((input % 40) == 0)
System.out.print("fizzwizz"); else if ((input % 56) == 0)
System.out.print("buzzwizz"); else if ((i % 8) == 0)
System.out.print("wizz");
// ------------------------- ends here
else if (((input % 5)== 0)&&((input % 7) == 0)) System.out.print("fizzbuzz");
else if ((i % 5) == 0) System.out.print("fizz");
else if ((i % 7) == 0) System.out.print("buzz");
else
System.out.print(input);
Which testing technique would you use to test the updated implementation? Briefly justify your choice. Provide tests using this technique for the updated part of the implementation. How would you check you have enough tests to exercise the updated behaviour in the implementation?
(d) Assume we have an application that accepts inputs using the following GUI control elements,
• TextBox 1 to enter an email address that is required to be a sequence of alphanumeric characters with exactly one ‘@’, ending with ‘.com’ or ‘.edu’
• TextBox 2 to choose a password that is at least 8 characters long, with at least one alphabetic, numeric, and one special character
• TextBox 3 to confirm password which should match with the password entered in TextBox 2
i. Define partitions/value classes for the inputs. How many test specifi- cations do you get covering all combinations of the value classes for all inputs?
ii. Generate test case specifications that cover each of the different value classes at least once.
Page 7 of 7
[6 marks]
[5 marks] [5 marks]