【问题标题】:Beanshell assertion throwing exception when comparing null values比较空值时Beanshell断言抛出异常
【发布时间】:2018-01-30 01:54:24
【问题描述】:

我有以下 beanshell 断言代码;当 value3 具有空值时,此代码似乎给出了异常。否则它工作正常。 我认为它必须与 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);
               }
}

【问题讨论】:

    标签: jmeter beanshell


    【解决方案1】:

    您的“抛出异常”节提供了非常丰富的信息,我可以立即给您的唯一建议是“修复您的代码”。

    如果您将代码括在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 文章以开始使用。

    【讨论】:

      【解决方案2】:

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

      1. value3 不为空,但不是有效的BigDecimal(例如空字符串)时
      2. new BigDecimal 抛出异常时
      3. value10 为空时
      4. setScale 抛出异常时
      5. value11 为空时

      所以我会像这样更改您的代码:

      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 都为null,那么剩下的杂耍就没有意义了。
      2. 如果 value3value4 中的任何一个为 null,但不是两者都为空(情况 1 涵盖),则无需计算,我们已经知道它们是不同的。
      3. 如果value3不能转换为BigDecimal,而我们知道value4不为空,脚本也可以失败退出
      4. 如果没有得到value11,则同比较失败

      所以这是一个优化的版本:

      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;
      }
      

      【讨论】:

      • 谢谢 Kiril,您的代码和解释非常有帮助!
      猜你喜欢
      • 1970-01-01
      • 2011-08-06
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 2013-01-16
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多