软件质量与测试第4周小组作业:WordCountPro

1、github地址

https://github.com/Hare-Lucius/WordCountPro

 

基本功能(分别以个人和小组形式提交至github)

2、                                                                                                                          PSP2.1表格

PSP2.1

PSP阶段

预估耗时

(分钟)

实际耗时

(分钟)

Planning

计划

 30

 20

· Estimate

· 估计这个任务需要多少时间

 30

 20

Development

开发

 470

 550

· Analysis

· 需求分析 (包括学习新技术)

 30

 20

· Design Spec

· 生成设计文档

 20

 20

· Design Review

· 设计复审 (和同事审核设计文档)

 30

 20

· Coding Standard

· 代码规范 (为目前的开发制定合适的规范)

 30

 30

· Design

· 具体设计

 30

 40

· Coding

· 具体编码

 180

 240

· Code Review

· 代码复审

 30

 30

· Test

· 测试(自我测试,修改代码,提交修改)

 120

 150

Reporting

报告

 90

 90

· Test Report

· 测试报告

 30

 30

· Size Measurement

· 计算工作量

 30

 30

· Postmortem & Process Improvement Plan

· 事后总结, 并提出过程改进计划

 30

 30

 

合计

 590

 660

 

3、接口设计

我负责完成核心处理部分,即单词词频统计,排序等功能。输入模块会以String形式传入待处理的文件名,本模块将文件内的单词进行词频统计,并按照词频进行升序排列,对于频率相同的单词,按照字母顺序进行二次排列,并将单词和频率分别存入两个数组中。本模块的输出为两个数组的数组名,将传入输出模块进行后续处理。在实际代码编写过程中,对文件进行行处理。规定a-z、A-Z和“-”为单词字符,对每一行进行扫描,遇到非单词字符则跳过,遇到单词字符则进行标记直至遇到非单词字符,再向前扫描至非“-”字符,所得子串为一个单词。判断该单词是否已录入数组,若是则频率自增,否则录入该单词并设频率为1。对文章统计完毕后,将频率数组进行排序,考虑到时间开销 ,此处采用快速排序,交换频率次序的同时也要交换单词的次序。之后,对于同频率的单词,利用Arrays.sort()函数进行单词排序,由于频率相同,故只需交换单词次序。

词频统计:

