【软件测试】考虑闰年问题中的非法输入

  • 问题提出
    • 在上一篇中提到了闰年问题的实现以及测试,但是在上篇中并没有提及输入框中如果输入非法输入会发生什么问题
    • 观察如下,当我们在输入框中输入"ab"时:

    会出现下面java.lang.NumberFormatException:

java.lang.NumberFormatException: For input string: "ab"
    at java.lang.NumberFormatException.forInputString(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at java.lang.Integer.parseInt(Unknown Source)
    at task$Listener.handle(task.java:48)
    at task$Listener.handle(task.java:1)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Node.fireEvent(Unknown Source)
    at javafx.scene.control.Button.fire(Unknown Source)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
    at com.sun.javafx.scene.control.skin.SkinBase$4.handle(Unknown Source)
    at com.sun.javafx.scene.control.skin.SkinBase$4.handle(Unknown Source)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
    at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
    at javafx.event.Event.fireEvent(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.process(Unknown Source)
    at javafx.scene.Scene$MouseHandler.access$1900(Unknown Source)
    at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
    at com.sun.glass.ui.View.notifyMouse(Unknown Source)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
    at com.sun.glass.ui.win.WinApplication$3$1.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
  • 问题探索
    • 观察上一篇闰年问题的代码实现部分:
      • 闰年判定函数的实现
        private boolean isLeap( int year ) {
          if( year % 4 != 0 ) {
               return false;
            }
            else if( year % 100 != 0 ) {
               return true;
            }
            else if( year % 400 != 0 ) {
               return false;
            }
            else {
               return true;
            }
        }
      • 闰年函数的调用
        if( isLeap( Integer.parseInt( str ) ) ) {
            inf = "输入年份为闰年";
        }
        else {
            inf = "输入年份非闰年";
        }

        可以发现会出现这个问题是因为Integer.parseInt()这个函数

  • 问题分析
    • 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常,说明作为参数的字符串有问题
    • Integer.parseInt()函数
      • public static int parseInt(String s) throws NumberFormatException
      • 将字符串参数作为带符号十进制整数来分析。除过第一个字符为 ASCII 字符中减号 '-' 表示的负数,字符串中的字符都必须是十进制数。
      • 参数: s字符串
      • 返回值: 十进制表示的整数
      • 抛出: NumberFormatException (若该字符串不包含一个可分析的整数)
  • 改进
    • 加入异常处理
    1. import javax.swing.JOptionPane;
      
      import javafx.application.Application;
      import javafx.event.ActionEvent;
      import javafx.event.EventHandler;
      import javafx.geometry.Pos;
      import javafx.scene.Scene;
      import javafx.scene.control.Button;
      import javafx.scene.control.Label;
      import javafx.scene.control.TextField;
      import javafx.scene.layout.HBox;
      import javafx.stage.Stage;
      
      
      public class task extends Application {
      
          public static void main(String[] args) {
              // TODO Auto-generated method stub
              task.launch( args );
          }
          
          private TextField textfield = new TextField();
          
          @Override
          public void start(Stage arg0) throws Exception {
              // TODO Auto-generated method stub
              arg0.setTitle( "Testing" );
              
              HBox hbox = new HBox( 8 );
              textfield.setPrefColumnCount( 25 );
              hbox.setAlignment( Pos.CENTER_LEFT );
              Button btn = new Button();
              btn.setText( "提交" );
              btn.setOnAction( new Listener() );
              hbox.getChildren().addAll( new Label( "  请输入年份: "), textfield, btn );
              
              arg0.setScene( new Scene( hbox, 460, 50 ));
              arg0.show();
          }
          
          public class Listener implements EventHandler<ActionEvent> {
      
              @Override
              public void handle(ActionEvent arg0) {
                  // TODO Auto-generated method stub
                  String str = textfield.getText();
                  String inf = "";
                  
                  try{
                      if( isLeap( Integer.parseInt( str ) ) ) {
                          inf = "输入年份为闰年";
                      }
                      else {
                          inf = "输入年份非闰年";
                      }
                  }
                  catch (Exception e){
                      inf = "输入不合法";
                  }
                  
                  JOptionPane.showMessageDialog( null, inf, "information", 
                          JOptionPane.INFORMATION_MESSAGE );
              }
          }
          
          private boolean isLeap( int year ) {
              if( year % 4 != 0 ) {
                  return false;
              }
              else if( year % 100 != 0 ) {
                  return true;
              }
              else if( year % 400 != 0 ) {
                  return false;
              }
              else {
                  return true;
              }
          }
      }
  • 测试用例
编号 输入 预测输出
1 1963 输入年份非闰年
2 1964 输入年份为闰年
3 1900 输入年份非闰年
4 2000 输入年份为闰年
5 "" 输入不合法
6 "ab;d" 输入不合法

 

  • 测试结果

                      

  • JAVA中int,String的类型转换
    • int -> String
      • i = Integer.parseInt(s);
        • public static int parseInt(String s) throws NumberFormatException
        • 参数: 字符串s
        • 返回值: 十进制整数
        • 抛出: NumberFormatException
        • 直接使用静态方法,不会产生多余的对象,但会抛出异常
      • i = Integer.valueOf(s).intValue();
        • public static Integer valueOf(String s) throws NumberFormatException
        • 参数: 字符串s
        • 返回值: Integer对象
        • 抛出:NumberFormatException
        • 会抛出异常同时会多产生一个对象
    • String -> int
      • s = i + ""; 
        • 会产生两个String对象
      • s = String.valueof(i);
        • 直接使用String类的静态方法,之产生一个对象
原文地址:https://www.cnblogs.com/tju-crab/p/4394998.html