作業 20180925-4 單元測試,結對
此作業的要求參見:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2146
結對夥伴:張俊余
測試框架:NUnit
測試內容:本周作業 20180925-6 四則運算試題生成
測試環境:Microsoft Visual Studio 2015,cmd.exe
要求1 對每個功能,先給出測試用例,然後再編碼功能。請註意把測試用例視為功能需求完成的檢驗指標。 (40分)
對於四則運算的四個大功能,由於可以使用控制臺進行交互,故無需使用TDD測試工具。對於實現功能的具體函數方法,使用TDD測試工具進行測試。具體測試用例如下:
功能1 測試用例
ID |
測試用例 |
預期結果 |
1 |
用戶輸入f4 |
出現第一個運算表達式及換行的問號 |
2 |
用戶輸入非f4 |
不出現第一個運算表達式及換行的問號,可能會因電腦系統不同而出現提示信息。例如:”xx’ 不是內部或外部命令,也不是可運行的程序或批處理文件。 |
3 |
用戶輸入f4後對於表達式做出正確答案 |
提示:“答對啦,你真是個天才!”並給出下一題及換行後的問號 |
4 |
用戶輸入f4後對於表達式做出錯誤答案 |
提示:“再想想吧,答案似乎是12喔!”並給出下一題及換行後的問號 |
5 |
用戶輸入f4後並答完20道題,其中答對X道 |
提示:“你一共答對X道題,共20道題” |
6 |
使用NUnit測試算式表達式計算結果是否正確 情況一:不含括號。 輸入:11-18+3*5 |
輸出為:8 |
功能2測試用例
功能2與功能1的主要區別在於是否含有括號,所以功能1的測試用例1-6同樣適用於功能2,在此不進行贅述。只提供區別於功能1的測試用例。
ID |
測試用例 |
預期結果 |
7 |
用戶輸入f4後,觀察給出的20道算術表達式是否含有括號 |
因為功能2在功能1的基礎上實現,故算術表達式應包括不含括號、含一個括號、含兩個括號的形式,且括號位置出現合理,即“(”在數字前,“)”在數字後,且不同時發生“(”在表達式首位與“)”在表達式末尾的情況。 |
8 |
使用NUnit測試算式表達式轉化成逆波蘭式是否正確情況一:不含括號。 輸入:2/8+1-10 |
輸出為:28/1+10- |
9 |
使用NUnit測試算式表達式轉化成逆波蘭式是否正確情況二:含一個括號。 輸入:(a+b)*c |
輸出為:ab+c* |
10 |
使用NUnit測試算式表達式轉化成逆波蘭式是否正確情況三:含兩個括號。 輸入:d+((a+b)*c) |
輸出為:dab+c*+ |
11 |
使用NUnit測試算式表達式計算結果是否正確 情況二:含一個括號。 輸入:13*(14*12-12) |
輸出為:2028 |
12 |
使用NUnit測試算式表達式計算結果是否正確 情況三:含兩個括號。 輸入:((19+6)-6)*2 |
輸出為:38 |
功能3測試樣例
功能3與上述功能1、功能2的區別在於用戶輸入命令行參事,指定出題數目。且輸出格式不一致,並最終輸出內容可以寫入文件。其中應該滿足上述測試用例6,測試用例8-12,在此不贅述。
ID |
測試用例 |
預期結果 |
13 |
使用NUnit測試是否生成了指定內容的txt文件 創建文件equation.txt,並寫入”for test” 讀取文件equation.txt,對比寫入內容與讀取內容。 |
電腦指定位置確實生成equation.txt文件,且對比結果一致。 |
14 |
用戶輸入 f4 –c -200 |
輸出:”題目數量必須是 正整數” |
15 |
用戶輸入 f4 –c 6.5 |
輸出:”題目數量必須是 正整數” |
16 |
用戶輸入 f4 –c 3 |
按照作業要求格式輸出三道不重復的題目,且保存到指定txt文件。 |
17 |
用戶再次輸入 f4 –c 3 |
按照作業要求格式輸出三道不重復的題目,且保存到指定txt文件。且此時的txt文件內容為最新的三道題。(不排除隨機表達式與測試用例15中輸出一致的可能性) |
要求2 在博客報告測試用例全部fail 到 全部pass 的過程,報告事實 (fail到修改代碼或者測試用例,到pass) 以及收獲。 除了最初的框架,測試用例中存在一次性pass沒有經過fail的,也報告一次性通過,給出如此優秀地實現了這部分功能的代碼。(40分)
功能1測試過程:
ID |
測試用例 |
預期結果 |
測試結果 |
測試過程 |
1 |
用戶輸入f4 |
出現第一個運算表達式及換行的問號 |
通過 見下圖一 |
設置好程序入口,直接運行debug版本exe。 輸入f4,出現第一個運算表達式及換行的問號 |
2 |
用戶輸入非f4 |
不出現第一個運算表達式及換行的問號,可能會因電腦系統不同而出現提示信息。例如:”xx’ 不是內部或外部命令,也不是可運行的程序或批處理文件。 |
通過 見下圖二 |
設置好程序入口,直接運行debug版本exe. 輸入f5,提示“‘f5‘不是內部或外部命令,也不是可運行的程序或批處理文件” |
3 |
用戶輸入f4後對於表達式做出正確答案 |
提示:“答對啦,你真是個天才!”並給出下一題及換行後的問號 |
通過 見下圖一 |
對於給定題目,用戶自己計算正確結果並輸入到控制臺 |
4 |
用戶輸入f4後對於表達式做出錯誤答案 |
提示:“再想想吧,答案似乎是12喔!”並給出下一題及換行後的問號 |
通過 見下圖一 |
對於給定題目,用戶自己輸出一個錯誤結果並輸入到控制臺 |
5 |
用戶輸入f4後並答完20道題,其中答對X道 |
提示:“你一共答對X道題,共20道題” |
通過 見下圖三 |
做完20道題目,控制正確數目在5道,輸出“你一共答對5道題,共20道題” |
6 |
使用NUnit測試算式表達式計算結果是否正確 情況一:不含括號。 輸入:11-18+3*5 |
輸出為:8 |
修改測試代碼後通過。 見圖四、圖五 |
寫一個測試方法TestCalculate(),調用計算表達式的方法,設置預計值與程序計算值,對比二者是否相等。 測試錯誤。 檢查發現NUnit測試是否相同 用Assert.AreEqual(),而測試工作錯誤使用了Assert.Equals(),修改後測試成功 |
測試結果截圖:
圖一:
圖二
圖三
圖四
圖五
重要代碼展示:
(1) 判斷題目計算是否正確交互
1 if (userResult == trueResult) 2 { 3 trueNum++; 4 Console.WriteLine("答對啦,你真是個天才!"); 5 } 6 else 7 { 8 Console.WriteLine("再想想吧,答案似乎是" + trueResult.ToString() + "喔!"); 9 } 10 11 Console.WriteLine("你一共答對" + trueNum.ToString() + "道題,共20道題。");
(2) 計算表達式
1 private static void CalcResult(Stack<string> resultStack, string operatorStr) 2 { 3 if (resultStack.Count >= 2) 4 { 5 decimal num2 = Convert.ToDecimal(resultStack.Pop()); 6 decimal num1 = Convert.ToDecimal(resultStack.Pop()); 7 if (operatorStr == "+") 8 { 9 resultStack.Push(Convert.ToString(num1 + num2)); 10 } 11 else if (operatorStr == "-") 12 { 13 resultStack.Push(Convert.ToString(num1 - num2)); 14 } 15 else if (operatorStr == "*") 16 { 17 resultStack.Push(Convert.ToString(num1 * num2)); 18 } 19 else if (operatorStr == "/") 20 { 21 resultStack.Push(Convert.ToString(num1 / num2)); 22 } 23 } 24 }
(3) 測試方法TestCalculate()
1 [Test]// 測試求值不含括號(在逆波蘭測試正確的基礎上) 2 public void TestCalculate() 3 { 4 Stack<string> numStack = new Stack<string>(); 5 Stack<string> rpnStack = new Stack<string>(); 6 ReversePolishEquation reversePolishEquation = new ReversePolishEquation(); 7 numStack = reversePolishEquation.getReversePolish("11-18+3*5"); 8 CalculatePolishEquation calculatePolishEquation = new CalculatePolishEquation(); 9 rpnStack = calculatePolishEquation.getRpnEquation(numStack); 10 decimal expResult = 0; 11 expResult = Convert.ToDecimal(calculatePolishEquation.CalcRPNFormula(rpnStack)); 12 decimal userResult = 8; 13 //rpnStack = calculatePolishEquation.getRpnEquation(numStack); 14 Assert.AreEqual(expResult, userResult); 15 }
功能2 測試過程
ID |
測試用例 |
預期結果 |
測試結果 |
測試過程 |
7 |
用戶輸入f4後,觀察給出的20道算術表達式是否含有括號 |
因為功能2在功能1的基礎上實現,故算術表達式應包括不含括號、含一個括號、含兩個括號的形式,且括號位置出現合理,即“(”在數字前,“)”在數字後,且不同時發生“(”在表達式首位與“)”在表達式末尾的情況。 |
通過 見下圖六 |
輸入f4後回車。觀察題目是否符合標準,檢驗得符合標準。 |
8 |
使用NUnit測試算式表達式轉化成逆波蘭式是否正確情況一:不含括號。 輸入:2/8+1-10 |
輸出為:28/1+10- |
通過 見下圖七 |
寫一個測試方法TestCreatRPN(),調用生成逆波蘭式方法, 輸入“2/8+1-10”,輸出“28/1+10-” |
9 |
使用NUnit測試算式表達式轉化成逆波蘭式是否正確情況二:含一個括號。 輸入:(a+b)*c |
輸出為:ab+c* |
通過 見下圖七 |
寫一個測試方法TestCreatRPN1(),調用生成逆波蘭式方法, 輸入“(a+b)*c”,輸出“ab+c*”
|
10 |
使用NUnit測試算式表達式轉化成逆波蘭式是否正確情況三:含兩個括號。 輸入:d+((a+b)*c) |
輸出為:dab+c*+ |
通過 見下圖七 |
寫一個測試方法TestCreatRPN2(),調用生成逆波蘭式方法, 輸入“d+((a+b)*c)”,輸出“dab+c*+*” |
11 |
使用NUnit測試算式表達式計算結果是否正確 情況二:含一個括號。 輸入:13*(14*12-12) |
輸出為:2028 |
通過 見下圖七 |
寫一個測試方法TestCalculate1(),調用計算表達式的方法,設置預計值與程序計算值,對比二者是否相等。 輸入“13*(14*12-12)” 輸出“2028” |
12 |
使用NUnit測試算式表達式計算結果是否正確 情況三:含兩個括號。 輸入:((19+6)-6)*2 |
輸出為:38 |
通過 見下圖七 |
寫一個測試方法TestCalculate2(),調用計算表達式的方法,設置預計值與程序計算值,對比二者是否相等。 輸入“((19+6)-6)*2” 輸出“38” |
測試結果截圖:
圖六
圖七
重要代碼展示:
(1) 生成含括號的表達式
1 int flag = rm.Next(1,10); 2 string equation = ""; 3 string[] nums = getRandomNum(); 4 string[] operators = getRandomOperator(); 5 if(flag % 2 == 0) 6 { 7 flag = rm.Next(1, 100); 8 }else 9 { 10 flag = 0; 11 } 12 if(flag == 0) 13 { 14 equation = nums[0] + operators[0] + nums[1] + operators[1] + nums[2] + operators[2] + nums[3] ; 15 }else 16 { 17 switch(flag % 10) 18 { 19 case 0: // (1+2+3)+4 20 equation = "(" + nums[0] + operators[0] + nums[1] + operators[1] + nums[2] + ")" + operators[2] + nums[3]; 21 break; 22 case 1: // 1+(2+3+4) 23 equation = nums[0] + operators[0] + "(" +nums[1] + operators[1] + nums[2] + operators[2] + nums[3] + ")"; 24 break; 25 case 2: // (1+2)+3+4 26 equation = "(" + nums[0] + operators[0] + nums[1] + ")" + operators[1] + nums[2] + operators[2] + nums[3] ; 27 break; 28 case 3: // 1+(2+3)+4 29 equation = nums[0] + operators[0] + "(" + nums[1] + operators[1] + nums[2] + operators[2] + nums[3] + ")" ; 30 break; 31 case 4: // 1+2+(3+4) 32 equation = nums[0] + operators[0] + nums[1] + operators[1] + "(" + nums[2] + operators[2] + nums[3] + ")" ; 33 break; 34 case 5: // (1+2)+(3+4) 35 equation = "(" + nums[0] + operators[0] + nums[1] + ")" + operators[1] + "(" + nums[2] + operators[2] + nums[3] + ")" ; 36 break; 37 case 6: // ((1+2)+3)+4 38 equation = "(" + "(" + nums[0] + operators[0] + nums[1] + ")" + operators[1] + nums[2] + ")" + operators[2] + nums[3]; 39 break; 40 case 7: // (1+(2+3))+4 41 equation = "(" + nums[0] + operators[0] + "(" +nums[1] + operators[1] + nums[2] + ")" + ")" +operators[2] + nums[3] ; 42 break; 43 case 8: // 1+((2+3)+4) 44 equation = nums[0] + operators[0] + "(" + "(" + nums[1] + operators[1] + nums[2] + ")" + operators[2] + nums[3] + ")"; 45 break; 46 case 9: // 1+(2+(3+4)) 47 equation = nums[0] + operators[0] + "(" + nums[1] + operators[1] + "(" + nums[2] + operators[2] + nums[3] + ")" + ")"; 48 break; 49 default: 50 Console.WriteLine("Error"); 51 break; 52 } 53 }
(2)轉化為逆波蘭數
1 public Stack<string> getReversePolish(string equation) 2 { 3 //equation = "(1+2)*3"; 4 Stack<string> opStack = new Stack<string>(); // 定義運算符棧 5 opStack.Push("#"); 6 Stack<string> numStack = new Stack<string>(); // 定義操作數棧 7 for(int i = 0; i < equation.Length;) 8 { 9 int opNum = GetOperationLevel(equation[i].ToString()); 10 if (opNum == 0) 11 { 12 int index = GetCompleteValue(equation.Substring(i, equation.Length - i)); 13 numStack.Push(equation.Substring(i, index)); 14 i = (i + index); 15 } 16 else 17 { 18 if (equation[i] == ‘(‘) 19 { 20 opStack.Push(equation[i].ToString()); 21 } 22 else if (equation[i] == ‘)‘) 23 { 24 MoveOperator(opStack, numStack); 25 } 26 else 27 { 28 if (opStack.Peek() == "(") 29 { 30 opStack.Push(equation[i].ToString()); 31 } 32 else 33 { 34 JudgeOperator(opStack, numStack, equation[i].ToString()); 35 } 36 } 37 i++; 38 } 39 } 40 if (opStack.Count != 0) 41 { 42 while (opStack.Count != 0 && opStack.Peek() != "#") 43 { 44 numStack.Push(opStack.Pop()); 45 } 46 } 47 return numStack; 48 }
功能3測試過程
ID |
測試用例 |
預期結果 |
測試結果 |
測試過程 |
13 |
使用NUnit測試是否生成了指定內容的txt文件 創建文件equation.txt,並第一次寫入”for test1”,第二次寫入”for test2”。即執行兩次 讀取文件equation.txt,對比寫入內容與讀取內容。 |
電腦指定位置確實生成equation.txt文件,且對比結果一致。 |
通過 見圖八 圖九 |
寫一個測試方法TestOutput(),調用寫入文件的方法,讀取文件內容,對比讀入與寫入內容,發現一致。 再次執行該測試方法,更換寫入內容,對比後發現讀取內容與寫入內容一致且為最新一次的寫入內容。 |
14 |
用戶輸入 f4 –c -200 |
輸出:”題目數量必須是 正整數” |
通過 見圖十 |
輸入 f4 –c -200 後回車, 輸出”題目數量必須是 正整數” |
15 |
用戶輸入 f4 –c 6.5 |
輸出:”題目數量必須是 正整數” |
通過 見圖十一 |
輸入 f4 –c -200 後回車, 輸出”題目數量必須是 正整數” |
16 |
用戶輸入 f4 –c 21 |
按照作業要求格式輸出三道不重復的題目,且保存到指定txt文件。 |
通過 見圖十二 |
輸入 f4 –c -3 後回車, 輸出二十一道不重復的題目,且可以檢查到txt文件中確實存在給出的題目。 |
17 |
用戶再次輸入 f4 –c 21 |
按照作業要求格式輸出三道不重復的題目,且保存到指定txt文件。且此時的txt文件內容為最新的三道題。(不排除隨機表達式與測試用例15中輸出一致的可能性) |
通過 見圖十三 |
輸入 f4 –c -3 後回車, 輸出二十一道不重復的題目,且可以檢查到txt文件中確實存在給出的不同於測試用例16中生成的題目。 |
測試結果截圖:
圖八
圖九
圖十
圖十一
圖十二
圖十三
重要代碼展示:
(1)命令行參數判斷
1 else if(args.Length == 2) 2 { 3 string num = args[1]; 4 //Console.WriteLine(num); 5 if(isNumeric(num)) 6 { 7 int equationNums = Convert.ToInt32(num); 8 // Console.WriteLine("success"); 9 ProduceEquation produceEquation = new ProduceEquation(); 10 produceEquation.produceEquations(equationNums); 11 } 12 else 13 { 14 Console.WriteLine("題目數量必須是 正整數。"); 15 } 16 }
(2)寫入文件
1 public void produceFiles(string filename,List<string> equations) 2 { 3 StreamWriter streamWriter = new StreamWriter(filename, false, Encoding.Default); 4 for(int i = 0; i < equations.Count;i++) 5 { 6 streamWriter.WriteLine(equations[i]); 7 } 8 streamWriter.Flush(); 9 streamWriter.Close(); 10 }
(3)測試方法對比寫入文件內容與讀取文件是否一致
1 [Test]// 測試是否生成txt文件以及文件內容是否與寫入一致 2 public void TestOutput() 3 { 4 ProduceFiles produceFiles = new ProduceFiles(); 5 List<string> equations = new List<string>(); 6 string str = "for test2"; 7 equations.Add(str); 8 produceFiles.produceFiles("D:/equations.txt", equations); // 寫入 9 10 StreamReader sr = new StreamReader("D:/equations.txt"); // 讀取 11 string line; 12 string exp = ""; 13 while ((line = sr.ReadLine()) != null) 14 { 15 exp = line; 16 } 17 Assert.AreEqual(str, exp); // 對比 18 }
要求3 做好準備,在接下的一周你可能無法通過別人的測試用例。 (0分)
要求4 使用coding.net做版本控制。checkin 前要求清理 臨時文件、可執行程序,通常執行 build-clean可以達到效果。(5分)
作業 20180925-4 單元測試,結對