File fi=new File(file);
            Scanner in = new Scanner(fi);
            //String[] sto=new String [100];
            while (in.hasNextLine()) 
            {
                int i=0,start=0,end=0,sf=0;
                String str = in.nextLine();
                while(i<str.length())
                {
                    char b=str.charAt(i);
                    if(b>='a'&&b<='z'||b>='A'&&b<='Z'||b=='-')
                    {
                        if(sf==0)
                        {
                            start=i;
                            sf=1;
                        }
                        i++; 
                    }
                    else
                    {
                        if(sf==1)
                        {
                            end=i-1;
                            //b=str.charAt(end);
                            while(str.charAt(end)=='-')
                            {
                                end--;
                            }
                            sf=0;
                            list(str.substring(start, end+1).toLowerCase());
                            
                        }
                        i++;
                    }
                    
                    
                        
                    //System.out.println(end);
                    
                }
                if(sf==1)
                {
                    end=i-1;
                    //b=str.charAt(end);
                    while(str.charAt(end)=='-')
                    {
                        end--;
                    }
                    sf=0;
                    list(str.substring(start, end+1).toLowerCase());
                }

频率排序:

    public static int partition(int []array,int lo,int hi)
    {
        int key=array[lo];
        String keys=slist[lo];
        while(lo<hi)
        {
            while(array[hi]>=key&&hi>lo)
            {
                hi--;
            }
            array[lo]=array[hi];
            slist[lo]=slist[hi];
            while(array[lo]<=key&&hi>lo)
            {
                lo++;
            }
            slist[hi]=slist[lo];
        }
        array[hi]=key;
        slist[hi]=keys;
        return hi;
    }
    
    public static void sort(int[] array,int lo ,int hi)
    {
        if(lo>=hi)
        {
            return ;
        }
        int index=partition(array,lo,hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi); 
    }

同频率单词排序:

int m=0,n=0;
while(m<=record&&n<=record)
{
     while(fqc[m]==fqc[n])
           n++;
     Arrays.sort(slist,m,n);
     m=n+1;
     n=m;
}

 

4、测试设计

测试用例覆盖函数中所有的判断语句,同时针对同单词的不同形式识别、排序最差情况、词频排序、字母排序等各种情况设计测试用例。

 

5、单元测试截图

测试质量:测试涵盖了重要的函数,并从多个不同方面设计了40个测试用例对核心部分进行了单元测试,可以认为测试具有较高的质量。

被测模块的质量:从测试的正确率可以看出,被测模块的质量较高,对于一些常见的输入情况都能做出正确的输出。此外,从测试时间也可以看出,被测的函数的时间复杂度并不高,经常是很快的时间就能输出结果。

 

6、小组贡献分

我负责的核心模块在小组内编码量最多,同时也承担了组内一半的测试用例,故小组贡献分为0.38。

(小组情况:17044:核心模块,0.38;17062:输入模块,0.2;17065:输出模块,图形界面,0.32;17064:其他模块,0.1)

 

 

扩展功能(仅以小组形式提交至github)

7、开发规范说明

选取《阿里巴巴 Java 开发手册》中“编程规约-代码格式”中的前九条强制要求进行代码评审。我负责评审17065的代码(输出模块)。

 

8、交叉代码评审

(下面将列出评审要求,若未满足则在括号内予以说明,若满足则无说明;同时将待评审代码张贴如下)

a、大括号使用:1) 左大括号前不换行。(未满足) 2) 左大括号后换行。 3) 右大括号前换行。 4) 右大括号后还有else等代码则不换行;表示终止的右大括号后必须换行。

b、左小括号和字符之间不出现空格;右小括号和字符之间也不出现空格。

c、if/for/while/switch/do等保留字与括号之间都必须加空格(未满足)。

d、任何二目、三目运算符的左右两边都需要加一个空格(未满足)。

e、采用4个空格缩进,禁止使用tab字符(部分未满足)。

f、注释的双斜线与内容之间有且仅一个空格(未满足)。

g、单行字符数限不超过 120 个,超出需要换行,换行时遵循如下原则:1) 第二行相对第一行缩进4个空格,从第三行开始不再继续缩进(未满足)。 2) 运算符与下文一起换行。 3) 方法调用的点符号与下文一起换行。 4) 方法调用时,多个参数,需要换行时,在逗号后进行。 5) 在括号前不要换行。

h、方法参数在定义和传入时,多个参数逗号后边必须加空格(未满足)。

i、IDE的text file encoding设置为UTF-8; IDE中文件的换行符使用Unix格式,不要使用Windows格式。

public class Output 
{
    private String[] name;
    private int[] num;
    private int length=0;
    private int record;
    public Output(String[] name,int[] num,int record)
    {
        this.record=record+1;
        this.name=name;
        this.num=num;
    }
    public void out() throws IOException{
        if(record>100) record=100;
        else if(record==0) 
            {
            System.out.println("没有统计到单词"); 
            //return 0;
            }
       // if(name.length!=num.length) 
        //    {
        //    System.out.println("单词数量统计错误"); 
            //return 1;
        //    }
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("output.txt")),true)); 
        for(int i=0;i<record;i++)
        {
            if(num[i]<0) 
            {
                System.setOut(new PrintStream(new BufferedOutputStream(  
                        new FileOutputStream(FileDescriptor.out)),true));  
                System.out.println("单词数量统计错误");
                //return 1;
            }
            System.out.println(name[i]+" "+num[i]);
        }
        //return 2;
    }

}

 

9、静态代码扫描

静态代码检查工具:阿里巴巴Java开发代码检测IDE插件;

下载网址:https://github.com/alibaba/p3c。

 

