WordCount-软件测试初体验

github:https://github.com/skz12345/WordCount

PSP2.1 PSP阶段 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 40 60
· Estimate · 估计这个任务需要多少时间 40 60
Development 开发 305 510
· Analysis · 需求分析 (包括学习新技术) 60 120
· Design Spec · 生成设计文档 20 30
· Design Review · 设计复审 (和同事审核设计文档) 20 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 15 20
· Design · 具体设计 40 60
· Coding · 具体编码 60 120
· Code Review · 代码复审 30 40
· Test · 测试(自我测试,修改代码,提交修改) 60 90
Reporting 报告 100 150
· Test Report · 测试报告 30 60
· Size Measurement · 计算工作量 10 30
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 60 60
合计 445 720

代码部分参考了MasonWater在https://github.com/MasonWater/WCProject所提交的代码,本次测试基于本程序进行测试。

解题思路

根据作业要求,可以分析出此次作业有多个输入参数,根据参数的不同,实现一些有严格要求的功能。关于多参数的传递,选择使用main函数传参的方法。通过查阅资料【1】,找到了java如何读取文件内容,通过此方法,按照作业要求对各项数据进行统计,用代码得以实现。

程序设计实现过程(以下主要基于http://www.cnblogs.com/hayitutu/p/8613653.html,Wonderkid的博客)

程序包括一个类(wordcount),9个函数,其中包括一个main函数。其余8个函数为:

Operator函数(实现功能)、BaseCount函数(基本功能)、Display函数(设置输出到文件的字符串)、MoreCount函数(扩展功能)、getStopLisy函数(获取停词表中停词)、outputTxt函数(设置输出文件)、Bianli(实现递归处理)、getAllFile函数(获得符合要求后缀的文件名)。

main函数获取到参数后分类,将功能参数和文件参数分别存储之后用于生成wordcount类的一个对象。之后调用对象的Operator功能,循环遍历功能数组判断需要执行那些操作。根据参数判断来调用对应的函数。如事先判断是否有启用停词表的参数,若有则先调用getStopList函数获取停用词表,之后若参数是基本功能的参数,就调用BaseCount函数来统计,同时判断是否去除停词。若是扩展功能参数,如复杂行的统计则调用MoreCount函数来统计代码行,空行和注释行。若是递归调用功能参数则调用BianLi函数,BianLi函数调用getAllfile函数获取符合要求的文件队列然后递归执行相应的操作(BaseCount、MoreCount等)。在递归操作或者Operator执行过程中若有输出文件指定则将输出flag调整。最后调用Display函数设置输出到文件中的内容,之后调用outputTxt函数来根据输出flag输出到文件中。当完成基本功能后,将源文件上传到github仓库中,commit一次,之后完成程序再次上传,打包好exe后完成最后的上传。后续还上传了测试脚本和测试相关文件。

代码说明(以下主要基于http://www.cnblogs.com/hayitutu/p/8613653.html,Wonderkid的博客)

代码说明

BaseCount方法中去除停词时将文件按行读入【2】,通过逗号和空格分割单词后和停用词数组中词比较,统计去除词的个数,每行处理一遍。同时注意行开头空格的去除【3】

代码如下:

BufferedReader st2 = new BufferedReader(new FileReader(this.sFilename));//统计单词数
                 String read1 = null;
                 int lengthofSplit=0;
                   while (( read1 =st2.readLine()) != null)
                   {
                      read1=read1.trim();//去除空格
                     String[] arrSplit =read1.split(" |,");//以空格或者逗号分隔
                     lengthofSplit=arrSplit.length;
                     for(String s:arrSplit)
                     {
                         if(s.length()==0)
                             lengthofSplit--;//去除空格
                     }
                     wordcount+=lengthofSplit;
                     if(openStopList==1)
                     {
                      for(String s:arrSplit)
                      {
                         for(String stop:StopList)
                         if(s.equals(stop))
                             stopWordCount++;

                      }
                     }

                   }
                   st2.close();

MoreCount方法中同样也是对文件按行读取,判断多行注释的时候和单行注释一样要判断注释前是否多于一个字符,这通过一个计数变量来实现,以及“/”后有字符则不算注释行,这也通过计数变量来实现。同时当有“/”开始后,设置多行注释的flag变量,当遇到“/*”时重置flag

代码如下:

flagOfword=0;
              countOfword=0;
              numberOfMLines=0;
             BufferedReader brm = new BufferedReader(new FileReader(this.sFilename));
             String linem;
             int flagOfM=0;//标记是否有/*开始了
             int countss=0;//记录每行字符数以便判断是否是注释行
             int counts=0;//记录每行字符数以便判断是否是注释行
            while ((linem = brm.readLine()) != null)//判断/**/类型的注释行
             {

                 String [] sss=new String[10000];
                 if(flagOfM==1)
                    numberOfMLines++;

                  for (int x = 0; x < linem.length(); x++)
                  {

                    sss[x]=String.valueOf(linem.charAt(x));
                     int temp=(x+1)<(linem.length()-1)? x+1:(linem.length()-1);
                if(flagOfM==0)
                { countss=0;//
                     if(x<linem.length()-1&&sss[x].equals("/")&&linem.charAt(temp)==‘*‘)
                      {
                         for(int i=0;i<x;i++)
                            {if(linem.charAt(i)!=‘ ‘)
                              {  if(linem.charAt(i)==‘\t‘)
                                  continue;
                              countss++;

                              }
                            }
                        if(countss>1)
                        {
                            flagOfM=0;

                        }
                        else
                        {

                            flagOfM=1;

                        }
                        continue;
                      }

                }
                 if(flagOfM==1)
                {counts=0;
                    if(x<linem.length()-1&&sss[x].equals("*")&&linem.charAt(temp)==‘/‘)
                    {
                        for(int i=temp+1;i<linem.length()-1;i++)
                            {if(linem.charAt(i)!=‘ ‘)
                              {  if(linem.charAt(i)==‘\t‘)
                                  continue;
                                counts++;
                              }
                            }
                        if(counts<=1)
                        {
                            numberOfMLines++;
                            flagOfM=0;

                        }
                        else
                        {
                            flagOfM=0;
                        }

                    }

                }

              }

             }
             brm.close();

对于扩展功能里的递归读取符合要求的文件,这通过两个函数实现,BianLi函数调用getAllFile函数来筛选符合要求的文件之后的操作便是循环执行Operator函数的操作,所以BianLi函数不再赘述。关于getAllFile函数,函数有四个参数:文件路径、符合要求的文件/文件夹的存储数组、要筛选的类型以及筛选出来的文件数组。函数通过判断是否是文件夹来操作,若是文件夹则递归调用函数,否则判断类型后删选文件。

代码如下:

private static List<String> getAllFile(File filePath,List<String> filePaths,String type,List<String> finalFiles){
            File[] files = filePath.listFiles();//递归获取文件夹以及子目录下的所有符合条件的文件

            if(files == null){
                return filePaths;
            }
            for(File f:files){
                if(f.isDirectory()){
                    filePaths.add(f.getPath());
                    getAllFile(f,filePaths,type,finalFiles);
                }else{
                    if(f.getName().endsWith(type))
                    {filePaths.add(f.getPath());
                    finalFiles.add(f.getPath());}
                }
            }

            /*for(String path:finalFiles){
                System.out.println(path);
            }*/

            return finalFiles;
        }

测试设计过程

在线学习2.3节中对测试的判定中提到“要保证测试用例覆盖函数中的所有可执行路径”,以此为出发点,我尽可能精简的设计了10条测试用例。

一、基于基本功能的测试

基本功能是该程序的第一次提交所实现的内容,由以下4条测试用例测试基本功能:

  1. wc.exe -c -w file1.c
  2. wc.exe -l file.c -o output.txt
  3. wc.exe -l -c -w file1.c
  4. wc.exe -c -l -w file1.c

设计思想

基本功能的实现中,所有指令均为通过flag置位判断是否执行,flag的值只为0或1,在1,2两个测试用例中,交叉试验了-c -w -l -o四个功能,flag为0和为1全部覆盖。

在3,4两个测试用例中,测试了需求中要求的顺序是否能正确执行。

二、基于扩展功能的测试

扩展功能是该程序的第二次提交所实现的内容,有以下三条测试用例测试扩展功能:

  1. wc.exe -a file1.c
  2. wc.exe -s -a *.c
  3. wc.exe -w file1.c -e stoplist.txt

设计思想

测试用例5测试了返回更复杂的数据,测试用例6测试了递归处理,测试用例7测试了启用停用词表下统计单词总数功能是否正确。

三、综合测试

最后提交将两种功能叠加,进行总体测试,以下为三条测试用例:

  1. wc.exe -c -w -a -l file1.c
  2. wc.exe -w -a -c -l file1.c
  3. wc.exe -s -c -w -l -a *.c -o output.txt -e stoplist.txt

设计思想

测试用例8和9对于总顺序是否能正确执行进行测试,测试用例10对于系统最复杂的功能集合进行了测试。

在对错误输入的处理上,如果处理不当,往往会造成许多无法估计的后果,风险很高。

由于10条测试用例太少,并不能完全说明问题,预想中还应改变不同的代码,进行一些错误处理、临界值等的测试,将会在未来进行尝试。

参考文献

【1】https://blog.csdn.net/sky786905664/article/details/65626886

【2】https://www.cnblogs.com/xyzq/p/7095011.html

【3】http://blog.csdn.net/zhangzehai2234/article/details/73522041

原文地址:https://www.cnblogs.com/fleshbone/p/8634955.html

时间: 2024-11-12 16:44:00

WordCount-软件测试初体验的相关文章

软件测试学习笔记week 3 --- 测试框架初体验

测试框架初体验 在这周的软件测试课上,第一次了解了软件测试框架的概念.软件测试框架包含的范围非常广,从自动化测试框架到单元测试框架以及性能测试框架.在上个寒假中,在学习Coursera的在线课程时发现普林斯顿的单元测试做得非常强大,从程序正确性到Time consuming甚至Memory consuming,几乎能发现程序中的每一处错误或者缺陷.因此,在上完了这周的课程后,我查阅了一些资料,做了这篇随笔记录了解到的单元测试的知识. 一.什么是测试框架 要认识测试框架,首先要对所谓框架有概念.框

Hadoop集群启动、初体验

1. 启动方式要启动Hadoop集群,需要启动HDFS和YARN两个集群.注意:首次启动HDFS时,必须对其进行格式化操作.本质上是一些清理和准备工作,因为此时的HDFS在物理上还是不存在的.hdfs namenode–format或者hadoop namenode –format1.1. 单节点逐个启动在主节点上使用以下命令启动HDFS NameNode:hadoop-daemon.sh start namenode在每个从节点上使用以下命令启动HDFS DataNode:hadoop-dae

erlang 初体验

最近测试了一下 erlang的坑... 如不出意外.... 大家第一眼看到这语法... 心里第一句一定是"我擦.这TM都是啥!!!!!" 没有变量!!! 没有结构体!!! 没有循环!!! 好吧,至少我是这样想的. 找了半天..连个if也不知道怎么写.. 这记录一些基本常识.. -module(module_name)  %%定义模块 括号内的要和文件名相同. -export([fun1/1 fun2/2]) %%这里是导出2个函数对外使用  函数名/参数名. 一个简单的函数定义如下 f

linux初体验

第一次听到linux这个'词语'是在一次偶然的朋友聊天中朋友提到的,之前压根没听到过'这个东西',所以我可以说是个linux的新新手,菜鸟都不算. 截至到目前,我已经开始linux系统运维学习有差不多10天时间了.在没接触linux之前,我对它的认识仅仅是:它是个计算机系统.决定学习linux系统运维之前,自我以为运维应该是对系统的一些日常维护之类的,不会很难的东西,我更希望运维是个不难的东西,我个人很笨,对难的东西可能接受的很慢,所以我愿意认为运维是很简单的,这样我就可以轻轻松松的掌握运维相关

【Spark深入学习 -15】Spark Streaming前奏-Kafka初体验

----本节内容------- 1.Kafka基础概念 1.1 出世背景 1.2 基本原理 1.2.1.前置知识 1.2.2.架构和原理 1.2.3.基本概念 1.2.4.kafka特点 2.Kafka初体验 2.1 环境准备 2.2 Kafka小试牛刀 2.2.1单个broker初体验 2.2.2 多个broker初体验 2.3 Kafka分布式集群构建 2.3.1 Kafka分布式集群构建 2.3.2 Kafka主题创建 2.3.3 生产者生产数据 2.3.4消费者消费数据 2.3.5消息的

Java8初体验(二)Stream语法详解

原文链接:http://ifeve.com/stream/ 1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel aggregate operations. 我们来解读一下上面的那句话: Stream是元素的集合,这点让Stream看起来用些类似Iterator: 可以支持顺序和并行的对原Stream进行汇聚的操作: 大家可以把Stream当成一个高级版本的

hibernate--CRUD初体验

hibernate的crud操作初体验. 看具体实例 package com.fuwh.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import org.hibernate.annotations.GenericGenerator; @Entity publ

Oracle SQL篇(一)null值之初体验

    从我第一次正式的写sql语句到现在,已经超过10年的时间了.我写报表,做统计分析和财务对账,我一点点的接触oracle数据库,并尝试深入了解.这条路,一走就是10年,从充满热情,到开始厌倦,我不知道我还能坚持多久,未来的路,谁知道呢? 也许是该抓紧时间,做一点什么了,我不知道该开始写些什么,我从来没有在网上写东西的习惯.     先从简单的开始吧,那当然就是SQL,这是我SQL系列的第一篇,希望我能够坚持. 在Oracle数据库中,如果一个表中的列没有值的话,我们可以说是空值,比如IT员

AngularJS路由系列(3)-- UI-Router初体验

本系列探寻AngularJS的路由机制,在WebStorm下开发. AngularJS路由系列包括: 1.AngularJS路由系列(1)--基本路由配置2.AngularJS路由系列(2)--刷新.查看路由,路由事件和URL格式,获取路由参数,路由的Resolve3.AngularJS路由系列(3)-- UI-Router初体验4.AngularJS路由系列(4)-- UI-Router的$state服务.路由事件.获取路由参数5.AngularJS路由系列(5)-- UI-Router的路由

Android Studio初体验之启动AVD模拟器异常:cannot set up guest memory &#39;pc.ram&#39;

启动AVD模拟器异常:Cannot set up guest memory 'pc.ram' 错误信息: HAX is working and emulator runs in fast virt mode Cannot set up guest memory 'pc.ram': Invalid argument Error accepting connect 分析 各种查资料,没有发现网上有同样问题的,在一篇相关文章中找到类似的解决方法. 从语意看,应该是hax安装后没有启动.(不懂hax是什