一、实验报告封面
课程:Java程序设计 班级:1652班
指导教师:娄嘉鹏 实验日期:2018年4月13日
实验时间:15:35 - 17:15 实验序号:实验二
实验名称:Java开发环境的熟悉
实验题目:实现凯撒密码并进行安全加固,并进行测试(正常情况,异常情况,边界情况)
实验内容:
1. 初步掌握单元测试和TDD
2. 理解并掌握面向对象三要素:封装、继承、多态
3. 初步掌握UML建模
4. 熟悉S.O.L.I.D原则
5. 了解设计模式
实验要求:
1. 没有Linux基础的同学建议先学习《Linux基础入门(新版)》《Vim编辑器》 课程
2. 完成实验、撰写实验报告,实验报告以博客方式发表在博客园,注意实验报告重点是运行结果,遇到的问题(工具查找,安装,使用,程序的编辑,调试,运行等)、解决办法(空洞的方法如“查网络”、“问同学”、“看书”等一律得0分)以及分析(从中可以得到什么启示,有什么收获,教训等)。报告可以参考范飞龙老师的指导
3. 严禁抄袭,有该行为者实验成绩归零,并附加其他惩罚措施。
4. 请大家先在实验楼中的~/Code目录中用自己的学号建立一个目录,代码和UML图要放到这个目录中,截图中没有学号的会要求重做,然后跟着下面的步骤练习。
二、实验内容及步骤
第一个提交点
参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECUNITTEST 完成单元测试的学习
提交最后三个JUnit测试用例(正常情况,错误情况,边界情况)都通过的截图,截图上要有画图加水印,输入自己的学号
本提交点考查JUnit会不会使用,测试用例至少要包含正常情况,错误情况,边界情况的测试
三种代码
编程是智力活动,不是打字,编程前要把干什么、如何干想清楚才能把程序写对、写好。与目前不少同学一说编程就打开编辑器写代码不同,我希望同学们养成一个习惯,当你们想用程序解决问题时,要会写三种码:
- 伪代码
- 产品代码
- 测试代码
伪代码:伪代码从意图层面来解决问题,是产品代码最自然的、最好的注释
百分制转五分制:
如果成绩小于60,转成“不及格”
如果成绩在60与70之间,转成“及格”
如果成绩在70与80之间,转成“中等”
如果成绩在80与90之间,转成“良好”
如果成绩在90与100之间,转成“优秀”
其他,转成“错误”
- 产品代码:按照
伪代码
的思路逐步实现程序的就是产品代码
public class MyUtil{ public static String percentage2fivegrade(int grade){ //如果成绩小于0,转成“错误” if ((grade < 0)) return "错误"; //如果成绩小于60,转成“不及格” else if (grade < 60) return "不及格"; //如果成绩在60与70之间,转成“及格” else if (grade < 70) return "及格"; //如果成绩在70与80之间,转成“中等” else if (grade < 80) return "中等"; //如果成绩在80与90之间,转成“良好” else if (grade < 90) return "良好"; //如果成绩在90与100之间,转成“优秀” else if (grade <= 100) return "优秀"; //如果成绩大于100,转成“错误” else return "错误"; } }
- 测试代码:为了防止Bug没发现而将产品提交给别人,可以使用测试代码测试bug。
import org.junit.Test; import junit.framework.TestCase; public class MyUtilTest extends TestCase { @Test public void testNormal() { assertEquals("不及格", MyUtil.percentage2fivegrade(55)); assertEquals("及格", MyUtil.percentage2fivegrade(65)); assertEquals("中等", MyUtil.percentage2fivegrade(75)); assertEquals("良好", MyUtil.percentage2fivegrade(85)); assertEquals("优秀", MyUtil.percentage2fivegrade(95)); } @Test public void testExceptions(){ assertEquals("错误",MyUtil.percentage2fivegrade(105)); assertEquals("错误",MyUtil.percentage2fivegrade(-55)); } @Test public void testBoundary(){ assertEquals("不及格",MyUtil.percentage2fivegrade(0)); assertEquals("及格",MyUtil.percentage2fivegrade(60)); assertEquals("中等",MyUtil.percentage2fivegrade(70)); assertEquals("良好",MyUtil.percentage2fivegrade(80)); assertEquals("优秀",MyUtil.percentage2fivegrade(90)); assertEquals("优秀",MyUtil.percentage2fivegrade(100)); } }
我们是该“先写产品代码
,然后再写测试代码
,通过测试发现了一些Bugs,修改代码”,还是该“先写测试代码
,然后再写产品代码
,从而写出来的代码就是正确的”呢?当然先写测试代码
了。这种先写``测试代码`,然后再写产品代码的开发方法叫“测试驱动开发”(TDD)。TDD的一般步骤如下:
- 明确当前要完成的功能,记录成一个测试列表
- 快速完成编写针对此功能的测试用例
- 测试代码编译不通过(没产品代码呢)
- 编写产品代码
- 测试通过
- 对代码进行重构,并保证测试通过(重构下次实验练习)
- 循环完成所有功能的开发
Java中有单元测试工具JUnit来辅助进行TDD,IDEA中使用JUnit要安装插件,选择File->Setting
打开设置对话框:
在设置对话框中选择Plugins
, 单击Install JetBrains
plugin...按钮打开插件安装界面:
在插件安装对话框的搜索中输入junit
,单击JunitGenerator V2.0
,单击右边绿色的Install
按钮安装:
安装完成:
然后在IDEA中新建一个空的类,鼠标单击类名会出现一个灯泡状图标,单击图标或按Alt + Entert
,在弹出的菜单中选择Create Test
后自动生成一个test类
:
如果TestCase
是红色的,需要在IDEA中的项目(模块)中加入junit.jar包,junit.jar包的位置一般在安装目录下lib
文件夹中可以找到,然后在IDEA中选择菜单File->Project Structure...
在弹出的对话框中选择Dependancies
标签页,单击+号,选择JARs or Directories...
,输入junit
的文件地址。
最后run
测试类,所有test
通过就算是通过了.(新版本的IDEA可能没有老版本的小绿条和小红条,但是会有小绿勾和橙感叹)
测试结果:
第二个提交点
- 参考 积极主动敲代码,使用JUnit学习Java (http://www.cnblogs.com/rocedu/p/4837092.html)
- 以 TDD的方式研究学习StringBuffer
- 提交你的单元测试用例和测试通过的截图,截图要加上学号水印
- 测试自己会不会写JUnit测试用例
根据老师给的代码,进行对Junit的应用。
public class StringBufferDemo{ public static void main(String [] args){ StringBuffer buffer = new StringBuffer(20); buffer.append('S'); buffer.append("tringBuffer"); System.out.println(buffer.charAt(1)); System.out.println(buffer.capacity(); System.out.println(buffer.indexOf("tring12345")); System.out.println("buffer = " + buffer.toString()); System.out.println(buffer.length()); } }
产品代码:
public class StringBufferDemo{ StringBuffer buffer = new StringBuffer(); public StringBufferDemo(StringBuffer buffer){ this.buffer = buffer; } public Character charAt(int i){ return buffer.charAt(i); } public int capacity(){ return buffer.capacity(); } public int length(){ return buffer.length(); } public int indexOf(String buf) { return buffer.indexOf(buf); } }
测试代码:
import junit.framework.TestCase; import org.junit.Test; import static org.junit.Assert.*; public class StringBufferDemoTest extends TestCase { StringBuffer a = new StringBuffer("StringBuffer"); StringBuffer b = new StringBuffer("StringBufferStringBuffer"); StringBuffer c = new StringBuffer("StringBufferStringBufferStringBuffer"); @Test public void testcharAt() throws Exception { assertEquals('S',a.charAt(0)); assertEquals('B',a.charAt(6)); assertEquals('r',a.charAt(11)); } @Test public void testcapacity() throws Exception { assertEquals(28, a.capacity()); assertEquals(40, b. capacity()); assertEquals(52, c.capacity()); } @Test public void testlength() throws Exception { assertEquals(12, a.length()); assertEquals(24, b.length()); assertEquals(36, c.length()); } @Test public void testindexOf() throws Exception { assertEquals(0, a.indexOf("Str")); assertEquals(6, a.indexOf("Buf")); assertEquals(10,a.indexOf("er")); } }
按照提交点一的步骤测试
测试截图:
第三个提交点
参考实验二 Java面向对象程序设计
对设计模式示例进行扩充,体会OCP原则和DIP原则的应用,初步理解设计模式
用自己的学号%6进行取余运算,根据结果进行代码扩充 :
0:让系统支持Byte类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
1:让系统支持Short类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
2:让系统支持Boolean类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
3:让系统支持Long类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
4:让系统支持Float类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
5:让系统支持Double类,并在MyDoc类中添加测试代码表明添加正确,提交测试代码和运行结的截图,加上学号水印
代码如下:测试支持short型
abstract class Data { abstract public void DisplayValue(); } class Integer extends Data { int value; Integer() { value=31; } public void DisplayValue(){ System.out.println (value); } } // Pattern Classes abstract class Factory { abstract public Data CreateDataObject(); } class IntFactory extends Factory { public Data CreateDataObject(){ return new Integer(); } } //Client classes class Document { Data pd; Document(Factory pf){ pd = pf.CreateDataObject(); } public void DisplayData(){ pd.DisplayValue(); } } //Test class public class MyDoc { static Document d; public static void main(String[] args) { d = new Document(new IntFactory()); d.DisplayData(); } }
测试截图:
第四个提交点
提交:单元测试代码和运行成功截图及码云上代码链接,截图要加上学号水印
参考http://www.cnblogs.com/rocedu/p/6736847.html
任务:以TDD的方式开发一个复数类Complex,要求如下:
// 定义属性并生成getter,setter
double RealPart;
double ImagePart;
// 定义构造函数
public Complex()
public Complex(double R,double I)
//Override Object
public boolean equals(Object obj)
public String toString()
// 定义公有方法:加减乘除
Complex ComplexAdd(Complex a)
Complex ComplexSub(Complex a)
Complex ComplexMulti(Complex a)
Complex ComplexDiv(Complex a)
产品代码:
public class Complex { private double r; private double i; public Complex(double r, double i) { this.r = r; this.i = i; } public static double getRealPart(double r) { return r; } public static double getImagePart(double i) { return i; } public Complex ComplexAdd(Complex c) { return new Complex(r + c.r, i + c.i); } public Complex ComplexSub(Complex c) { return new Complex(r - c.r, i - c.i); } public Complex ComplexMulti(Complex c) { return new Complex(r * c.r - i * c.i, r * c.i + i * c.r); } public Complex ComplexDiv(Complex c) { return new Complex((r * c.i + i * c.r) / (c.i * c.i + c.r * c.r), (i * c.i + r * c.r) / (c.i * c.i + c.r * c.r)); } public String toString() { String s = " "; if (i > 0) s = r + "+" + i + "i"; if (i == 0) s = r + ""; if (i < 0) s = r + " " + i + "i"; return s; } }
测试代码:
import junit.framework.TestCase; import org.junit.Test; public class ComplexTest extends TestCase { Complex a =new Complex(0,3); Complex b=new Complex(-1,-1); @Test public void testComplexAdd() throws Exception { assertEquals("-1.0+2.0i",a.ComplexAdd(b).toString()); } @Test public void testComplexSub() throws Exception { assertEquals("1.0+4.0i", a.ComplexSub(b).toString()); } @Test public void testComplexMulti() throws Exception { assertEquals("3.0 -3.0i", a.ComplexMulti(b).toString()); } @Test public void testComlexDiv() throws Exception { assertEquals("-1.5 -1.5i", a.ComplexDiv(b).toString()); } }
测试结果:
第五个提交点
使用StarUML对实验二中的代码进行建模
更具老师提供的代码实例得出的UML图:
实验中第三个提交点MyDoc的UML图: