Beanshell断言在比较空值时抛出异常

时间:2018-01-29 16:38:07

标签: jmeter beanshell

我有下面的beanshell声明代码;当value3具有null值时,此代码似乎给出了异常。否则它工作正常。 我认为它必须与BigDecimal做一些事情,但我不知道如何处理空值。有人可以帮我吗?

import java.math.BigDecimal;
import java.math.RoundingMode; 
String value3 = vars.get("budget_api");
String value4 = vars.get("c_budget_1");

if(value3 != null) {
BigDecimal value10 = new BigDecimal(value3);
String value11 = value10.setScale(8, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();    
    if(!value11.equals(value4)) {
                   Failure = true;
                              FailureMessage = ":  budget doesnt match, api: "+ value11 + "   db: "+ value4; 
                              print(FailureMessage);
               }
} 
else {
    if(value4 != null) {
                   Failure = true;
                              FailureMessage = ":  budget doesnt match, api: "+ value3 + "   db: "+ value4; 
                              print(FailureMessage);
               }
}

2 个答案:

答案 0 :(得分:0)

你的"抛出异常" stanza是非常有用的,我可以立即给你的唯一建议是#34;修复你的代码"。

如果您将代码包含在try block中,则可以获得更全面的错误消息:

try {
    //your code here
}
catch (Throwable ex) {
    log.error("Beanshell failure", ex);
    throw ex;
}

一旦完成,您将能够看到"正常"在 jmeter.log 文件中的堆栈跟踪,您应该能够从中找出问题的根本原因。如果没有 - 至少你可以将它添加到你的问题中,以便社区可以提出建议。

我的期望是您的budget_api变量值不是null,而是无法转换为BigDecimal的值。

另外考虑转移到JSR223 Assertion and Groovy language,因为Beanshell性能在高负载时可能是个大问号,请查看Scripting JMeter Assertions in Groovy - A Tutorial文章以开始使用。

答案 1 :(得分:0)

我在这里看到一些可能的失败:

  1. value3不为空,但不是有效BigDecimal时(例如空字符串)
  2. new BigDecimal抛出异常时
  3. value10为空时
  4. setScale抛出异常时
  5. value11为空时
  6. 所以我会改变你的代码:

    import java.math.BigDecimal;
    import java.math.RoundingMode; 
    
    String value3 = vars.get("budget_api");
    String value4 = vars.get("c_budget_1");
    
    BigDecimal value10 = null;
    String value11 = null;
    
    if(value3 != null) {
        try {
            value10 = new BigDecimal(value3); // addresses issues 1 and 2
        } catch(NumberFormatException e) {
            // whatever you want to do if conversion failed; 
            // value 10 will remain null in this case
        }
    }
    
    if(value10 != null) { // addresses issue 3
    
        try { // addresses issue 4
            value11 = value10.setScale(8, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
        } catch(ArithmeticException e) {
            // value 11 will remain null
        }
    }
    
    if(value11 != null) { // addresses issue 5
    
        if(!value11.equals(value4)) {
            Failure = true;
            FailureMessage = ":  budget doesnt match, api: "+ value11 + "   db: "+ value4; 
            print(FailureMessage);
        }
    } 
    else {
        if(value4 != null) {
            Failure = true;
            FailureMessage = ":  budget doesnt match, api: "+ value3 + "   db: "+ value4; 
            print(FailureMessage);
        }
    }
    

    现在,如果您查看此代码,您可能会注意到一些优化,这可以使它更快,更易读。它不会导致更短的代码,但它会在发现比较失败时立即退出脚本。

    1. 如果value4value3都为空,那么其余的杂耍就没有意义了。
    2. 如果value3为空,或value4,但不是两者(案例1都涵盖了这一点),没有计算点,我们已经知道它们是不同的。
    3. 如果value3无法转换为BigDecimal,虽然我们知道value4不为null,但脚本也会因失败而退出
    4. 如果未获得value11,则与比较失败相同
    5. 所以这是一个优化版本:

      import java.math.BigDecimal;
      import java.math.RoundingMode; 
      
      String value3 = vars.get("budget_api");
      String value4 = vars.get("c_budget_1");
      
      BigDecimal value10 = null;
      String value11 = null;
      
      if(value3 == null && value4 == null) { // optimization 1
          return;
      }
      
      if(value3 == null || value4 == null) { // optimization 2
          Failure = true;
          FailureMessage = ":  budget doesnt match, api: "+ value3 + "   db: "+ value4; 
          print(FailureMessage);
          return; 
      }
      
      // no longer need to check if value3 is null, since previous checks would make sure script exits if it is
      try {
          value10 = new BigDecimal(value3);
      } catch(NumberFormatException e) { 
          // value10 remains null
      }
      
      if(value10 == null) { // optimization 3
          Failure = true;
          FailureMessage = ":  budget doesnt match, api: "+ value3 + "   db: "+ value4; 
          print(FailureMessage);
          return;
      }
      
      // no longer need to check if value10 is null, since previous checks would make sure script exits if it is
      try {
          value11 = value10.setScale(8, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
      } catch(ArithmeticException e) {
          // value11 will remain null
      }
      
      if(value11 == null || !value11.equals(value4)) { // optimization 4
          Failure = true;
          FailureMessage = ":  budget doesnt match, api: "+ value3 + "   db: "+ value4; 
          print(FailureMessage);
          return;
      }