WordCount编码和测试

WordCount编码和测试

项目地址:https://github.com/handsomesnail/WordCount

PSP表格

PSP2.1PSP阶段预估耗时(分钟)实际耗时(分钟)
Planning计划2010
Estimate估计任务需要多少时间2010
Development开发150140
Analysis需求分析1010
Design Spec生成设计文档100
Design Review设计复审100
Coding Standard代码规范100
Design具体设计2020
Coding具体编码6080
Code Review代码复审1010
Test测试2020
Reporting报告6090
Test Report测试报告3060
Size Measurement计算工作量2020
Postmortem总结1010
合计230240

解题思路

将问题分解为如下模块:

  • 解析命令行参数 (将输入转化为路径以及各种操作选项如-c -w -l等)
  • I/O操作 (将路径转化为相应路径下文件的字符串内容)
  • 字符串统计 (将各种操作选项抽象为各类处理字符串的方法)

程序设计实现

Program类
  • void Main(string[] args)
    Main函数作为程序入口
  • int Entrance(string[] args)
    测试入口, 返回值为错误码,正确执行返回0
  • string Read(string fileName)
    读取相对路径下名为fileName的文件并返回字符串
  • string Read(out string fileName)
    调用win32 api选取文件并读取返回字符串,同时返回选取的文件名
  • void Write(string fileName, string content)
    在相对路径下向名为fileName的文件追加内容为content的字符串
  • void LogArgumentError(int code)
    打印错误信息
  • int CountChar(string s)
    统计并返回字符串s的字符数
  • int CountWord(string s)
    统计并返回字符串s的单词数
  • int CountWord(string s,HashSet stopList)
    根据停用词表stopList统计并返回字符串s的单词数
  • int CountLine(string s)
    统计并返回字符串s的行数
  • void CountMoreAboutLine(string s, out int codeLineCount, out int emptyLineCount, out int commentLineCount)
    统计并返回行的详细信息(代码行/空行/注释行)
OpenFileName类

初始化打开或另存为对话框的信息,系统返回关于用户的选择信息到这个结构中

LocalDialog类
  • extern bool GetOpenFileName([In, Out] OpenFileName ofn)
    链接Comdlg32.dll中打开文件的系统函数

代码说明

/// <summary>统计字符数并打印</summary>
private static int CountChar(string s) {
    return s.Length; //直接返回字符串长度
}
/// <summary>统计单词数并打印</summary>
private static int CountWord(string s) {
    return CountWord(s, new HashSet<string>());
}
/// <summary>根据停用词表统计单词数并打印</summary>
private static int CountWord(string s,HashSet<string> stopList) {
    if (s.Length == 0)
        return 0;
    int count = 1;
    int i = -1;
    StringBuilder sb = new StringBuilder();
    foreach (char c in s) {
        i++;
        if (splitCharDic.Contains(c)) {
            if (i < s.Length - 1 && !splitCharDic.Contains(s[i + 1])) {
                if (!stopList.Contains(sb.ToString())) {
                    count++;
                    //Console.WriteLine(count + ":" + sb.ToString());
                    sb.Clear();
                }
                else {
                    sb.Clear();
                }
            }
        }
        else {
            sb.Append(c);
        }
    }
    return count;
}
/// <summary>统计行数并打印</summary>
private static int CountLine(string s) {
    int count = 0;
    //遍历直接统计'\n'数量
    foreach (char c in s) {
        if (count == 0) {
            count++;
            continue;
        }
        if (c == '\n') {
            count++;
        }
    }
    return count;
}
/// <summary>统计行的详细信息</summary>
private static void CountMoreAboutLine(string s, out int codeLineCount, out int emptyLineCount, out int commentLineCount) {
    codeLineCount = 0;//代码行
    emptyLineCount = 0;//空行
    commentLineCount = 0;//注释行
    int charInALine = 0; //当前行可见字符数
    int i = -1;
    CommentLineType CommentLine = CommentLineType.NonCommentLine;
    bool cancelCommentLine = false;
    foreach (char c in s) {
        i++;
        if (c == '\n'||i==s.Length-1) {
            if (CommentLine==CommentLineType.SingleCommentLine) {
                commentLineCount++;
                CommentLine = CommentLineType.NonCommentLine;
            }
            else if ((CommentLine == CommentLineType.SeveralCommentLine|| cancelCommentLine )&& charInALine<=1) {
                commentLineCount++;
            }
            else if (charInALine > 1) {
                codeLineCount++;
            }
            else emptyLineCount++;
            if (cancelCommentLine) {
                cancelCommentLine = false;
            }
            charInALine = 0;
        }
        if (charInALine <= 1 && c == '/' && i > 0 && s[i - 1] == '/') {
            CommentLine = CommentLineType.SingleCommentLine;
        }
        else if (c == '*' && i > 0 && s[i - 1] == '/') {
            CommentLine = CommentLineType.SeveralCommentLine;
        }
        else if (c == '/' && i > 0 && s[i - 1] == '*') {
            cancelCommentLine = true;
            CommentLine = CommentLineType.NonCommentLine;
        }
        else if (CommentLine == CommentLineType.NonCommentLine && !displayedCharDic.Contains(c)) {
            charInALine++;
        }
    }
}
/// <summary>通过图形界面读取文件 </summary>
public static string Read(out string fileName) {
    OpenFileName ofn = new OpenFileName();
    ofn.structSize = Marshal.SizeOf(ofn);
    ofn.file = new string(new char[256]);
    ofn.maxFile = ofn.file.Length;
    ofn.fileTitle = new string(new char[64]);
    ofn.maxFileTitle = ofn.fileTitle.Length;
    ofn.title = "选择文件";
    ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000200 | 0x00000008;
    if (LocalDialog.GetOpenFileName(ofn)) {
        fileName = ofn.fileTitle;
        using (FileStream fs = new FileStream(ofn.file, FileMode.Open, FileAccess.Read)) {
            using (StreamReader sw = new StreamReader(fs, Encoding.UTF8)) {
                return sw.ReadToEnd();
            }
        }
    }
    throw new System.Exception("用户没有选择文件");
}

