根据log拦截信息生成测试代码

最近碰到一个小需求, 需要根据调用拦截打印出的日志数据, 生成测试代码(主要是构造测试数据), 用于debug分析问题. 因为我们的调用数据比较复杂, 因此构造起来比较麻烦, 而根据log里面的调用信息直接生成测试数据, 相对来说会容易一些.
主要用groovy脚本来处理, 重点是字符串的解析, 而解析主要借助正则表达式.
感觉类似这种解析应该大同小异吧. 算是一个以后处理类似问题的一个参考:


String log = """ItemServiceImpl.save(arg1=1602962222, arg2=2018265146, arg3=ItemUpdateDO[...])"""
public void parse(String log){
// 对日志里面的()[]{}进行调整以便切分
String[] adjustedLog = adjustSeperator(log)

// 对日志中的无用参数信息进行清理
List<String> argList = processArgument(adjustedLog)

// 对括号进行处理
replaceBrace(argList)

// 输出最终结果
printResult(argList)
}

private String[] adjustSeperator(String log) {
String replacedResult = "";
log.eachLine { replacedResult += it }
// 在"{}[]()"前后加","以便后面切分
replacedResult = (replacedResult =~ /\(/).replaceAll("(,")
replacedResult = (replacedResult =~ /\)/).replaceAll(",),")
replacedResult = (replacedResult =~ /\{/).replaceAll("{,")
replacedResult = (replacedResult =~ /\}/).replaceAll(",},")
replacedResult = (replacedResult =~ /\[/).replaceAll("[,")
replacedResult = (replacedResult =~ /\]/).replaceAll(",],")

return replacedResult.split(",");
}

private List<String> processArgument(String[] fulls) {
List<String> argList = []
fulls.each{
// 去掉空值
if (it.equals("") || it ==~/.+=$/ || it ==~ /.*=null$/) {
return;
}
// 去掉arg1, arg2...
def arg = (it =~/arg[0-9]+=/).replaceAll("")

// 将=替换成:
arg = (arg =~ /=/).replaceAll(":")

// 将{}替换成[]
arg = (arg =~ /\{/).replaceAll("[")
arg = (arg =~ /\}/).replaceAll("]")

argList << arg
}

return argList
}

void replaceBrace(List<String> argList) {
int recursiveLevel = 0; // 递归次数
for(int i = 0; i <argList.size(); i++ ) {
String arg = argList[i];
if (argList[i] ==~ /.*:*[a-zA-Z]+\[$/) {
def matcher = (argList[i] =~ /([a-zA-Z]+)(\[)$/)
String className = matcher[0][1];
argList[i] = matcher.replaceAll(" new ${className}(")
continue
}

// 检查内部是否还有类定义
if (argList[i] ==~ /.*\[$/) {
recursiveLevel ++
continue
}

if (argList[i].equals("]")) {
if (recursiveLevel==0) {
argList[i] = ")"
}else {
recursiveLevel--
}
}
}
}

private printResult(List argList) {
// 要转换为String的属性列表
List stringValueList = ["title", "pictUrl", "city", "prov", "lang", "sourceIp"]
// 要去掉的属性列表
List deleteFieldList = ["isCardCode", "isSupplier", "updateFeatureCc"]
// 要替换的属性列表
Map replaceFieldMap = [
clientAppName:{String[] pair ->
return "${pair[0]}:ClientAppName.${pair[1].toUpperCase()}"
},
descriptionLength:{String[] pair ->
def len = new Integer(pair[1])
return """description:\"${"A".center(len, 'A')}\""""
}]

for(int i = 0; i < argList.size(); i ++) {
def pair = argList[i].split(":")

if (pair?.length == 2) {

if (deleteFieldList.contains(pair[0])) {
continue;
}

if (replaceFieldMap.keySet().contains(pair[0])) {
argList[i] = replaceFieldMap[pair[0]].call(pair)
}else {
// 凡是数字都转换成long类型
if (NumberUtils.isDigits(pair[1])) {
argList[i] = "${pair[0]}:${pair[1]}L"
}

if (stringValueList.contains(pair[0])) {
argList[i] = """${pair[0]}:\"${pair[1]}\""""
}
}
}else if (pair?.length == 1) {
if (NumberUtils.isDigits(pair[0])) {
argList[i] = "${pair[0]}L"
}
}

// 对class进行处理
if (i == 0) {
pair = argList[i].split(/\./)
if (pair?.length == 2) {
pair[0] = pair[0].replaceAll(/(^Default)|(Impl$)/, "")
pair[0] = pair[0].replaceAll(/^./){ it.toLowerCase() }
argList[i] = """${pair[0]}.${pair[1]}"""
}
}

if (i == 0
|| i == (argList.size()-1)
|| i == (argList.size()-2)
|| argList[i] ==~ /.*\($/
|| argList[i] ==~ /.*\[$/
|| argList[i] ==~ /.*\{$/
) {
println argList[i]
}else {
println "${argList[i]},"
}
}
}

// 得到的测试结果
@Test void parsed() {
itemService.save(
1602962222L,
2018265146,
new ItemUpdateDO(
description:"AAAAAAAAAAAAAAAAAAAA",
title:"123455666",...,
)
)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值