第四周小组作业wcPro

第四周小组作业wcPro

1  基本任务:代码编写+单元测试

  1.1 小组github地址

    github.com/Asfalas/wcPro

  1.2 PSP表格

    

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

  

  1.3 接口实现及具体编码

    · 接口描述

      本次小组任务中我所需要实现的模块是核心处理部分,接口是接受输入模块传过来的字符串进行分析,统计字符串中的所有单词及其词频,再将其放置在一个Map容器内输出(未经过排序)。

    · 设计思路

      使用一个类wcMainProcess实现相关功能,内有两个方法,分别为词频统计方法countWordFrequency()和单词判断函数word()。思路为使用递归下降的方法对字符串进行分析,设置一个属性为 index记录当前所读的字符位置,先预读一个字符,如果是字母a-z,则调用word方法检索以该字母开头的符合规则的单词,直到后面的字符不是a-z,如果是-,则再次预读一个字符,若为字母则递归调用word向后检索;如果不是-,则将检索的字符放入stringBuilder中并返回。

    · 具体实现

    (1)word()检索判断单词方法,fileContent为输入模块所返回的字符串,index为当前索引位置。
 1  public StringBuilder Word()
 2     {
 3         char temp = fileContent.charAt(index);
 4         while(temp >= 'a' && temp <= 'z')
 5         {
 6             curWordBuilder.append(temp);
 7             if(index == fileContent.length()-1)
 8                 return curWordBuilder;
 9             temp = fileContent.charAt(++index);
10         }
11         if(temp == '-')
12         {
13             if(index + 1 < fileContent.length())
14             {
15                 char nextChar = fileContent.charAt(index + 1);
16                 if((nextChar >= 'a' && nextChar <= 'z'))
17                 {
18                    curWordBuilder.append('-');
19                    index++;
20                    Word();
21                 }
22             }
23         }
24         return curWordBuilder;
25     }
    (2)countWordFrequency(),使用word()方法依次检索fileContent里的每个单词并统计词频放入map容器,最后返回统计完成后的map容器
 1 public Map<String,Integer> countWordFrequency()
 2     {
 3         curWordBuilder = new StringBuilder();
 4         for(;index < fileContent.length(); index++)
 5         {
 6             char temp = fileContent.charAt(index);
 7             if(temp >= 'a' && temp <= 'z')
 8             {
 9                 String word = Word().toString();
10                 if(result.containsKey(word))
11                     result.put(word,result.get(word)+1);
12                 else
13                     result.put(word,1);
14                 curWordBuilder = new StringBuilder();
15             }
16         }
17         return result;
18     }

   1.4 测试用例设计

  本次测试使用黑盒测试和白盒测试(条件判定覆盖)结合的方式,各选取10个用例对两个方法进行单元测试,具体用例设计参见测试用例清单。

  以Word()方法为例,其中有5个条件和7个逻辑表达式判定,使用条件/判定覆盖方式进行测试时,用例将每种逻辑表达式均覆盖到,可按照如下清单方式选择测试用例。黑盒测试则是将单词分成若干等价类,每个等价类选取1-2个测试用例进行测试,如只有字母的单词,用-连接的单词,用其他特殊符号连接的单词等,详情见测试用例清单如下:

  

 

  1.5 单元测试运行结果

  使用JUnit4框架进行单元测试,在类wcMainProcessTest中对wcMainProcess进行单元测试。

  为了测试的可重用性,我将用例并没有写死在代码中,而是写在了文件里,在@beforeClass注解的方法中将其读入用例的容器,提高了测试用例的可重用性和可修改性及独立性。

  参数化测试方法   

  由于测试用例数目较多,我使用了单元测试的参数化方法,使用@RunWith(Parameterized.class)注解,同时构建了参数构造方法,如下图所示:

 1 @Parameterized.Parameters
 2 public static Collection testData(){
 3     return Arrays.asList(new Object[][]
 4             {
 5             { 0 },
 6             { 1 },
 7             { 2 },
 8             { 3 },
 9             { 4 },
10             { 5 },
11             { 6 },
12             { 7 },
13             { 8 },
14             { 9 },
15             { 10 },
16             { 11 },
17             { 12 },
18             { 13 },
19             { 14 },
20             });
21 }//将用例的序号传入下面的测试构造方法
22 
23 //根据序号从初始化容器中取出用例
24 public wcMainProcessTest(int index){
25     wcMainProcess wcmp = new wcMainProcess(usecasesOfWord.elementAt(index));
26     actualOfWord = wcmp.Word().toString();
27     expectOfWord = expectsOfWord.elementAt(index);
28     wcmp = new wcMainProcess(usecasesOfWordFrequency.elementAt(index));
29     actualOfWordFrequency = wcmp.countWordFrequency();
30     expectOfWordFrequency = expectsOfWordFrequency.elementAt(index);
31 
32 }

    单元测试方法如下:

 1 /** 
 2 * 
 3 * Method: countWordFrequency() 
 4 * 
 5 */ 
 6 @Test
 7 public void testCountWordFrequency() throws Exception {
 8     assertEquals(expectOfWordFrequency, actualOfWordFrequency);
 9 } 
10 
11 /** 
12 * 
13 * Method: Word() 
14 * 
15 */ 
16 @Test
17 public void testWord() throws Exception
18 {
19     assertEquals(expectOfWord,actualOfWord);
20 }

  测试结果截图如下:

  测试质量和测试代码质量均较高,可以在9ms内跑完所有的30个用例。

  1.6 小组贡献分

  根据小组讨论结果,小组贡献分大致为 17046-0.27分、17043-0.26分、17053-0.25分、17049-0.22分。

 

