Presentation is loading. Please wait.

Presentation is loading. Please wait.

Testing and Debugging Hakam Alomari

Similar presentations


Presentation on theme: "Testing and Debugging Hakam Alomari"— Presentation transcript:

1 Testing and Debugging Hakam Alomari halomari@cs.kent.edu

2 Outline Include Guards Namespace name access Testing Concepts – What is software testing? – How to find faults? – Black Box vs. Glass Box testing – How many tests cases are there? – Regression testing Using assert and cerr Building test cases, Makefile

3 Include Guards Are used to prevent the contents of a file from being included more than once – Example: (string.h) #ifndef CS2_STRING_H #define CS2_STRING_H Class string { //… }; #endif

4 Example [wiki] File "grandfather.h“ struct foo { int member; }; File "father.h“ #include "grandfather.h" File "child.c“ #include "grandfather.h" #include "father.h"

5 Use of #include guards File "grandfather.h“ #ifndef GRANDFATHER_H #define GRANDFATHER_H struct foo { int member; }; #endif File "father.h“ #include "grandfather.h" File "child.c“ #include "grandfather.h" #include "father.h"

6 Namespaces Used to group entities (e.g., objects) under a name, such as each group has its own name Example: namespace foo1 { int var = 1; } namespace foo2 { int var = 2; } int main () { std::cout<< foo1::var <<“\n”; // output 1 std::cout<< foo2::var <<“\n”; // output 2 return 0; }

7 Standard Includes Names defined by standard includes (e.g., cout) can be used as: – Prefix the name with std:: – Use using std::name before the name is used – Put using namespace::std before the name is used – Example: int main() { std::cout << "Hello World!\n"; //... int main() { using std::cout; cout << "Hello World!\n"; //... using namespace std; int main() { cout << "Hello World!\n"; //...

8 Software Testing Software testing is used to find errors error: – Incorrect output for a given input – Caused by faults inside the program – A fault is represent the incorrect part of the code E.g., incorrect stopping condition So, test cases should be developed to exercise the program and uncovering errors

9 Testing levels Start by testing each method (unit tests) Then each class in full (module tests) Then the whole program (system tests) The test case that has a high probability to uncover an error is known to be the best one

10 Testing Types Black box vs Glass box (white box) – Black box Uses only the I/O spec. to develop test cases – Glass box Uses only the implementation details to develop test cases Both types are necessary to develop a good set of test cases

11 Number of Test Cases Functions usually have a very large number of pre. and post. conditions So, there is no need to test all of these to make sure our function behaves correctly How? – Pairing down test cases, by: – Develop equivalence classes of test cases – Examine the boundaries of these classes carefully

12 Equivalence Classes The input and output often fall into equivalence partitions where the system behaves in an equivalent way for each class Then, the test cases should be developed to test each partition

13 Classes Boundaries Example: – Partition system inputs and outputs into equivalence classes – If input is a 2 digit integer between 10 and 99 then the equivalence partitions are 99 (invalid) – Choose test cases at the boundary of these partitions – 09, 10, 99, 100

14 Building Test Cases 1.Determine the I/O spec. for the method 2.Develop test cases 3.Method implementation 4.Run the method against the test cases from 2 5.Debugging (fix) 6.Go to 4

15 Test Steps There are three steps in a test: – Set-up the "fixture", the system to be tested – Perform the test – Verify the results, make sure there are no unwanted side effects Example: Test for existence of const char& operator[](int) const – // Setup fixture const string str("abc"); – // Test assert(str[0] == 'a'); assert(str[1] == 'b'); assert(str[2] == 'c'); – // Verify assert(str.length() == 3);

16 Regression Testing The intent of regression testing is to ensure that a change, such as a bugfix, did not introduce new faults Each time you add a new method to your class or fix a fault run your test cases (all of them) – Adding something new or fixing a problem may have side effects Re-running your test cases will uncover these problems

17 Asserts Used to output an error message and terminate a program if a condition is false Asserts are useful for testing #include is required to use asserts Example: – assert(result == correct_result); Asserts can be turned off using – #define NDEBUG

18 Debugging Used when the program is not working properly One easy thing to do is output the value of relevant variables Use cerr instead of cout. cout is buffered Buffering means output is accumulated in a "buffer" and the accumulated output sent out to the OS together Output to cerr is not buffered, it is output immediately If a program crashes there may be output in a buffer that gets lost It is a good idea to include a message with values that are output – std::cerr << "var1 = " < < var1 << "\n";

19 The make Command The make command may be used to automate compiling The make command when executed will look for a file named makefile and then, if not found, for a file named Makefile to specify dependencies Otherwise a makefile must be specified with the - f option The make command has some rules built-in so it can do some basic compiling but usually the developer provides a makefile

20 Makefile Rules Rules have the form: – target: dependency_list – TAB command TargetA file or name dependency_listFiles that the target "depends on" TABThe TAB character. REQUIRED! CommandTypically a compiling/linking command but can be any command. There may be more than one TAB/command line If the modification time of any dependency is more recent than the target the command lines are executed

21 Common Rule Types Creating machine language,.o, files and linking are two things that must be done # Link executable: file_1.o file_2.o g++ -Wall file_1.o file_2.o -o executable # Create.o file file.o: file.h file.cpp g++ -Wall -c file.cpp Note.cpp files are typically not targets,.cpp files do not depend on other files

22 Makefile Example # Create the executable is the first rule here # Link main: bigint.o main.o g++ -Wall bigint.o main.o -o main # Create.o file main.o: bigint.h main.cpp g++ -Wall -c main.cpp # Create.o file bigint.o: bigint.h bigint.cpp g++ -Wall -c bigint.cpp # Remove.o and executable clean: rm -f *.o rm -f main

23 References [wiki]: http://en.wikipedia.org/wiki/Include_guard http://en.wikipedia.org/wiki/Include_guard Computer Science II Lab: http://classes.cs.kent.edu/courses/cs33001_lab/svn/index.html http://classes.cs.kent.edu/courses/cs33001_lab/svn/index.html Software Testing for CS II slides: http://www.cs.kent.edu/~jmaletic/CS33001/ http://www.cs.kent.edu/~jmaletic/CS33001/


Download ppt "Testing and Debugging Hakam Alomari"

Similar presentations


Ads by Google