LISP:基于大语言模型的库API输入空间划分测试技术
本文完整解析ICSE’25论文提出的创新测试工具LISP,通过大语言模型实现智能化的API测试
什么是LISP?
LISP(LLM based Input Space Partitioning)是一项突破性的软件测试技术。它能利用大语言模型(LLM)深入理解库API的代码逻辑,并基于这种理解自动完成输入空间的智能划分。简单来说,它让AI像专业测试工程师一样分析代码,自动生成高质量的测试用例。
技术亮点
- 
🧠 代码理解能力:LLM直接分析API源代码  - 
📊 智能分区策略:基于代码语义划分输入空间  - 
💡 常识知识融合:结合通用领域知识优化测试  - 
🏆 学术认可:入选软件工程顶会ICSE 2025  

项目已通过ACM科研复现认证
环境配置指南(手把手安装)
系统要求
| 组件 | 要求 | 
|---|---|
| 操作系统 | Ubuntu 20.04/22.04 (x86架构) | 
| 内存 | ≥4 GB RAM | 
| Java | JDK 11+ | 
| Python | 3.10+ | 
| 构建工具 | Maven 3.6+ | 
安装四步曲
- 
安装Java依赖
进入llm-JQF目录执行:mvn install -DskipTests - 
配置API密钥
在llm-JQF目录运行:sh set-key.sh -k <Your_API_Key> -b https://api.openai.com/v1💰 成本提示:完整运行约需$40的OpenAI token费用
 - 
安装Python依赖
进入llm-seed-generator目录执行:pip3 install -r requirements.txt - 
准备测试API
预置2205个API方法签名位于:LISP/llm-JQF/signs/ ├── commons-lang3 ├── guava └── ... 
实战操作手册
核心工具
主执行文件位于:./llm-JQF/bin/jqf-llm
关键参数说明:
-i  # 启用覆盖率统计
-o  # 输出覆盖率结果
-l  # 指定签名文件(批量测试)
-s  # 实验模式选择:
    #   cg → LISP-CG模式
    #   skipUnder → 消融实验1
    #   skipEP → 消融实验2
    #   basic → LLM基线测试
单API测试示范
测试Guava库的Longs.min方法:
bin/jqf-llm -i -o "com.google.guava:guava:32.1-jre" \
"com.google.common.primitives.Longs.min(long[])"
成功输出示例:
Semantic Fuzzing with LLM
--------------------------
Test signature: org.apache.commons.lang3.ArrayUtils.addAll(boolean[],boolean[])
Elapsed time: 3s
Number of executions: 4
Valid inputs: 4 (100.00%)
Unique failures: 0
API Coverage: 11 branches (100.00% of 11)
Total Coverage: 16 branches (100.00% of 16)
批量测试流程
注意:文件中所有API必须属于同一库
bin/jqf-llm -i -o -l signs/guava -s cg \
"com.google.guava:guava:32.1.2-jre"
结果深度解析
结果目录结构
result/
├── commons-lang3_cg_1737620727667.json  # 概要报告
└── details/
    ├── commons-lang3/
    │   ├── cg/
    │   │   ├── ArrayUtils.addAll(...)0/
    │   │   │   ├── coverage_hash    # 覆盖路径哈希
    │   │   │   ├── detail.json      # 详细数据
    │   │   │   ├── graph.json       # 方法调用图
    │   │   │   ├── input_generator  # LLM生成的输入
    │   │   │   ├── llm_output.log   # LLM交互日志
    │   │   │   └── RunCode.java     # 测试用例代码
关键数据文件说明
1. 概要报告(JSON格式)
{
  "coverage":1.0,             // 覆盖率
  "coveredEdge":11,           // 覆盖分支数
  "generatedInputsNum":6,     // 生成输入总数
  "inputToken":9449,          // 输入token消耗
  "outputToken":969,          // 输出token消耗
  "runTime":27950,            // 运行时间(ms)
  "successAPINum":1,          // 成功测试API数
  "totalEdge":11,             // 总分支数
  "unexpectedBehaviorNum":0   // 异常行为数
}
2. 详细数据(detail.json)
包含方法级别的:
- 
分支覆盖详情  - 
执行路径记录  - 
异常行为日志  - 
token消耗明细  
实验评估方法论
RQ1:代码覆盖能力
- 
评估指标:分支覆盖率  - 
数据源: - 
概要报告的 coverage字段 - 
detail.json中的分支覆盖详情  
 - 
 - 
分析重点:LISP与传统方法的覆盖率对比  
RQ2:错误检测能力
- 
评估指标:异常行为数量  - 
数据源: - 
概要报告的 unexpectedBehaviorNum - 
detail.json中的异常堆栈信息  
 - 
 - 
分析重点:检测到的边界条件错误  
RQ3:执行成本分析
- 
核心指标: - 
Token消耗(inputToken/outputToken)  - 
执行时间(runTime)  
 - 
 - 
优化方向:降低LLM交互成本  
RQ4:消融实验设计
| 模式参数 | 测试内容 | 
|---|---|
| -s cg | 完整LISP-CG | 
| -s skipUnder | 消融实验1 (ISP+OI) | 
| -s skipEP | 消融实验2 (TDA+OI) | 
| -s basic | LLM基线方法 | 
技术问答(FAQ)
Q1:为什么需要4GB内存?
A:LLM推理和代码分析需要较大内存空间,实测低于4GB会导致OOM错误
Q2:如何查看具体的测试输入?
A:在details/<库名>/<模式>/<方法名>/input_generator文件中查看LLM生成的原始输入
Q3:token成本如何预估?
A:参考公式:
总成本 ≈ (inputToken/1000)×$0.01 + (outputToken/1000)×$0.03
Q4:能测试私有方法吗?
A:目前仅支持public API,私有方法需通过公有接口间接测试
Q5:结果中的coverage_hash有什么用?
A:用于快速比对不同运行的覆盖路径差异,避免重复计算
结语:测试技术的智能化演进
LISP代表了API测试领域的范式转变:
- 
人机协作:结合LLM的代码理解与人类测试经验  - 
动态分区:基于代码语义的智能输入空间划分  - 
知识融合:将通用领域知识注入测试过程  - 
量化评估:通过四维度研究问题系统验证效果  

