此次來聯繫怎麼用VS2015來進行C#代碼的單元測試管理,首先,正好上次寫了一個C#的WordCount程序,就用它來進行單元測試聯繫吧。html
首先,根據VS2015的提示,僅支持在共有類或共有方法中支持建立單元測試。因此,若是咱們要測試私有或是保護的類和方法,是要先將他們暫時設定成公有類型。數組
在VS2015中建立單元測試很是簡單,只要在咱們想測試的地方點擊右鍵,就會出現 「建立單元測試」 選項。函數
若是發現菜單沒有顯示,能夠參照這篇博客進行設置。http://www.bubuko.com/infodetail-1370830.html單元測試
單擊 「建立單元測試」 後,會出項以下對話框。不用修改,保持默認選項就能夠。學習
點擊「肯定」,耐心等待一會。測試
建立完成後,會出項一個名爲 「WCTests」 的文件,文件初始代碼爲this
1 using Microsoft.VisualStudio.TestTools.UnitTesting; 2 using wc; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace wc.Tests 10 { 11 [TestClass()] 12 public class WCTests 13 { 14 [TestMethod()] 15 public void WCTest() 16 { 17 Assert.Fail(); 18 } 19 20 [TestMethod()] 21 public void OperatorTest() 22 { 23 Assert.Fail(); 24 } 25 } 26 }
在進行單元測試時,主要使用的是 Assert 類,他的用發有不少,詳細用法能夠參照 https://msdn.microsoft.com/zh-cn/library/microsoft.visualstudio.testtools.unittesting.assert.aspxspa
下面給出咱們要進行測試的代碼,爲了方便測試,咱們對其中代碼輸出的部分進行了修改,將原先控制檯輸出的部分改爲了函數返回。code
1 public class WC 2 { 3 private string sFilename; // 文件名 4 private string[] sParameter; // 參數數組 5 private int iCharcount; // 字符數 6 private int iWordcount; // 單詞數 7 private int iLinecount; // 行 數 8 private int iNullLinecount; // 空行數 9 private int iCodeLinecount; // 代碼行數 10 private int iNoteLinecount; // 註釋行數 11 12 // 初始化 13 public WC() 14 { 15 this.iCharcount = 0; 16 this.iWordcount = 0; 17 this.iLinecount = 0; 18 this.iNullLinecount = 0; 19 this.iCodeLinecount = 0; 20 this.iNoteLinecount = 0; 21 } 22 // 控制信息 23 public string Operator(string[] sParameter, string sFilename) 24 { 25 this.sParameter = sParameter; 26 this.sFilename = sFilename; 27 28 string retrun_str = ""; 29 30 foreach (string s in sParameter) 31 { 32 if(s == "-x") 33 { 34 string resultFile = ""; 35 OpenFileDialog fd = new OpenFileDialog(); 36 fd.InitialDirectory = "D:\\Patch"; 37 fd.Filter = "All files (*.*)|*.*|txt files (*.txt)|*.txt"; 38 fd.FilterIndex = 2; 39 fd.RestoreDirectory = true; 40 if (fd.ShowDialog() == DialogResult.OK) 41 { 42 resultFile = fd.FileName; 43 //Console.WriteLine("文件名:{0}", resultFile); 44 SuperCount(resultFile); 45 BaseCount(resultFile); 46 retrun_str = DisplayAll(); 47 } 48 break; 49 } 50 // 遍歷文件 51 else if (s == "-s") 52 { 53 try 54 { 55 string[] arrPaths = sFilename.Split('\\'); 56 int pathsLength = arrPaths.Length; 57 string path = ""; 58 59 // 獲取輸入路徑 60 for (int i = 0; i < pathsLength - 1; i++) 61 { 62 arrPaths[i] = arrPaths[i] + '\\'; 63 64 path += arrPaths[i]; 65 } 66 67 // 獲取通配符 68 string filename = arrPaths[pathsLength - 1]; 69 70 // 獲取符合條件的文件名 71 string[] files = Directory.GetFiles(path, filename); 72 73 foreach (string file in files) 74 { 75 //Console.WriteLine("文件名:{0}", file); 76 SuperCount(file); 77 BaseCount(file); 78 retrun_str = Display(); 79 } 80 break; 81 } 82 catch (IOException ex) 83 { 84 //Console.WriteLine(ex.Message); 85 return ""; 86 } 87 } 88 // 高級選項 89 else if (s == "-a") 90 { 91 //Console.WriteLine("文件名:{0}", sFilename); 92 SuperCount(sFilename); 93 BaseCount(sFilename); 94 retrun_str = Display(); 95 break; 96 } 97 // 基本功能 98 else if (s == "-c" || s == "-w" || s == "-l") 99 { 100 //Console.WriteLine("文件名:{0}", sFilename); 101 BaseCount(sFilename); 102 retrun_str = Display(); 103 break; 104 } 105 else 106 { 107 //Console.WriteLine("參數 {0} 不存在", s); 108 break; 109 } 110 } 111 Console.WriteLine("{0}", retrun_str); 112 return retrun_str; 113 } 114 115 // 統計基本信息:字符數 單詞數 行數 116 private void BaseCount(string filename) 117 { 118 try 119 { 120 // 打開文件 121 FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 122 StreamReader sr = new StreamReader(file); 123 int nChar; 124 int charcount = 0; 125 int wordcount = 0; 126 int linecount = 0; 127 //定義一個字符數組 128 char[] symbol = { ' ', ',', '.', '?', '!', ':', ';', '\'', '\"', '\t', '{', '}', '(', ')', '+' ,'-', 129 '*', '='}; 130 while ((nChar = sr.Read()) != -1) 131 { 132 charcount++; // 統計字符數 133 134 foreach (char c in symbol) 135 { 136 if(nChar == (int)c) 137 { 138 wordcount++; // 統計單詞數 139 } 140 } 141 if (nChar == '\n') 142 { 143 linecount++; // 統計行數 144 } 145 } 146 iCharcount = charcount; 147 iWordcount = wordcount + 1; 148 iLinecount = linecount + 1; 149 sr.Close(); 150 } 151 catch (IOException ex) 152 { 153 Console.WriteLine(ex.Message); 154 return; 155 } 156 } 157 158 // 統計高級信息:空行數 代碼行數 註釋行數 159 private void SuperCount(string filename) 160 { 161 try 162 { 163 // 打開文件 164 FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read); 165 StreamReader sr = new StreamReader(file); 166 String line; 167 int nulllinecount = 0; 168 int codelinecount = 0; 169 int notelinecount = 0; 170 while ((line = sr.ReadLine()) != null) 171 { 172 line = line.Trim(' '); 173 line = line.Trim('\t'); 174 // 空行 175 if (line == "" || line.Length <= 1) 176 { 177 nulllinecount++; 178 } 179 // 註釋行 180 else if(line.Substring(0, 2) == "//" || line.Substring(1, 2) == "//") 181 { 182 notelinecount++; 183 } 184 // 代碼行 185 else 186 { 187 codelinecount++; 188 } 189 } 190 iNullLinecount = nulllinecount; 191 iCodeLinecount = codelinecount; 192 iNoteLinecount = notelinecount; 193 sr.Close(); 194 } 195 catch (IOException ex) 196 { 197 Console.WriteLine(ex.Message); 198 return; 199 } 200 } 201 // 打印信息 202 private string Display() 203 { 204 string return_str = ""; 205 206 foreach (string s in sParameter) 207 { 208 if (s == "-c") 209 { 210 //Console.WriteLine("字 符 數:{0}", iCharcount); 211 return_str += "字符數:"+iCharcount.ToString(); 212 } 213 else if (s == "-w") 214 { 215 //Console.WriteLine("單 詞 數:{0}", iWordcount); 216 return_str += "單詞數:" + iWordcount.ToString(); 217 } 218 else if (s == "-l") 219 { 220 //Console.WriteLine("總 行 數:{0}", iLinecount); 221 return_str += "總行數:" + iLinecount.ToString(); 222 } 223 else if(s == "-a") 224 { 225 //Console.WriteLine("空 行 數:{0}", iNullLinecount); 226 //Console.WriteLine("代碼行數:{0}", iCodeLinecount); 227 //Console.WriteLine("註釋行數:{0}", iNoteLinecount); 228 return_str += "空行數:" + iNullLinecount.ToString(); 229 return_str += "代碼行數:" + iCodeLinecount.ToString(); 230 return_str += "註釋行數:" + iNoteLinecount.ToString(); 231 } 232 } 233 //Console.WriteLine(); 234 return return_str; 235 } 236 private string DisplayAll() 237 { 238 string return_str = ""; 239 foreach (string s in sParameter) 240 { 241 //Console.WriteLine("字 符 數:{0}", iCharcount); 242 //Console.WriteLine("單 詞 數:{0}", iWordcount); 243 //Console.WriteLine("總 行 數:{0}", iLinecount); 244 //Console.WriteLine("空 行 數:{0}", iNullLinecount); 245 //Console.WriteLine("代碼行數:{0}", iCodeLinecount); 246 //Console.WriteLine("註釋行數:{0}", iNoteLinecount); 247 return_str += "字符數:" + iCharcount.ToString(); 248 return_str += "單詞數:" + iWordcount.ToString(); 249 return_str += "總行數:" + iLinecount.ToString(); 250 return_str += "空行數:" + iNullLinecount.ToString(); 251 return_str += "代碼行數:" + iCodeLinecount.ToString(); 252 return_str += "註釋行數:" + iNoteLinecount.ToString(); 253 } 254 //Console.WriteLine(); 255 return return_str; 256 } 257 }
接下來,咱們對測試代碼進行修改,在咱們進行單元測試時,某種程度上就是將咱們人工給出的程序運行結果與程序實際輸出結果進行比較,因此單元測試的過程通常分爲 3 步:htm
下面以 WC 程序執行 -c 參數對 123.txt 文件進行統計的功能爲例進行測試,咱們將測試代碼修改以下,其中 AreEqual 方法用於對指望值與實際值進行比較。
1 using Microsoft.VisualStudio.TestTools.UnitTesting; 2 using wc; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 9 namespace wc.Tests 10 { 11 [TestClass()] 12 public class WCTests 13 { 14 [TestMethod()] 15 public void WCTest() 16 { 17 // arrange 18 string expected = "字符數:138"; 19 WC testwc = new WC(); 20 21 // act 22 string[] opar = new string[1]; 23 opar[0] = "-c"; 24 25 string actual = testwc.Operator(opar, @"D:\學習\個人工程\軟件工程\wc\wc\wc\123.txt"); 26 27 // assert 28 Assert.AreEqual(expected, actual); 29 } 30 } 31 }
"123.txt" 文件爲
咱們預期的測試結果是此文件有138個字符,因此會輸出 「字符數:138」 ;咱們來看看測試的結果,點擊右鍵,選擇 「運行測試」 ,選項測試經過了。
咱們如今給出一個錯誤的預期來看看結果會如何,咱們如今認爲 "123.txt" 文件有50個字符。
系統會提示出錯,而且給出實際值與指望值分別是多少。至此,咱們已經完成了簡單的C#單元測試。接下來,只須要對測試代碼進行修改,測試跟多的樣例,來對代碼進行測試。