Four Operations-Unit Testing
Li Zhiqiang 201421123028 Lian Yonggang 201421123014 Lin Dialect 201421123023
Coding address: https://git.coding.net/lizhiqiang 0x01/sizeyunsuan-TestExample.git
I. Topic Requirements
1. Unit test code to test whether addition works correctly.
2. Through unit test code, the function of addition, subtraction, multiplication and division is tested.
3. Through unit test code, test the support of calculation class for various parameters.
a. The input is incorrect, such as "1 + 2".
b. In the numerical range of - 1000.. 1000, pass in "10000 + 32768".
What about c. or "248/0"?
d. How to tell the caller of the function that you are wrong? Define the returned string as "-1"?
e. What if the real calculation result is "-1"?
4. Improving the procedure by incremental modification to deal with all kinds of errors.
2. Experimental steps
a. Demand Analysis
Through the unit test code, test whether the add, subtract, multiply and divide function of the program works correctly, and whether the format error, numerical overflow and divide zero anomaly can be detected.
b. Design test framework and simulate test data
- Test add-subtract multiply-divide function
TEST_METHOD(TestAdd) //Test addition { Test.CheckInput("1/2+4"); Assert::AreEqual(test11,Test.add()); } TEST_METHOD(TestAdd1) { Test.CheckInput("3+1/3"); Assert::AreEqual(test12, Test.add()); } TEST_METHOD(TestAdd2) { Test.CheckInput("2+4"); Assert::AreEqual(test13, Test.add()); } TEST_METHOD(TestAdd3) { Test.CheckInput("1/2+1/4"); Assert::AreEqual(test14, Test.add()); } TEST_METHOD(TestSub) //Test subtraction { Test.CheckInput("1/2-1/3"); Assert::AreEqual(test21, Test.sub()); } TEST_METHOD(TestSub1) { Test.CheckInput("1/3-2"); Assert::AreEqual(test22, Test.sub()); } TEST_METHOD(TestSub2) { Test.CheckInput("2-1/3"); Assert::AreEqual(test23, Test.sub()); } TEST_METHOD(TestSub3) { Test.CheckInput("5-3"); Assert::AreEqual(test24, Test.sub()); } TEST_METHOD(TestMul) //Test multiplication { Test.CheckInput("1×2"); Assert::AreEqual(test31, Test.mul()); } TEST_METHOD(TestMul1) { Test.CheckInput("1/2×2"); Assert::AreEqual(test32, Test.mul()); } TEST_METHOD(TestMul2) { Test.CheckInput("2×1/3"); Assert::AreEqual(test33, Test.mul()); } TEST_METHOD(TestMul3) { Test.CheckInput("1/3×1/2"); Assert::AreEqual(test34, Test.mul()); } TEST_METHOD(TestDiv) //Test Division { Test.CheckInput("1/2÷2"); Assert::AreEqual(test41, Test.div()); } TEST_METHOD(TestDiv1) { Test.CheckInput("4÷1/2"); Assert::AreEqual(test42, Test.div()); } TEST_METHOD(TestDiv2) { Test.CheckInput("1/2÷2/3"); Assert::AreEqual(test43, Test.div()); } TEST_METHOD(TestDiv3) { Test.CheckInput("1÷2"); Assert::AreEqual(test44, Test.div()); }
- Test Format Error, Value Overflow, Zero-dividing Abnormal Function
TEST_METHOD(TestCheckFormat1) //Test Format Error { Test.CheckInput("2--2"); Assert::AreEqual(test5, Test.g_szErrIn); } TEST_METHOD(TestCheckFormat2) { Test.CheckInput("2+÷2"); Assert::AreEqual(test5, Test.g_szErrIn); } TEST_METHOD(TestCheckFormat3) { Test.CheckInput("2+×2"); Assert::AreEqual(test5, Test.g_szErrIn); } TEST_METHOD(TestCheckFormat4) { Test.CheckInput("2+×"); Assert::AreEqual(test5, Test.g_szErrIn); } TEST_METHOD(TestCheckFormat5) { Test.CheckInput("2+/2"); Assert::AreEqual(test5, Test.g_szErrIn); } TEST_METHOD(TestCheckNum61) //Test illegal values { Test.CheckInput("1÷0"); Test.div(); Assert::AreEqual(test6, Test.g_szErrNum); } TEST_METHOD(TestCheckNum62) { Test.CheckInput("1/0"); Test.div(); Assert::AreEqual(test6, Test.g_szErrNum); } TEST_METHOD(TestCheckNum63) { Test.CheckInput("1/2+2/0"); Test.add(); Assert::AreEqual(test6, Test.g_szErrNum); } TEST_METHOD(TestCheckBey71) //Value spillover during testing { Test.CheckInput("-2000+2"); Test.add(); Assert::AreEqual(test7, Test.g_szErrBey); } TEST_METHOD(TestCheckBey72) { Test.CheckInput("-2000"); Test.add(); Assert::AreEqual(test7, Test.g_szErrBey); } TEST_METHOD(TestCheckBey73) { Test.CheckInput("-200+2/3000"); Test.add(); Assert::AreEqual(test7, Test.g_szErrBey); }
- Unit Test Addition Function
string Calc::add() { size_t iPos = g_szInput.find('+'); g_szX = g_szInput.substr(0, iPos); g_szY = g_szInput.substr(iPos+1, g_szInput.length()-1-iPos); size_t iPosInX = g_szX.find('/'); g_iFirNer = stoi(g_szX.substr(0, iPosInX)); if (iPosInX == -1) { g_iFirDer = 1; } else { g_iFirDer = stoi(g_szX.substr(iPosInX+1, g_szInput.length() - 1 - iPosInX)); } size_t iPosInY = g_szY.find('/'); g_iSecNer = stoi(g_szY.substr(0, iPosInY)); if (iPosInY == -1) { g_iSecDer = 1; } else { g_iSecDer = stoi(g_szY.substr(iPosInY+1, g_szInput.length() - 1 - iPosInY)); } simplify(g_iFirNer, g_iFirDer, g_iSecNer, g_iSecDer); g_iRusNer = g_iFirNer*g_iSecDer + g_iFirDer*g_iSecNer; g_iRusDer = g_iFirDer*g_iSecDer; init(g_iRusNer, g_iRusDer); //Approximate to the true fraction g_szRusDer = ""; g_szRusNer = ""; if (g_iRusDer == 1) { g_szRusNer += to_string(g_iRusNer); return g_szRusNer; } else{ g_szRusDer += to_string(g_iRusDer); g_szRusNer += to_string(g_iRusNer); return g_szRusNer + "/" + g_szRusDer; }
}
c. Test results
3. PSP
PSP2.1 | Personal Software Process Stages | Estimated time(h) | actual time(h) |
Planning | plan | 1 | 1.5 |
· Estimate | Estimate how long this task will take | 10 | 15 |
Development | Development | 8 | 10 |
· Analysis | Needs analysis (including learning new technologies) | 0.5 | 1 |
· Design Spec | Generating Design Documents | 2 | 2 |
· Design Review | design review | 0.3 | 0.5 |
· Coding Standard | Code specification | 0.5 | 0.4 |
· Design | Specific design | 1.5 | 1.3 |
· Coding | Specific coding | 8 | 7 |
· Code Review | Code Review | 0.5 | 1 |
· Test | Testing (self-testing, code modification, submission of modifications) | 0.2 | 0.5 |
Reporting | Presentation | 2 | 2 |
· | Test Report | 0.5 | 0.5 |
· | Calculating workload | 0.5 | 1 |
· | Propose process improvement plan | 2 |
4 |
Summary
First, a piece of bread: Teammates'previous assignments were written in c++, using c++ unit tests.
Put the meat on: First, we divide the functional modules and test the corresponding modules in groups to achieve the purpose of unit testing. In the process of dividing, we solved the criticism of variable chaos. In this unit testing, we made great improvements in the code specification. We use the Hungarian naming method to name variables, such as g_iFirNer, g_iFirDer, g_szRusDer, etc. Under the structure of attribute + type + description, it is easy to understand the meaning of this variable, which obviously accelerates the team's speed in the process of alternating code writing. In the subsequent programming path, we will Pay more attention to code specification.
Then a piece of bread: After this unit test, we have a deeper understanding of software engineering. It took many processes to gradually improve the original release of a software, and need tacit teamwork.