2 扩展功能

  2.1 开发文档的选择与说明

       我们在开发过程中选择了《阿里巴巴Java开发手册》,通过老师在博客中发布的链接进行下载:https://yq.aliyun.com/attachment/download/?id=4942

    并且可以了解开发手册对应插件在IDEA上的应用:https://yq.aliyun.com/articles/225187?spm=5176.10695662.1996646101.searchclickresult.6ff77f392uUgs1

  2.2 同学的代码问题

   我负责检查文宇凡(17053)的代码,可以看出,他的编码习惯还是比较好的,存在的问题就是类名的驼峰命名法、包名的大小写问题 ,缺少创建者信息,以及使用了行尾注释的问题。最为重要的一点就是test类方法较为冗余,建议采取参数化方法简化代码结构。

  2.3 代码检查工具及说明

   我们使用的是“alibaba java coding guidance”插件,可以通过idea直接下载使用,注意保持网络畅通(血的教训)。路径:setting-plugin-Browse Repositories-search,如下图所示:

 

    2.4 我的代码存在的问题

  

   我的代码在自己检测的过程中也存在不少的问题,包括一个我第一次了解到的“魔法值问题”,即出现了未定义的字符或字符串常量,应先用一个常量存放该字符常量等问题,同时还有一些注释的规范。还有值得一提的就是字符串判断相等,应改为("xxx").equals(String)的形式,这样可以避免出现错误,是个良好的编码习惯。

   2.5 小组存在的问题

  总而言之,我们小组的编码规范问题还是挺多的,我们没有使用UpperCamelCase风格作为类名,导致在修改某些类时,因为同样的方法被多次调用所以修改成本非常高,包名等命名规范问题注意之后就有很大改善,修改的并不多,不过仍需要注意;再就是在自己的代码上方添加自己的有关注释,这也是一件看起来十分职业规范化的一件事,综上,大致就是我们小组共同的问题。

3 高级功能

  3.1 测试数据集设计思路

  使用文件大小比较大的数据集来对本程序进行压力测试。我使用了英文的电子书籍《了不起的盖茨比》作为构造测试集,分别构造出了大小为500k,1m,2m,4m,8m,16m的数据集,同时使用了参数化方法对Main函数进行集成的多次测试,观察运行时间。

  3.2 优化前性能指标

  程序的大小以及对应的时间消耗

  3.3 同行评审过程

  小组成员:张付俊(U201517046)、孙帅(U201517043)、张瑞祺(U201517049)、文宇凡(U201517053)

  人员角色分工:张付俊(作者、讲解员)、孙帅(作者,评审员)、张瑞祺(作者,主持人)、文宇凡(作者、评审员)

  评审目的:确保要发布质量可靠的代码,发现各种类型的错误,提高代码质量、规范性、一致性和可维护性,提高代码效能。

  评审意见:

  孙帅:主要对于程序的代码规范角度与部分功能模块角度提出意见

  文宇凡:主要对于代码的功能实现角度提出意见

  评审结论:

  孙帅:(1)代码注释部分较少。可读性较差。

             (2)针对输出测试类方法代码存在大量冗余,需要改进。

  文宇凡:

             (1)将输入字符串传入核心处理模块导致两遍扫描文本,可能会使效率下降,可以一边读文本一边进行排序工作。

             (2)代码规范性存在许多问题需要改进。

  总体结论:代码需要作者做进一步改进

  本次评审的不足:

            (1)由于时间较为紧凑,部分细节的评审并未做到面面俱到。

            (2)因为代码量较少,评审内容有限,不能发现作者的隐藏问题。

  3.4 测试后得到的结论

 

通过测试可以发现,本程序可以在较短的时间内完成对500k,1m,2m,4m,8m,16m等大小的文件进行统计词频。

  3.5 优化思路及其指标

 优化思路如下:可以对一边对文本进行按字符读取,一边进行单词判断统计等功能,最后使用优化的随机快速排序算法对容器进行排序,因为时间有限,优化尚未完成。

  3.6 总结说明

"通过基本任务、扩展任务、到高级任务的完成,如何体现软件开发、软件测试、软件质量之间的关系"

我认为软件开发、软件测试和软件质量这三者之间是存在紧密的联系的。

软件开发离不开测试。不仅是相互的测试,专业测试员对代码的测试,程序开发者也应对自己的代码进行测试,来保证软件的质量。

首先,程序员是最了解自己的代码逻辑的,因此很方便进行白盒测试,在开发过程中就可以找到自身的不足之处,但是由于程序猿写代码过程中的定式思维,许多隐藏的代码难以被发现,此时就需要测试工程师对代码进行单独测试,只有通过了完整和系统的软件测试的软件的质量才是有一定的保障的。

以上便是本次小组实验所得到的结论。

 

4 附加功能

使用-x参数可以调出图形界面进行选取文件,代码如下:

  

1    JFileChooser jfc=new JFileChooser(".");
2                 int returnVal = jfc.showOpenDialog(null);
3                 if(returnVal == JFileChooser.APPROVE_OPTION)
4                 {
5                     //获得打开的文件
6                     inputFile = jfc.getSelectedFile().getAbsolutePath();
7                 }

 

5 参考文献

https://blog.csdn.net/zhu1qiu/article/details/71170850(对map进行遍历)

https://blog.csdn.net/casularm/article/details/164877(map的性质)
 
https://www.zhihu.com/question/21682976(github push和fork的使用)

https://yq.aliyun.com/articles/225187?spm=5176.10695662.1996646101.searchclickresult.6ff77f392uUgs1(idea上使用代码规范插件) 

 

转载于:https://www.cnblogs.com/zhangfjhust/p/8733426.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值