CSE306 Software Quality in Practice
- Dr. Carl Alphonce
CSE306 Software Quality in Practice Dr. Carl Alphonce - - PowerPoint PPT Presentation
CSE306 Software Quality in Practice Dr. Carl Alphonce alphonce@buffalo.edu 343 Davis Hall Recall the rules 1. Understand the requirements 2. Make it fail 3. Simplify the test case 4. Read the right error message 5. Check the plug 6.
1. Understand the requirements 2. Make it fail 3. Simplify the test case
5. Check the plug 6. Separate fact from fiction 7. Divide and conquer 8. Match the tool to the bug 9. One change at a time
t fix it, it ain’ t fixed
1. Understand the requirements 2. Make it fail 3. Simplify the test case
5. Check the plug 6. Separate fact from fiction 7. Divide and conquer 8. Match the tool to the bug 9. One change at a time
t fix it, it ain’ t fixed
1. Understand the requirements 2. Make it fail 3. Simplify the test case
5. Check the plug 6. Separate fact from fiction 7. Divide and conquer 8. Match the tool to the bug 9. One change at a time
t fix it, it ain’ t fixed
http:/ /cunit.sourceforge.net/doc/introduction.html
http:/ /cunit.sourceforge.net/doc/introduction.html
(the most common ones)
CU_ASSERT_TRUE(x) CU_ASSERT_EQUAL(x,y) CU_ASSERT_PTR_EQUAL(x,y) CU_ASSERT_PTR_NULL(x,y) CU_ASSERT_STRING_EQUAL(x,y) CU_ASSERT_DOUBLE_EQUAL(x,y,𝜁) CU_PASS(message) CU_ASSERT_FALSE(x) CU_ASSERT_NOT_EQUAL(x,y) CU_ASSERT_PTR_NOT_EQUAL(x,y) CU_ASSERT_PTR_NOT_NULL(x,y) CU_ASSERT_STRING_NOT_EQUAL(x,y) CU_ASSERT_DOUBLE_NOT_EQUAL(x,y,𝜁) CU_FAIL(message) http:/ /cunit.sourceforge.net/doc/headers/CUnit.h
Production code Test code
Test code is separate from production code, but calls production code to verify its functionality.
void test00(void) { int x = 5; int y = -3; int expected = 2; int actual = eval(x, y); CU_ASSERT_EQUAL( expected , actual ); }
A test is a void to void function. Set up inputs and an expected (correct) answer. Compute an actual answer using production code. Compare actual and expected values.
void test01(void) { runTest(1,1,2); } void test02(void) { runTest(2,1,3); } void test03(void) { runTest(0,2,2); } void test04(void) { runTest(2,0,2); } /* Runs a test with inputs that *should* pass * and produce an expected result. */ void runTest(int x, int y, int expected) { int actual = eval(x, y); CU_ASSERT_EQUAL( expected , actual ); }
Can simplify writing many tests by using a helper function, runTest.
Needed #includes: #include "CUnit.h" #include "Basic.h"
Live coding reconstruction
/* The main() function for setting up and running the tests. */ int main() { CU_pSuite SuiteValid = NULL; /* initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) { return CU_get_error(); } /* add a suite to the registry */ SuiteValid = CU_add_suite("Suite_of_tests_with_valid_inputs", NULL, NULL); if (NULL == SuiteValid) { CU_cleanup_registry(); return CU_get_error(); } /* add the tests to SuiteValid */ if ( (NULL == CU_add_test(SuiteValid, "5+(-3)=2", test00)) || (NULL == CU_add_test(SuiteValid, "1+1=2", test01)) ) { CU_cleanup_registry(); return CU_get_error(); } /* Run all tests using the CUnit Basic interface */ CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); CU_cleanup_registry(); return CU_get_error(); }
Live coding reconstruction
/* The main() function for setting up and running the tests. */ int main() { CU_pSuite SuiteValid = NULL; /* initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) { return CU_get_error(); } /* add a suite to the registry */ SuiteValid = CU_add_suite("Suite_of_tests_with_valid_inputs", NULL, NULL); if (NULL == SuiteValid) { CU_cleanup_registry(); return CU_get_error(); } /* add the tests to SuiteValid */ if ( (NULL == CU_add_test(SuiteValid, "5+(-3)=2", test00)) || (NULL == CU_add_test(SuiteValid, "1+1=2", test01)) ) { CU_cleanup_registry(); return CU_get_error(); } /* Run all tests using the CUnit Basic interface */ CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); CU_cleanup_registry(); return CU_get_error(); }
Create a test suite. In this case the suite is named SuiteValid.
Live coding reconstruction
/* The main() function for setting up and running the tests. */ int main() { CU_pSuite SuiteValid = NULL; /* initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) { return CU_get_error(); } /* add a suite to the registry */ SuiteValid = CU_add_suite("Suite_of_tests_with_valid_inputs", NULL, NULL); if (NULL == SuiteValid) { CU_cleanup_registry(); return CU_get_error(); } /* add the tests to SuiteValid */ if ( (NULL == CU_add_test(SuiteValid, "5+(-3)=2", test00)) || (NULL == CU_add_test(SuiteValid, "1+1=2", test01)) ) { CU_cleanup_registry(); return CU_get_error(); } /* Run all tests using the CUnit Basic interface */ CU_basic_set_mode(CU_BRM_VERBOSE); CU_basic_run_tests(); CU_cleanup_registry(); return CU_get_error(); }
Register each test function with the SuiteValid test suite here. If you add more test functions for this suite, add code here to register each test function.
Live coding reconstruction
/* The main() function for setting up and running the tests. */ int main() { CU_pSuite SuiteValid = NULL; /* initialize the CUnit test registry */ if (CUE_SUCCESS != CU_initialize_registry()) { return CU_get_error(); } /* add a suite to the registry */ SuiteValid = CU_add_suite("Suite_of_tests_with_valid_inputs", NULL, NULL); if (NULL == SuiteValid) { CU_cleanup_registry(); return CU_get_error(); } /* add the tests to SuiteValid */ if ( (NULL == CU_add_test(SuiteValid, "5+(-3)=2", test00)) || (NULL == CU_add_test(SuiteValid, "1+1=2", test01)) || (NULL == CU_add_test(SuiteValid, "1+2=3", test02)) || (NULL == CU_add_test(SuiteValid, "0+2=2", test03)) || (NULL == CU_add_test(SuiteValid, "2+0=2", test04)) ) { CU_cleanup_registry(); return CU_get_error(); } /* Run all tests using the CUnit Basic interface */ CU_basic_set_mode(CU_BRM_VERBOSE); }
This is what it looks like with more test functions registered.
A sequence of commits all in the master branch.
commit 1 commit 2 commit 3
master
HEAD
Create a new branch: git branch bugfix
commit 1 commit 2 commit 3
master
HEAD
bugfix
Move HEAD to new branch git checkout bugfix
commit 1 commit 2 commit 3
master
HEAD
bugfix
Make a commit on bugfix branch
commit 1 commit 2 commit 3
master
HEAD
bugfix
commit 4
Make another commit on bugfix branch
commit 1 commit 2 commit 3
master
HEAD
bugfix
commit 4 commit 5
Check out master again
commit 1 commit 2 commit 3
master
HEAD
bugfix
commit 4 commit 5
Merge bugfix into
commits were made to master in between this merge is straightforward.
commit 1 commit 2 commit 3
master
HEAD
bugfix
commit 4 commit 5