github地址:https://github.com/szc1506/WChtml
一.PSP表格java
PSP2.1git |
PSP階段程序員 |
預估耗時github (分鐘)數組 |
實際耗時intellij-idea (分鐘)app |
Planningide |
計劃函數 |
15 | 25 |
· Estimate |
· 估計這個任務須要多少時間 |
30 | 30 |
Development |
開發 |
280 | 350 |
· Analysis |
· 需求分析 (包括學習新技術) |
100 | 120 |
· Design Spec |
· 生成設計文檔 |
50 | 60 |
· Design Review |
· 設計複審 (和同事審覈設計文檔) |
30 | 20 |
· Coding Standard |
· 代碼規範 (爲目前的開發制定合適的規範) |
20 | 30 |
· Design |
· 具體設計 |
110 | 80 |
· Coding |
· 具體編碼 |
300 | 450 |
· Code Review |
· 代碼複審 |
60 | 60 |
· Test |
· 測試(自我測試,修改代碼,提交修改) |
200 | 180 |
Reporting |
報告 |
150 | 220 |
· Test Report |
· 測試報告 |
120 | 150 |
· Size Measurement |
· 計算工做量 |
30 | 25 |
· Postmortem & Process Improvement Plan |
· 過後總結, 並提出過程改進計劃 |
60 | 45 |
合計 |
1555 | 1845 |
二.需求說明
WordCount的需求能夠歸納爲:對程序設計語言源文件統計字符數、單詞數、行數,統計結果以指定格式輸出到默認文件中,以及其餘擴展功能,並可以快速地處理多個文件。
wc.exe -c file.c //返回文件 file.c 的字符數
wc.exe -w file.c //返回文件 file.c 的單詞總數
wc.exe -l file.c //返回文件 file.c 的總行數
wc.exe -o outputFile.txt //將結果輸出到指定文件outputFile.txt
wc.exe -s //遞歸處理目錄下符合條件的文件
wc.exe -a file.c //返回更復雜的數據(代碼行 / 空行 / 註釋行)
wc.exe -e stopList.txt // 停用詞表,統計文件單詞總數時,不統計該表中的單
三.程序實現過程
第一次拿到題目時限定語言是java,由於自己對java不是很熟悉,就花了較多的時間在熟悉java和配環境上。參考連接:http://www.runoob.com/java/java-environment-setup.html。題目描述要求統計文件中的字符數,先讀入文件,而後字符數,單詞數,行數這三個能夠一塊兒統計,由於能夠一次讀一行。擴展功能中的各類代碼行,註釋行能夠用正則式來匹配,遞歸處理文件夾下文件能夠寫一個遞歸函數,停用詞表能夠先讀出全部停用詞,放到數組裏,而後匹配全部單詞,匹配則不用加一。找資料的過程大概就是JAVA的各類使用方法,文末已經給出連接。
四.代碼說明
1.字符計數:每讀入一個字符,判斷是否是回車換行符,不是則字符計數器加一
package java86; import java.io.*; import java.util.*; public class Javatest { public static int countC(String fn) {//統計字符數 BufferedReader reader = null; int res = 0; try { reader = new BufferedReader(new FileReader(fn)); String str = null; while ((str = reader.readLine()) != null) { res += str.length(); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } return res; }
2.單詞統計:按字符流讀取文件,對每個字符作判斷,若是不是換行符或空格則繼續往下讀取;當讀取到換行符或者空格是,將前面讀到的字符拼做一個單詞,單詞計數加一
public static int countW(String fn, List<String> list) {//統計單詞數目 BufferedReader reader = null; int res = 0; try { reader = new BufferedReader(new FileReader(fn)); String str = null; while ((str = reader.readLine()) != null) { String[] temp = str.split(" |,"); for (String s : temp) { if (s != null && !list.contains(s)) { ++res; } } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } return res; }
3.行數讀取調用java API,統計計數
public static int countL(String fn) {//統計行數 BufferedReader reader = null; int res = 0; try { reader = new BufferedReader(new FileReader(fn)); String str = null; while ((str = reader.readLine()) != null) { ++res; } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } return res; }
4.擴展功能
遞歸獲取文件:獲取文件目錄,判斷是否是目錄,若是是目錄則遞歸獲取該目錄下的內容;若是符合要求的文件,則先將文件名存儲,與以後的執行一同進行
代碼行,註釋行,空行的統計。
對於單詞數、字符數、行數的統計:
package text1; import java.io.*; import java.util.ArrayList; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.regex.Pattern; public class extendedFun { //遞歸處理該目錄下的同類型文件 static void allfile(String[] list){ int lenth=list.length; String myfile=null; myfile=list[lenth-1]; if(lenth==8) myfile=list[3]; File directory = new File("");//參數爲空 String courseFile; try { courseFile = directory.getCanonicalPath();//獲取當前目錄路徑 // 得到指定文件對象 File file = new File(courseFile); // 得到該文件夾內的全部文件 File[] array = file.listFiles(); File afile=new File(myfile); String fileName=afile.getName(); String fileTyle=fileName.substring(fileName.lastIndexOf("."),fileName.length()); //獲取文件類型 for(int i=0;i<array.length;i++) { if(array[i].isFile())//若是是文件 { if(array[i].getName().endsWith(fileTyle)){ if(lenth==2){ if(list[0].equals("-l")||list[0].equals("-c")||list[0].equals("-w")) basecount.count(list[0],array[i].getName()); else if(list[0].equals("-a")){ moredata(array[i].getName(),null); } } else if(lenth==3&&(list[0].equals("-l")||list[0].equals("-c")||list[0].equals("-w"))&&(list[1].equals("-l")||list[1].equals("-c")||list[1].equals("-w"))){ basecount.count(list[0],list[1],array[i].getName()); } else if(lenth==4){ basecount.count(list[0],list[1],list[2],array[i].getName()); } else if(lenth==8) { if(list[0].equals("-a")){ basecount.count(list[1], array[i].getName(),list[7]); basecount.count(list[2], array[i].getName(),list[7]); moredata(array[i].getName(),list[7]); stopcount(array[i].getName(),list[5],list[7]); } } else System.out.println("輸入格式錯誤"); } } } } catch (IOException e) { e.printStackTrace(); } } //統計代碼行/空行/註釋行 static void moredata(String myfile,String outfile)throws FileNotFoundException { if(outfile==null) outfile="result.txt"; String sfile=new String(myfile); File file=new File(sfile); // 記錄註釋行數 long annotationLine = 0; // 記錄空白行數 long blankLine = 0; // 記錄有效代碼的行數 long codeLine = 0; //假註釋 long notLine=0; if (file == null || !file.exists()) throw new FileNotFoundException(file + ",文件不存在!"); BufferedReader br = null; // 判斷此行是否爲註釋行 boolean comment = false; int whiteLines = 0; int commentLines = 0; int normalLines = 0; try { br = new BufferedReader(new FileReader(file)); String line = ""; while ((line = br.readLine()) != null) { line = line.trim(); if (line.matches("^[//s&&[^//n]]*$")||line.equals("{")||line.equals("}")) { // 空行 :本行所有是空格或格式控制字符,若是包括代碼,則只有不超過一個可顯示的字符,例如「{」 whiteLines++; } /* 本行不是代碼行,而且本行包括註釋。一個有趣的例子是有些程序員會在單字符後面加註釋: * }//註釋 */ else if (line.startsWith("/*") && !line.endsWith("*/")||((line.startsWith("{/*")||line.startsWith("}/*"))&&!line.endsWith("*/"))){ // 判斷此行爲"/*"開頭的註釋行 commentLines++; comment = true; } else if (comment == true && !line.endsWith("*/")&&!line.startsWith("*/")) { // 爲多行註釋中的一行(不是開頭和結尾) notLine++; commentLines++; } else if (comment == true && (line.endsWith("*/")||line.startsWith("*/"))) { // 爲多行註釋的結束行 commentLines++; comment = false; } else if (line.startsWith("//")|| line.startsWith("}//")||line.startsWith("{//")|| ((line.startsWith("{/*") ||line.startsWith("}/*")||line.startsWith("/*")) && line.endsWith("*/"))) { // 單行註釋行 commentLines++; } else { // 正常代碼行 //System.out.println(line); normalLines++; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); br = null; } catch (IOException e) { e.printStackTrace(); } } try{ //打開一個寫文件器,構造函數中的第二個參數true表示以追加形式寫文件 FileWriter writer = new FileWriter(outfile, true); char[] message=(myfile+",代碼行/空行/註釋行:"+(normalLines+notLine)+"/"+whiteLines+"/"+(commentLines-notLine)+"\r\n").toCharArray();//換行"\r\n"不是"\n" writer.write(message); writer.close(); } catch(IOException e){ System.out.println("File read/write Error"+e); } } } //調用停用詞表,重寫統計單詞數 static void stopcount(String thefile,String txt,String output){ int stopcount=0; int wordcount=0; File stopfile=new File(txt); File file=new File(thefile); ArrayList<String> stop=new ArrayList<String>(3); // 讀入stopfile.txt的單詞到一個動態string數組中保存 if(stopfile.exists()){ try{ FileInputStream fis=new FileInputStream(stopfile); InputStreamReader isr=new InputStreamReader(fis,"UTF-8"); BufferedReader br=new BufferedReader(isr); String line=new String(""); StringBuffer sb=new StringBuffer(); TreeMap<String, Integer> map = new TreeMap<>(); String[] split =null; while((line=br.readLine())!=null){ sb.append(line); split = line.split("\\s+"); for (int i = 0; i < split.length; i++) { // 獲取到每個單詞 Integer integer = map.get(split[i]); // 若是這個單詞在map中沒有,賦值1 if(null==integer){ map.put(split[i], 1); } } } Set<String> keySet = map.keySet(); for (String string : keySet) { stop.add(string); } br.close(); isr.close(); fis.close(); } catch(FileNotFoundException e){ e.printStackTrace(); } catch(UnsupportedEncodingException e){ e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } } //統計stop表的總數目 if(file.exists()){ try{ FileInputStream fis=new FileInputStream(file); InputStreamReader isr=new InputStreamReader(fis,"UTF-8"); BufferedReader br=new BufferedReader(isr); String line=new String(""); StringBuffer sb=new StringBuffer(); TreeMap<String, Integer> map = new TreeMap<>(); while((line=br.readLine())!=null){ String[] split = line.split("\\s++|\\.|,|\\;|\\(|\\)|\\[|\\]|\\<|\\>|\\=|\\-|\\+|\\*|\\/|\\{|\\}"); //去除多個空格\\s+ for (int i = 0; i < split.length; i++) { // 獲取到每個單詞 Integer integer = map.get(split[i]); // 若是這個單詞在map中沒有,賦值1 if(null==integer){ map.put(split[i], 1); }else{ // 若是有,在原來的個數上加上一 map.put(split[i], ++integer); } } } // 遍歷,根據key獲取所對應的value Set<String> keySet = map.keySet(); for (String string : keySet) { int i=0; if(!(string.equals(""))){ wordcount+=map.get(string); while(i<stop.size()){ if(string.equalsIgnoreCase(stop.get(i++)))//不區分大小寫判斷 { stopcount+=map.get(string); //System.out.println(string+":"+map.get(string)); }} } } //System.out.println(wordcount+" "+stopcount+" "+(wordcount-stopcount)); sb.append(line); br.close(); isr.close(); fis.close(); } catch(FileNotFoundException e){ e.printStackTrace(); } catch(UnsupportedEncodingException e){ e.printStackTrace(); } catch(IOException e){ e.printStackTrace(); } } try{ //打開一個寫文件器,構造函數中的第二個參數true表示以追加形式寫文件 if(output==null) output="output.txt"; FileWriter writer = new FileWriter(output, true); char[] message=(thefile+", 單詞數(停用後):"+(wordcount-stopcount)+"\r\n").toCharArray();//換行"\r\n"不是"\n" writer.write(message); writer.close(); } catch(IOException e){ e.printStackTrace(); } } }
五.測試過程
測試過程對於每一項功能單獨測試,再進行組合測試,確保覆蓋了全部可執行的代碼,對文件名輸入文件和文件夾也做出了測試,總共設計10個測試用例:
(1)wc.exe -l ../test/test.c -o out1.txt (2)wc.exe -w ../test/test.c -o out2.txt
(3)wc.exe -a ../test/test.c -o out3.txt (4)wc.exe -c ../test/test.c -o out4.txt
(5)wc.exe -l -w -a -c ../test/test.c -o out5.txt (6)wc.exe -a ../test/ -o out6.txt
(7)wc.exe -a -s ../test/ -o out7.txt (8)wc.exe -a ../test/*.c -o out8.txt
(9)wc.exe -a ../test/*.c -e ../stop.txt -o out9.txt (10)wc.exe -l -w -a -c -s ../test/ -e ../stop.txt -o out10.tx
六.總結
軟件測試工做是一個系統而複雜的工程,軟件測試的目的就是確保軟件的質量、確認軟件以正確的方式作了你所指望的事情,因此工做的主要任務是發現軟件的錯誤、有效定義和實現軟件成分由底層到高層的組裝過程、驗證軟件是否知足規格書要求和系統定義文檔所規定的技術要求、爲軟件質量模型的創建提供依據。
並且軟件的測試不只是要確保軟件的質量,還要給開發人員提供信息,以方便其爲風險評估作相應的準備,以及爲其提供分析依據,重要的是要貫穿在整個軟件開發的過程當中,保證整個 軟件開發的過程是高質量的。 軟件測試對測試工程師來說,要求具有較強的專業知識,嚴謹細心耐心的測試態度,良好的反向思惟、發散思惟能力、溝通能力等等。
部分代碼參考1504班成建偉
六.參考連接
1. http://www.cnblogs.com/winterfells/p/7965596.html
2. http://www.runoob.com/java/java-environment-setup.html
4. http://blog.csdn.net/daxiang_zhang/article/details/2149896
5. http://blog.csdn.net/hpchenqi_16/article/details/48504111