zoukankan      html  css  js  c++  java
  • 0328复利软件4.0测试

    一、项目简介

    项目名称:复利计算软件
      版  本  :4.0
    版本类型:java
    使用工具:eclipse+swing插件
    主要功能:本金,利率,年数及期待值的相互转换以及存款的实现
      备  注  :本代码仅作为学习交流用途,目前不适宜发布,更多功能及后续开发请关注本博客园

     

    二、新的功能需求

       以商业标准来要求数据保证万无一失

     

    三、实验代码

        本代码多处使用try catch语句保护数据。在此仅使用一个例子测试说明

         

     

        源代码:

     

        else if (b4.getText().equals("") && b1.getText() != null
                    && b3.getText() != null && b2.getText() != null) // 求期望值
            {
                try {
                    rate = Double.parseDouble(b2.getText());
                    if (rate < 0) {
                        JOptionPane.showMessageDialog(null, "利率输入有误,请重新输入数字");
                        rate = 0;
                    }
                    n = Integer.parseInt(b3.getText());
                    if (n < 0) {
                        JOptionPane.showMessageDialog(null, "年份输入有误,请重新输入数字");
                        n = 0;
                    }
                    principal = Double.parseDouble(b1.getText()); // b1本金
                    if (principal < 0) {
                        JOptionPane.showMessageDialog(null, "本金输入有误,请重新输入数字");
                        rate = 0;
                    }
                } catch (Exception e2) {
                    // TODO: handle exception
                    JOptionPane.showMessageDialog(null, "数据输入有误,请重新输入数字");
                }
    
                double tempprincipal = principal;
                result = JOptionPane.showConfirmDialog(null, "是否每年添加本金");
                if (result == JOptionPane.YES_OPTION) {
    //                while (year <= n) {
    //                    amount = principal * Math.pow(1 + rate, year)
    //                            + tempprincipal;
    //                    output += String.valueOf(year) + "			"
    //                            + currencyformatter.format(amount) + "
    ";
    //                    year = year + 1;
    //                }
                    amount=CalculateA(year,n,principal,rate,tempprincipal);
                    System.out.println("CalculateA(year,n,principal,rate,tempprincipal)"+year+n+principal+rate+tempprincipal);
                    output += String.valueOf(year) + "			"
                            + currencyformatter.format(amount) + "
    ";
                } else {
                    while (year <= n) {
                        amount = principal * Math.pow(1 + rate, year);
                        output += String.valueOf(year) + "			"
                                + currencyformatter.format(amount) + "
    ";
                        year = year + 1;
                    }
                }
    
                text.setText(output);
                int Isinfo = JOptionPane.showConfirmDialog(null, "是否要进行投资");
                if (Isinfo == JOptionPane.YES_OPTION) {
                    a[input] = principal;
    
                    b[input] = amount;
                    input += 1;
    
                }

     

    将上面的注释内容分离出来写成一个函数,如下:

    public double CalculateA(int years2,int n2,double principal2,double rate2,double tempprincipal2){
            double amount2 = 0;
            while (years2 <= n2) {
                amount2 = principal2 * Math.pow(1 + rate2, years2)
                        + tempprincipal2;
                
                years2 = years2 + 1;
            }
            return amount2;
        }
        

      注意:类放在Text包中

          类名用XXXText结尾

          方法用textMethod命名

    这样的方式能让我们保证一目了然,养成一个好习惯

    测试类的代码如下:

    public class Fulitext {
    
    
        @Test
        public void testFuli() {
            double z=new Fuli().CalculateA(1, 3, 100, 0.03, 100);
            boolean flag=0.0==z-209.2727;
            assertEquals(true, flag);
        }
    
    }

     

     

     

     

     我们可以发现,测试类报错了,原因是:z是一个double型的函数,且输出为209.2727.由此可知这是运行错误,是数据的问题。于是这样修改:

    可以看到,这样它没报错了。测试通过。

    四、相关知识扩展

       

    Assert是判断对不对。

     

    assertArrayEquals(message,expecteds, actuals);

    验证两个数组expectedsactuals是否相等。若相等则断言成功;若不相等则断言失败,提供message时输出message消息。当expectedsactuals均为null,assertArrayEquals认为二者相等

    static public void assertEquals(String message, Object expected, Object actual)

    assertEquals验证expectedactual是否相等。若相等则断言成功;若不相等则断言失败,提供message时输出message消息。当expectedactual均为null时,assertEquals认为二者相等。

    assertTrue(String message, boolean condition)

    assertTrue验证condition是否为true。若为true则断言成功;若为false则断言失败,提供message时输出message消息。

    assertFalse(String message, boolean condition)

    assertfalse验证condition是否为false。若为false则断言成功;若为true则断言失败,提供message时输出message消息。

    fail(String message)

    fail会使测试立即失败,提供message时输出message消息。

    assertNull(String message, Object object)

    assertNull验证对象object是否为空。若为空,则断言成功;若非空,则断言失败,提供message时输出message消息。

    assertSame(String message, Object expected, Object actual)

    assertSame验证expectedactual所引用的是否是同一对象。若相同,则断言成功;若不同,则断言失败,提供message时输出message消息

     assertNotSame(String message, Object unexpected, Object actual)

    assertSame验证unexpectedactual所引用的是否是不同对象。若不同,则断言成功;若相同,则断言失败,提供message时输出message消息。

    在谷歌下载1.2 FULL hamcrest包,把core和Library 1.2 的jar文件导入可使用hamcrest的Matchers,但是要注意,在导入的时候一定要使用静态的,因为只有静态的才能使用里面的静态方法和静态变量,在JUnit4.7的jar中有更强大的assertThat,它几乎包括了之前所有的方法。

     assertThat有以下方法:

    assertThat(n, allOf( greaterThan(8), lessThan(16) ) )    //表示n这个数满足右边所有的条件,这里举个例子大于8,小于16

    assertThat( n, anyOf( greaterThan(16), lessThan(8) ) )  //表示n这个数满足任意一个条件就可以了  例如大于16或者小于8

    assertThat( n, anything() );              //无论n是一个什么条件都可以成立的数

    assertThat(str, is/not ("****") )       //字符串是不是等于****

    assertThat(str, containsString( "***" ) );        //字符串是不是包含了***

    assertThat( str,  startsWith/endsWith( "***" ) );       //字符串是不是以****开始/结尾

    其他更多功能便不再一一列举了。

    五、阅读更多案例

    代码部分:

     

    public static String wordFormat4DB(String name){
           Pattern p = Pattern.compile("[A-Z]");
           Matcher m = p.matcher(name);
           StringBuffer sb = new StringBuffer();
    
           while(m.find()){
                 m.appendReplacement(sb, "_"+m.group());
           }
              return m.appendTail(sb).toString().toLowerCase();
         }
    }
    

     

      测试代码:

    public class TestWordDealUtil {
    //测试wordFormat4DB正常运行的情况
    @Test public void wordFormat4DBNormal(){
    String target = "employeeInfo";
    String result = WordDealUtil.wordFormat4DB(target);
    
    assertEquals("employee_info", result);
    }
    //测试null时的处理情况
    @Test public void wordFormat4DBNull(){
    String target = null;
    String result = WordDealUtil.wordFormat4DB(target);
    
    assertNull(result);
    }
    
    //测试空字符串的处理情况
    @Test public void wordFormat4DBEmpty(){
    String target = "";
    String result = WordDealUtil.wordFormat4DB(target);
    
    assertEquals("", result);
    }
    //测试当首字母大写时的情况
    @Test public void wordFormat4DBegin(){
    String target = "EmployeeInfo";
    String result = WordDealUtil.wordFormat4DB(target);
    
    assertEquals("employee_info", result);
    }
    
    //测试当尾字母为大写时的情况
    @Test public void wordFormat4DBEnd(){
    String target = "employeeInfoA";
    String result = WordDealUtil.wordFormat4DB(target);
    
    assertEquals("employee_info_a", result);
    }
    
    //测试多个相连字母大写时的情况
    @Test public void wordFormat4DBTogether(){
    String target = "employeeAInfo";
    String result = WordDealUtil.wordFormat4DB(target);
    
    assertEquals("employee_a_info", result);
    }
    }

    六、预期异常处理

    1、使用@Test(expected…)

    expected允许设置一个Throwable的子类,可以使用canVote()方法验证上面抛出预期的异常

    可以使用一个类,可以new一个对象,可以runnable

    例如:

    @Test(expected = IllegalArgumentException.class)
    public void canVote_throws_IllegalArgumentException_for_zero_age() {
          Student student = new Student();
          student.canVote(0);
    }

    2、ExpectedException

    使用JUnit框架中的ExpectedException类,需要声明ExpectedException异常。

    例如:

    @Rule
    public ExpectedException thrown= ExpectedException.none();
    @Test
    public void canVote_throws_IllegalArgumentException_for_zero_age() {
        Student student = new Student();
        thrown.expect(IllegalArgumentException.class);
        student.canVote(0);
    }

    这样就不用声明

    expect(RuntimeException.class, “Expected exception message”)
    

      

    thrown.expect(IllegalArgumentException.class, “age should be +ve”);

    3、Try/catch with assert/fail

    我比较喜欢使用这种方式,也在我的代码里有多处应用

    public void Dcalculate() {
    
            double principal = 0;
            double amount = 0;
            double rate = 0;
            int n = 0;
            NumberFormat currencyformatter = NumberFormat.getCurrencyInstance(); // 字符串转化为数字
            String output = "年" + "/" + "复利存款";
            int year = 1;
            int result;
    
            if (b1.getText().equals("") && b2.getText() != null
                    && b3.getText() != null && b4.getText() != null) { // 计算本金
    
                try {
                    rate = Double.parseDouble(b2.getText());
                    if (rate < 0) {
                        JOptionPane.showMessageDialog(null, "利率输入有误,请重新输入数字");
                        rate = 0;
                    }
                    n = Integer.parseInt(b3.getText());
                    if (n < 0) {
                        JOptionPane.showMessageDialog(null, "年份输入有误,请重新输入数字");
                        n = 0;
                    }
                    amount = Double.parseDouble(b4.getText());
                    if (amount < 0) {
                        JOptionPane.showMessageDialog(null, "期待值输入有误,请重新输入数字");
                        amount = 0;
                    }
                } catch (Exception e2) {
                    // TODO: handle exception
                    JOptionPane.showMessageDialog(null, "数据输入有误,请重新输入数字");
    
                }
    
                principal = 0;
                while (year <= n) {
                    principal = amount / (Math.pow(1 + rate, year));
                    year = year + 1;
                }
    
                output = "本金" + currencyformatter.format(principal) + "
    ";
                text.setText(output);
    
            }
    
            else if (b2.getText().equals("") && b1.getText() != null
                    && b3.getText() != null && b4.getText() != null) // 求利率
            {
                try {
                    principal = Double.parseDouble(b1.getText()); // b1本金
                    if (principal < 0) {
                        JOptionPane.showMessageDialog(null, "本金输入有误,请重新输入数字");
                        principal = 0;
                    }
                    n = Integer.parseInt(b3.getText()); // b3年份
                    if (n < 0) {
                        JOptionPane.showMessageDialog(null, "年份输入有误,请重新输入数字");
                        n = 0;
                    }
                    amount = Double.parseDouble(b4.getText()); // b4期望值
                    if (amount < 0) {
                        JOptionPane.showMessageDialog(null, "期待值输入有误,请重新输入数字");
                        amount = 0;
                    }
                } catch (Exception e2) {
                    // TODO: handle exception
                    JOptionPane.showMessageDialog(null, "数据输入有误,请重新输入数字");
                }
    
                rate = java.lang.StrictMath.pow(amount / principal, 1.0 / n) - 1;
                output = "利率" + rate + "
    ";
                text.setText(output);
            }
    
            else if (b3.getText().equals("") && b1.getText() != null
                    && b2.getText() != null && b4.getText() != null) // 求年份
            {
                try {
                    principal = Double.parseDouble(b1.getText()); // b1本金
                    if (principal < 0) {
                        JOptionPane.showMessageDialog(null, "本金输入有误,请重新输入数字");
                        principal = 0;
                    }
                    amount = Double.parseDouble(b4.getText()); // b4期望值
                    if (amount < 0) {
                        JOptionPane.showMessageDialog(null, "期待值输入有误,请重新输入数字");
                        amount = 0;
                    }
                    rate = Double.parseDouble(b2.getText());
                    if (rate < 0) {
                        JOptionPane.showMessageDialog(null, "利率输入有误,请重新输入数字");
                        rate = 0;
                    }
                } catch (Exception e2) {
                    // TODO: handle exception
                    JOptionPane.showMessageDialog(null, "数据输入有误,请重新输入数字");
                }
    
                double year2 = Math.log(amount / principal) / Math.log(1 + rate);
                output = "至少年数" + year2 + "
    ";
                text.setText(output);
            }
    
            else if (b4.getText().equals("") && b1.getText() != null
                    && b3.getText() != null && b2.getText() != null) // 求期望值
            {
                try {
                    rate = Double.parseDouble(b2.getText());
                    if (rate < 0) {
                        JOptionPane.showMessageDialog(null, "利率输入有误,请重新输入数字");
                        rate = 0;
                    }
                    n = Integer.parseInt(b3.getText());
                    if (n < 0) {
                        JOptionPane.showMessageDialog(null, "年份输入有误,请重新输入数字");
                        n = 0;
                    }
                    principal = Double.parseDouble(b1.getText()); // b1本金
                    if (principal < 0) {
                        JOptionPane.showMessageDialog(null, "本金输入有误,请重新输入数字");
                        rate = 0;
                    }
                } catch (Exception e2) {
                    // TODO: handle exception
                    JOptionPane.showMessageDialog(null, "数据输入有误,请重新输入数字");
                }
    
                double tempprincipal = principal;
                result = JOptionPane.showConfirmDialog(null, "是否每年添加本金");
                if (result == JOptionPane.YES_OPTION) {
    //                while (year <= n) {
    //                    amount = principal * Math.pow(1 + rate, year)
    //                            + tempprincipal;
    //                    output += String.valueOf(year) + "			"
    //                            + currencyformatter.format(amount) + "
    ";
    //                    year = year + 1;
    //                }
                    amount=CalculateA(year,n,principal,rate,tempprincipal);
                    System.out.println("CalculateA(year,n,principal,rate,tempprincipal)"+year+n+principal+rate+tempprincipal);
                    output += String.valueOf(year) + "			"
                            + currencyformatter.format(amount) + "
    ";
                } else {
                    while (year <= n) {
                        amount = principal * Math.pow(1 + rate, year);
                        output += String.valueOf(year) + "			"
                                + currencyformatter.format(amount) + "
    ";
                        year = year + 1;
                    }
                }
    
                text.setText(output);
                int Isinfo = JOptionPane.showConfirmDialog(null, "是否要进行投资");
                if (Isinfo == JOptionPane.YES_OPTION) {
                    a[input] = principal;
    
                    b[input] = amount;
                    input += 1;
    
                }
            } else if (b1.getText() != null && b4.getText() != null
                    && b3.getText() != null && b2.getText() != null) {
                JOptionPane.showMessageDialog(null, "请删除一个数据");
            } else {
                JOptionPane.showMessageDialog(null, "请增加数据");
            }
        }
        
        

    这样再使用JOptionpane。提示错误

    七、总结

    1、以后写代码尽量把模块分得清楚点方便进行测试

    2、多使用try catch语句包围保证程序正常运行

    3、写代码的要有意识地思考可能会出现哪些情况错误,单元测试不能完全保证无bug。

    4、在建立项目的时候要注意起到项目,要有创建包的习惯,把类和测试类分在不同的包,方法也要规范化,尽量,最好别用拼音。

    八、资源

    学习JUnit网站视频:http://www.sxt.cn/course/showdetail-10003-one.html

    github代码:https://github.com/hellolaona/text

    Junit测试代码参考网址:https://github.com/hellolaona/junitdemo

     

     

     

  • 相关阅读:
    栅格系统
    jq中文档的操作及正则的应用
    jq的简单操作
    jquery基础
    DOM&BOM
    布局和js的轮播图
    js中的事件
    js的高级操作
    js对页面的一些简单的操作
    第二章 ELKstack部署及配置
  • 原文地址:https://www.cnblogs.com/15linzhijie/p/5330404.html
Copyright © 2011-2022 走看看