10、扫描结果

代码的主要问题如下图所示

下面举例说明代码的不规范之处:

a、if语句中由于只有一行代码,未使用大括号,属于较严重的不规范之处

b、没有类的创建者信息

 

11、组内代码分析

小组成员的代码总体上实现所需的功能,但在代码规范上都或多或少地存在不足之处。除了格式问题,还有一些诸如存在未使用的变量、未尽可能地考虑异常处理等问题。

改进方案:规范代码格式,减少无用变量的声明,更多考虑异常。

 

12、代码改进

我按照静态测试的结果和小组评审的结果修改了代码(具体见github),再运行单元测试后,发现运行时间并未得到太大的改变,分析原因如下:

原代码中多为不规范之处,但并无严重影响代码效率的语句,故修改代码会有利于代码维护和更新,但不会对运行效率有太大的影响。

 

 

高级任务(仅以小组形式提交至github):

13、设计测试数据集

在软件设计完成后,设计多个不同大小的文本文档作为输入文件,作为测试数据集。对于每个文件,随机产生数字,再整除26,得到0-25的整数,将这些整数映射到a-z得到字符。

 

14、测试结果

未对代码进行方法优化,但通过性能测试改进了大数据时的代码不足。

使用20000字符,40000字符,80000字符,160000字符,640000字符(大小为59kb118kb235kb469kb1875kb)作为测试用例,多次测试,取平均结果,测试结果如下:

20000字符 63ms

40000字符 94ms

80000字符 140ms

160000字符 250ms

640000字符 874ms

结论:随着文件内字符数增加,运行时间也逐渐增加,且两者成一定的线性关系。

 

15、同行评审过程描述

小组成员及分工:U201517065 徐豪 记录员,主持人 ;

 

                         U201517062 练志东 评审员;

                         U201517044 陆犇圆 作者,讲解员;

评审过程:(1)指明讨论过程中的角色分工(主持人、作者、讲解员、评审员、记录员);(2)说明评审目的;(3)指明讨论过程中,各评审员的评审意见;(4)列出最终的评审结论,例如,发现并确认的缺陷清单;(5)说明本次评审中存在的不足,或者遇到的困难。

评审目的:优化代码性能。

 

16、性能分析(评审结果)

                      每次运行时间存在差异,主要原因可能是系统其他进程的影响,这种影响一般不大,但偶尔会出现使结果出现较大波动。

                      对于运行时间影响最大的因素是统计单词列表,其中的循环和判断语句会耗费比较多的时间,因此如果要提高性能,应尽可能精简单词判断方法。

                      其次的因素则是对于频率的排序,采用快速排序,已经尽肯能减小排序所带来的时间开销。

                      对于单词的输入输出部分,由于没有过多判断而且循环长度不大,因此对性能影响不大。

 

17、性能优化

通过测试,在输入不变的情况下,若通过注释减少单词判断方法内的判定语句的数量,可以减少运行时间(但这样显然得不到正确结果,故仅作为性能测试的依据,不予以实践);而对于其他模块的修改,减少的运行时间量明显不如前者,如此可以印证评审结论。

 

18、实践感想

软件开发和软件测试都是软件生命周期的重要组成部分,都是软件过程之中的重要活动。软件开发为软件测试提供对象,软件测试是保证软件质量的重要手段。软件开发是一个创造的过程, 软件测试是一个维护的过程,二者的目的都应该是致力于提高软件的质量。平时我们可能会忽略软件测试的重要性或者草草了事,但实践证明,软件测试的所需时间和重要性并不亚于软件开发。只有二者兼顾,才能真正保证软件的质量。

 

19、附加题

图形界面(在完成高级功能后加入,故github中只有最后一次提交的内容有图形界面)

 

 

20、参考文献

java实现快速排序:https://blog.csdn.net/u010853261/article/details/54884784

git创建标签:https://blog.csdn.net/wangjia55/article/details/8793577/

 

转载于:https://www.cnblogs.com/lucius-lby/p/8735467.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值