Page 48 - 《软件学报》2025年第4期
P. 48

1454                                                       软件学报  2025  年第  36  卷第  4  期


                 4.2.4.2    评价指标
                    基于上述人工实验的结果, 本文使用以下             3  个问题来评估方法的易用性.
                    ● RQ6-1: 本文检测方法能否帮助定位造成兼容性问题的代码元素? 即本文方法能否帮助开发者定位不兼容
                 的参数、语句、异常、返回值等代码元素. 具体来说, 本文使用问题                    1  的打分进行评估.
                    ● RQ6-2: 本文检测方法能否帮助理解造成兼容性问题的产生原因? 一方面, 本文使用                      API 在有检测方法结果
                 以及没有检测方法结果的两种情况下, 被标注正确率的对比进行评估. 这里的标注正确率指对某一不兼容                                   API ,
                 10  名参与者中标注正确的占比. 另一方面, 本文使用问题              2  的打分进行评估.
                    ● RQ6-3: 本文检测方法能否帮助缩短发现兼容性问题的所需时间? 具体来说, 本文使用                       API 在有检测方法结
                 果以及没有检测方法结果的两种情况下, 被标注所需时间的对比进行评估. 这里的标注时间指对某一不兼容                                  API ,
                 10    名参与者中标注时间的平均值.
                 4.3   有效性评估结果   (RQ3)
                    表  8  展示了本文提出的方法在        flask  库和  pandas 库数据集上的有效性结果. 总的来看, 方法对兼容性问题产
                 生原因的宏平均精准率和宏平均召回率分别达到了                  92.87%  和  93.79%. 从更细粒度的角度看, 除输出不同的返回
                 值  (CI7) 的精准率较低, 其余类别的精准率和召回率均不低于               75%. 可见, 本文方法在分析       Python  第三方库  API
                 兼容性问题产生原因的有效性.

                                       表 8 方法在   flask  库和  pandas 库数据集上的有效性结果

                     序号         兼容性问题产生原因              不兼容API数量 (个)          精准率 (%)         召回率 (%)
                     CI1           参数的增删                     26                100             100
                     CI2        关键字参数的键增删                    1                 100             100
                     CI3           参数的重命名                    3                 100             100
                     CI4         参数默认值的改变                    11                100             100
                     CI5          参数的范围改变                    45                93.33           95.45
                     CI6          抛出不同的异常                    6                 100             83.33
                     CI7         输出不同的返回值                    31                56.76           77.78
                                          宏平均
                                                                                               93.79
                                                                               92.87

                    本检测方法发生误报的原因主要有两个.
                    (1) 未充分利用   API 外部代码的语义信息. 对于        API 外部代码, 本文方法仅分析同一文件中的全局语句, 并且
                 分析时仅关注与      API 内部完全一致的全局语句, 将这些语句过滤为良性语义变化                   (算法  3  第  2  行), 而没有涉及过
                 程间分析. 然而, API 外部代码中有丰富的语义信息, 如声明和操作全局变量、导入模块中的特定变量、调用外部
                 API 等. 本文方法忽略了这些外部代码的语义信息, 这导致方法的错误识别, 如例                     13  所示.
                    例  13: 示例代码  8  中, 第  4  行类型判断  isinstance 中的  text_type 被替换为  str. 而  v1  版本中  text_type 通过第  1
                 行的  from-import 语句导入, _compat.py  文件中语句‘text_type = str’使  text_type 被赋值为  str. 因此, 该  API 本质上
                 未发生修改. 然而, 算法      1 (第  18–21  行) 错误地认为第  8  行  raise 语句的触发条件发生改变, 进而错误地认为参数
                 rv  的输入范围发生改变, 即错误地认为该          API 存在参数的范围改变       (CI5).
                 示例代码   8. 未充分利用    API 外部代码的语义信息所导致的错误识别.

                 # 版本变更: flask1.1.4 → flask2.0.0
                 1    –   from ._compat import text_type
                 2       def make_response(self, rv):
                 3       if (not isinstance(rv, self.response_class)):
                 4    –    if isinstance(rv, (text_type, bytes, bytearray)):
                 5    +    if isinstance(rv, (str, bytes, bytearray)):
   43   44   45   46   47   48   49   50   51   52   53