操作数是 TestHub 数据的最小操作单元,

我们用 FormulaNode 表示一个的操作数 - TestHub 中内置了 5 种基础操作数

  • DataNode 表示固定值,是有配置人员手动指定的, 例如:xxxx
  • PathNode 表示变量值,可以基于 jsonPath 从决策上下文中获取指定的变量值,标识为${xxx.yyy}
  • FuncNode 表示方法型函数的调用,标识为%{方法名(形参 1:操作数,......)}
  • ArithmeticNode 表示计算算数运算, 例如:1+2+3*4/5%3
  • MixNode 表示混合表达式

操作对象

后续介绍均以上下文中存在如下数据为前提

```xml copy { “store”: { “book”: [ { “category”: “reference”, “author”: “Nigel Rees”, “title”: “Sayings of the Century”, “price”: 8.95 }, { “category”: “fiction”, “author”: “Evelyn Waugh”, “title”: “Sword of Honour”, “price”: 12.99 }, { “category”: “fiction”, “author”: “Herman Melville”, “title”: “Moby Dick”, “isbn”: “0-553-21311-3”, “price”: 8.99 }, { “category”: “fiction”, “author”: “J. R. R. Tolkien”, “title”: “The Lord of the Rings”, “isbn”: “0-395-19395-8”, “price”: 22.99 } ], “bicycle”: { “color”: “red”, “price”: 19.95 } }, “expensive”: 2 }

  1. ## 语法
  2. ### 固定值-DataNode
  3. data="root"中的 我们写死的 root 其实就是 DataNode 类型的操作数
  4. ```xml copy
  5. <param code="password" name = "密码" dataType="STRING" data="root"/>
写法 例子
-1.0086 数字 -1.0086
{attr:{a:1},attr1:1} json 对象 {“attr”:{“a”:1},”attr1”:1}
[${expensive},1] 列表 操作对象的 expensive 做为第一个元素,1 是第二个元素 [2,1]

变量值-PathNode

::: warning PathNode 几乎支持了所有 jsonPath 的语法,但是我们不支持 $['store']['book'][0]['title'] 这种[]的写法 如果目前的语法满足不了你的测试过程,请于gitee仓库提 lssues,我们会优先支持。 jsonPath 语法学习 请参考 https://github.com/alibaba/fastjson/wiki/JSONPath :::

写法 例子
${expensive} 操作对象的 expensive 的值 2
${store.book.price} 操作对象的 store 的每一个 book 的 price 值 [8.95, 12.99, 8.99, 22.99]
${store.book[-1].author} 操作对象的 store 的最后一个 book 的 author J. R. R. Tolkien
${store.book[0:2].author} 操作对象的 store 的 0 到 2book 的 author Nigel Rees,Sword of Honour,Herman Melville
${store.book[?(isbn)]} 操作对象的 store 的 book 中 isbn 属性不等于空的 Herman Melville,J. R. R. Tolkien
${store.book[author='Nigel Rees'].title} 操作对象的 store 的 book 中 author 等于 Nigel Rees 的 book 的 title Sayings of the Century

内置方法-FuncNode

写法 例子
%{getNowTime()} 获取当前时间 看表
%{add(attr1:1,attr2:2)} 进行 1+2 ,key:val 的写法 3
%{add(1,2)} 进行 1+2 默认 key 为下标的写法 3

内置函数是我们基于 SPI 机制提供的扩展点之一,目前我们实现了这些内置函数

如果有不满足你的可以按照一下方式扩展

  1. 继承 FunctionHandler