测试设计过程

  • 如何设计测试用例
    保证设计的测试用例应至少覆盖函数中所有的可执行语句
  • 哪些地方会导致程序高风险
    边界条件,未捕获的异常,未正确初始化的内存空间,空引用等等
  • 测试代码如何设计
    通过验证测试入口函数和相应分支的返回码覆盖代码的所有分支
namespace UnitTest {
    [TestClass]
    public class UnitTest1 {
        [TestMethod]
        public void TestMethod1() {
            string[] input = new string[] { };
            Assert.AreEqual(Program.Entrance(input), -1);
        }
        [TestMethod]
        public void TestMethod2() {
            string[] input = new string[] {"-q", "input.txt" };
            Assert.AreEqual(Program.Entrance(input), 2);
        }
        [TestMethod]
        public void TestMethod3() {
            string[] input = new string[] {"-c", "-c" ,"input.txt"};
            Assert.AreEqual(Program.Entrance(input), 1);
        }
        [TestMethod]
        public void TestMethod4() {
            string[] input = new string[] { "-c", "input.txt", "-a" };
            Assert.AreEqual(Program.Entrance(input), 7);
        }
        [TestMethod]
        public void TestMethod5() {
            string[] input = new string[] { "-c", "input.txt", "-o", "output.txt", "-c" };
            Assert.AreEqual(Program.Entrance(input), 4);
        }
        [TestMethod]
        public void TestMethod6() {
            string[] input = new string[] { "-c", "input.txt","-o" };
            Assert.AreEqual(Program.Entrance(input), 5);
        }
        [TestMethod]
        public void TestMethod7() {
            string[] input = new string[] { "-c", "-w", "-l" ,"example.txt" };
            Assert.AreEqual(Program.Entrance(input), 6);
        }
        [TestMethod]
        public void TestMethod8() {
            string[] input = new string[] { "-c", "-w", "-l", "input.txt" };
            Assert.AreEqual(Program.Entrance(input), 0);
        }
        [TestMethod]
        public void TestMethod9() {
            string[] input = new string[] { "-l", "-w", "-c", "input.txt", "-o" ,"output.txt"};
            Assert.AreEqual(Program.Entrance(input), 0);
        }
        [TestMethod]
        public void TestMethod10() {
            string[] input = new string[] { "-l", "-w", "-c", "-a", "input.txt", "-e", "stopList.txt", "-o", "output.txt" };
            Assert.AreEqual(Program.Entrance(input), 0);
        }
        [TestMethod]
        public void TestMethod11() {
            string[] input = new string[] { "-l", "-w", "-c", "-a", "-s", "*.txt", "-e", "stopList.txt" };
            Assert.AreEqual(Program.Entrance(input), 0);
        }
        [TestMethod]
        public void TestMethod12() {
            string[] input = new string[] { "-x" };
            Assert.AreEqual(Program.Entrance(input), 0);
        }

    }
}
  • 测试结果
    1341434-20180319200529700-407099543.png

参考文献链接:
[1]http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html
[2]http://www.cnblogs.com/xinz/p/5044037.html
[3]http://http://www.cnblogs.com/xinz/archive/2011/11/20/2255830.html

转载于:https://www.cnblogs.com/handsomesnail/p/8585505.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值