WordCount编码和测试

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

PSP表格

PSP2.1 PSP阶段 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20 10
Estimate 估计任务需要多少时间 20 10
Development 开发 150 140
Analysis 需求分析 10 10
Design Spec 生成设计文档 10 0
Design Review 设计复审 10 0
Coding Standard 代码规范 10 0
Design 具体设计 20 20
Coding 具体编码 60 80
Code Review 代码复审 10 10
Test 测试 20 20
Reporting 报告 60 90
Test Report 测试报告 30 60
Size Measurement 计算工作量 20 20
Postmortem 总结 10 10
合计 230 240

解题思路

将问题分解为如下模块:

  • 解析命令行参数 (将输入转化为路径以及各种操作选项如-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);
} }
}
  • 测试结果


参考文献链接:

[1]http://www.cnblogs.com/xinz/archive/2011/10/22/2220872.html

[2]http://www.cnblogs.com/xinz/p/5044037.html

[3]http://http

WordCount编码和测试的更多相关文章

  1. WordCount 编码与测试

    word count github 项目地址:https://github.com/liuqiang666/wordCount PSP表格 PSP2.1  PSP阶段  预估耗时(小时)  实际耗时( ...

  2. WordCount编码与测试

    1. github项目地址:https://github.com/wwwwu/WordCount 2.PSP表格: PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning ...

  3. 软件质量与测试——WordCount编码实现及测试

    1.GitHub地址       https://github.com/noblegongzi/WordCount 2.PSP表格 PSP2.1 PSP 阶段 预估耗时 (分钟) 实际耗时 (分钟) ...

  4. WordCount编码测试

    Github项目地址:https://github.com/LantyrLYL/WordCount PSP表格: PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计 ...

  5. 软件测试第2周个人作业:WordCount编码测试

    一.Github地址 https://github.com/zhouyubei/WordCount 二.PSP表格 PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning ...

  6. WordCount程序与测试

    Github地址: https://github.com/hcy6668/wordCount PSP表格: PSP PSP阶段 预估耗时(分钟) 实际耗时(分钟) Planning 计划 60 40 ...

  7. WordCountPro 编码与测试

    WordCountPro github项目地址:https://github.com/handsomesnail/WordCountPro PSP表格 PSP2.1  PSP阶段  预估耗时(小时) ...

  8. WordCount程序及测试

    Github地址:https://github.com/CG0317/WordCount PSP表: PSP2.1 PSP阶段 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划  30 ...

  9. mysql字符集编码乱码测试如下

    创建三个表tb_latin1,tb_utf8,tb_gbk,编码分别为latin1/utf8/gbk “你好a”字符串编码如下GBK : %C4%E3 %BA%C3 %61UTF-8 : %E4%BD ...

随机推荐

  1. 转载:maven依赖范围

    其中依赖范围scope 用来控制依赖和编译,测试,运行的classpath(注意是与classpath)的关系. 主要的是三种依赖关系如下:1.compile: 默认编译依赖范围.对于编译,测试,运行 ...

  2. jacksi(比较实用的工具批处理)

    批处理类别: 国产软件 批处理语言: 简体中文 授权方式: 免费软件 运行环境: Windows平台 警告:运行BAT源码是一种危险的动作,如果你不熟悉,请不要尝试! 这里分享的是用bat写的比较实用 ...

  3. Linux评估 CPU使用情况

    评价参数 1)CPU utilization:最直观最重要的就是CPU的使用率.如果长期超过80%,则表明CPU遇到了瓶颈:2)User time: 用户进程使用的CPU:该数值越高越好,表明越多的C ...

  4. Oracle导出导入

    导出 exp 用户名/密码 file=文件名.dmp full=y; 导入 imp 用户名/密码 file=文件名.dmp full=y; 使用EXPDP和IMPDP时应该注意的事项: EXP和IMP ...

  5. Docker资源

    1.Docker入门教程 http://www.code123.cc/docs/docker-practice/repository/config.html 2.Docker入门教程 http://w ...

  6. [转载]Linux 内核list_head 学习(一)

    在Linux内核中,提供了一个用来创建双向循环链表的结构 list_head.虽然linux内核是用C语言写的,但是list_head的引入,使得内核数据结构也可以拥有面向对象的特性,通过使用操作li ...

  7. linux串口基本编程

    Linux的串口表现为设备文件.Linux的串口设备文件命名一般为/dev/ttySn(n=0.1.2„„),若串口是USB扩展的,则串口设备文件命名多为/dev/ttyUSBn(n=0.1.2„„) ...

  8. DataGrid 单元格输入验证 由ValidatingEditor事件完成

    private void gdv_reguline_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContai ...

  9. C语言生成程序问题

    问题: 我用VS2013写好C语言程序调试运行后就在debug文件夹下生成了EXE文件,可以在本机运行.但是这个EXE文件在别的没装过VS2013的电脑上就不能直接运行,说丢失MSVCR120D.dl ...

  10. 第十二章 Jetty的工作原理解析(待续)

    Jetty的基本架构 Jetty的启动过程 接受请求 处理请求 与JBoss集成 与Tomcat的比较