```java copy package org.dromara.testhub.nsrule.core.executer.mode.base.function;

import com.alibaba.fastjson.JSONObject; import org.dromara.testhub.nsrule.core.executer.context.Context;

public interface FunctionHandler { String getName();

  1. Object execute(Context context, JSONObject data);

}

  1. 2. META-INF.services 路径下的 org.dromara.testhub.nsrule.core.executer.mode.base.function.FunctionHandler 配置的你扩展方法
  2. ### 算数运算-ArithmeticNode
  3. 是的我们支持了手写算数运算的表达式
  4. | 符号 | 作用 |
  5. | ---- | ------ |
  6. | + | |
  7. | - | |
  8. | `*` | |
  9. | / | |
  10. | % | 取余 |
  11. | () | 优先级 |
  12. | 写法 | 例子 | |
  13. | --------------- | ------------------- | --- |
  14. | `1+2+3*4/5%3` | 计算`1+2+3*4/5%3` | 5.4 |
  15. | `1+(2+3)*4/5%3` | 计算`1+(2+3)*4/5%3` | 2 |
  16. ### 混合表达式-MixNode
  17. 用户组合所有 FormulaNode 最终结果返回字符串
  18. | 写法 | 例子 | |
  19. | ------------------------------------------------ | ------------------------------------------- | ----------------------------------- |
  20. | `http:${expensive}:10010/server/workerHeartbeat` | 将操作对象的 expensive 的值替换后返回字符串 | http:2:10010/server/workerHeartbeat |
  21. ## 实践
  22. ![](/images/build/表达式.jpg)
  23. ```xml copy
  24. <?xml version="1.0" encoding="UTF-8"?>
  25. <rule code="RULE_0000000013" name="Formula操作数使用说明" model="flow" project="default">
  26. <actions>
  27. <action code="getData" name="操作数据" type="CONST" dataType="MAP">
  28. <bound>
  29. {"store":{"book":[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],"bicycle":{"color":"red","price":19.95}},"expensive":2}
  30. </bound>
  31. </action>
  32. </actions>
  33. <flows>
  34. <flow code="flow1">
  35. <execute code="stp1" name="获取基础操作数据" actionCode="getData"/>
  36. <execute code="stp2" name="固定值-DataNode" actionCode="check">
  37. <checkItem code="check1" name="固定值数字" msg="">
  38. <expression expressionType="relation" operationCode="eq" dataType="NUMBER" cover="-1.0086" threshold="-1.0086"/>
  39. </checkItem>
  40. <checkItem code="check2" name="固定值字符串" msg="">
  41. <expression expressionType="relation" operationCode="eq" dataType="STRING" cover="* 0/1 * * * ?" threshold="* 0/1 * * * ?"/>
  42. </checkItem>
  43. <checkItem code="check3" name="固定值列表" msg="">
  44. <expression expressionType="relation" operationCode="eq" dataType="NUMBER" coverComplex="1" cover="[${stp1.expensive},1]" thresholdComplex="1" threshold="[2,1]"/>
  45. </checkItem>
  46. </execute>
  47. <execute code="stp3" name="变量值-PathNode" actionCode="check">
  48. <checkItem code="check1" name="操作对象的 expensive 的值" msg="">
  49. <expression expressionType="relation" operationCode="eq" dataType="NUMBER" cover="${stp1.expensive}" threshold="2"/>
  50. </checkItem>
  51. <checkItem code="check2" name="操作对象的 store 的每一个 book 的 price 值" msg="">
  52. <expression expressionType="relation" operationCode="eq" dataType="STRING" coverComplex="1" cover="${stp1.store.book.price}" thresholdComplex="1" threshold="[8.95,12.99,8.99,22.99]"/>
  53. </checkItem>
  54. <checkItem code="check3" name="操作对象的 store 的最后一个 book 的 author" msg="">
  55. <expression expressionType="relation" operationCode="eq" dataType="STRING" cover="${stp1.store.book[-1].author}" threshold="J. R. R. Tolkien"/>
  56. </checkItem>
  57. <checkItem code="check4" name="操作对象的 store 的 0 到 2book 的 author" msg="">
  58. <expression expressionType="relation" operationCode="eq" dataType="STRING" coverComplex="1" cover="${stp1.store.book[0:2].author}" thresholdComplex="1" threshold="[Nigel Rees,Sword of Honour,Herman Melville]"/>
  59. </checkItem>
  60. <checkItem code="check5" name="操作对象的 store 的 book 中 isbn 属性不等于空的 的 author" msg="">
  61. <expression expressionType="relation" operationCode="eq" dataType="STRING" coverComplex="1" cover="${stp1.store.book[?(isbn)].author}" thresholdComplex="1" threshold="[Herman Melville,J. R. R. Tolkien]"/>
  62. </checkItem>
  63. <checkItem code="check6" name="操作对象的 store 的 book 中 author 等于 Nigel Rees 的 book 的 title" msg="">
  64. <expression expressionType="relation" operationCode="eq" dataType="STRING" cover="${stp1.store.book[author='Nigel Rees'].title}" threshold="Sayings of the Century"/>
  65. </checkItem>
  66. </execute>
  67. <execute code="stp4" name="内置方法-FuncNode" actionCode="check">
  68. <checkItem code="check1" name="参数key:val形式" msg="">
  69. <expression expressionType="relation" operationCode="eq" dataType="NUMBER" cover="%{add(attr1:1,attr2:2)}" threshold="3"/>
  70. </checkItem>
  71. <checkItem code="check2" name="参数,形式" msg="">
  72. <expression expressionType="relation" operationCode="eq" dataType="NUMBER" cover="%{add(1,2)}" threshold="3"/>
  73. </checkItem>
  74. </execute>
  75. <execute code="stp5" name="算数运算-ArithmeticNode" actionCode="check">
  76. <checkItem code="check1" name="计算1+2+3*4/5%3" msg="">
  77. <expression expressionType="relation" operationCode="eq" dataType="NUMBER" cover="1+2+3*4/5%3" threshold="5.4"/>
  78. </checkItem>
  79. <checkItem code="check2" name="计算1+(2+3)*4/5%3" msg="">
  80. <expression expressionType="relation" operationCode="eq" dataType="NUMBER" cover="1+(2+3)*4/5%3" threshold="2"/>
  81. </checkItem>
  82. </execute>
  83. <execute code="stp6" name="混合表达式-MixNode" actionCode="check">
  84. <checkItem code="check1" name="store 的 book中第expensive+1个 的 author" msg="">
  85. <expression expressionType="relation" operationCode="eq" dataType="STRING" cover="${stp1.store.book[%{add(${stp1.expensive},1)}].author}" threshold="J. R. R. Tolkien"/>
  86. </checkItem>
  87. <checkItem code="check2" name="store 的 book中第expensive+1个 的 author" msg="">
  88. <expression expressionType="relation" operationCode="eq" dataType="STRING" cover="${stp1.expensive}.1" threshold="2.1"/>
  89. </checkItem>
  90. </execute>
  91. </flow>
  92. </flows>
  93. </rule>