基於C#的單元測試(VS2015)

此次來聯繫怎麼用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

  • 給出咱們指望的結果 expected
  • 執行需測試代碼,返回結果 actual
  • 比較 actual 和 expected

下面以 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#單元測試。接下來,只須要對測試代碼進行修改,測試跟多的樣例,來對代碼進行測試。

相關文章
相關標籤/搜索