如何从 Groovy 中断言的方法或闭包打印语句
How to print statement from asserted method or closure in Groovy
是否可以通过某种方式将闭包或方法中的语句内联到断言中,以便在断言失败时打印出来?
如果我们有像 assert 10 == (20 - 11)
这样的简单语句,那么 Groovy 的 power assert 会很好地打印它:
assert 10 == (20 - 11)
| |
false 9
但是,如果我们将语句提取到闭包中,例如:
def c = { arg -> arg == (20 - 11) }
assert c(10)
那么输出的信息量会少得多:
assert c(10)
|
false
我正在开发自定义特定测试框架,用例是将自定义断言表示为布尔闭包或方法,运行 来自一个地方的断言。
你得到这样的输出是因为 closure
正在返回布尔值并且 assert
确实在寻找 true
.
方法#1:如果你想改变输出,那么你可以将两个参数传递给 closure
而不是一个参数,如下所示。当然,您可能不想在框架中将相等与静态数字进行比较,因此第二个参数有意义。
def c = { arg1, arg2 -> arg1 == arg2 }
assert c(10, 20-11), 'comparison failed'
输出:
java.lang.AssertionError: Comparison failed. Expression: c.call(10, (20 - 11))
at Script1.run(Script1.groovy:2)
方法#2:此处适当更改了闭包名称,并在其内部进行断言。由于它的名字是 assertEqual
,它不太可能被误用于其他断言,例如 >
、<
。
def assertEqual = { arg1, arg2 -> assert arg1 == arg2, "Comparison failed: ${arg1} vs ${arg2}" }
assertEqual(10, 20-11)
输出:
java.lang.AssertionError: Comparison failed: 10 vs 9. Expression: (arg1 == arg2). Values: arg1 = 10, arg2 = 9
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)
你这样写更多的闭包,比如assertGreaterThan
assertLessThan
针对具体的操作
方法#3:在这里您甚至可以将错误消息传递给闭包。
def assertEqual = { arg1, arg2, message -> assert arg1 == arg2, message(arg1, arg2) }
assertEqual(10, 20-11) {op1, op2 -> "$op1 is not equal to $op2"}
输出:
java.lang.AssertionError: 10 is not equal to 9. Expression: (arg1 == arg2). Values: arg1 = 10, arg2 = 9
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)
方法 #4 用户可以传递 operation
和消息的另一种变体。您不仅可以执行 equal
,还可以执行其他操作。因此,将 closure
名称更改为 myAssert
。
def myAssert = { arg1, arg2, expression -> expression(arg1, arg2) }
//Greater than
myAssert(10, 20-11) {op1, op2 -> assert op1 > op2, "$op1 is not greater than $op2" }
//Less than
myAssert(10, 20-11) {op1, op2 -> assert op1 < op2, "$op1 is not less than $op2" }
//Equal
myAssert(10, 20-11) {op1, op2 -> assert op1 == op2, "$op1 is not equal to $op2" }
输出:
java.lang.AssertionError: 10 is not less than 9. Expression: (op1 < op2). Values: op1 = 10, op2 = 9
at Script1$_run_closure2.doCall(Script1.groovy:2)
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)
如果您想采用简单的方法并只使用 equal
断言,那么 方法 #2 是正确的方法。当然,你是更好的人,选择更适合你的需要。
是否可以通过某种方式将闭包或方法中的语句内联到断言中,以便在断言失败时打印出来?
如果我们有像 assert 10 == (20 - 11)
这样的简单语句,那么 Groovy 的 power assert 会很好地打印它:
assert 10 == (20 - 11)
| |
false 9
但是,如果我们将语句提取到闭包中,例如:
def c = { arg -> arg == (20 - 11) }
assert c(10)
那么输出的信息量会少得多:
assert c(10)
|
false
我正在开发自定义特定测试框架,用例是将自定义断言表示为布尔闭包或方法,运行 来自一个地方的断言。
你得到这样的输出是因为 closure
正在返回布尔值并且 assert
确实在寻找 true
.
方法#1:如果你想改变输出,那么你可以将两个参数传递给 closure
而不是一个参数,如下所示。当然,您可能不想在框架中将相等与静态数字进行比较,因此第二个参数有意义。
def c = { arg1, arg2 -> arg1 == arg2 }
assert c(10, 20-11), 'comparison failed'
输出:
java.lang.AssertionError: Comparison failed. Expression: c.call(10, (20 - 11)) at Script1.run(Script1.groovy:2)
方法#2:此处适当更改了闭包名称,并在其内部进行断言。由于它的名字是 assertEqual
,它不太可能被误用于其他断言,例如 >
、<
。
def assertEqual = { arg1, arg2 -> assert arg1 == arg2, "Comparison failed: ${arg1} vs ${arg2}" }
assertEqual(10, 20-11)
输出:
java.lang.AssertionError: Comparison failed: 10 vs 9. Expression: (arg1 == arg2). Values: arg1 = 10, arg2 = 9
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)
你这样写更多的闭包,比如assertGreaterThan
assertLessThan
针对具体的操作
方法#3:在这里您甚至可以将错误消息传递给闭包。
def assertEqual = { arg1, arg2, message -> assert arg1 == arg2, message(arg1, arg2) }
assertEqual(10, 20-11) {op1, op2 -> "$op1 is not equal to $op2"}
输出:
java.lang.AssertionError: 10 is not equal to 9. Expression: (arg1 == arg2). Values: arg1 = 10, arg2 = 9
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)
方法 #4 用户可以传递 operation
和消息的另一种变体。您不仅可以执行 equal
,还可以执行其他操作。因此,将 closure
名称更改为 myAssert
。
def myAssert = { arg1, arg2, expression -> expression(arg1, arg2) }
//Greater than
myAssert(10, 20-11) {op1, op2 -> assert op1 > op2, "$op1 is not greater than $op2" }
//Less than
myAssert(10, 20-11) {op1, op2 -> assert op1 < op2, "$op1 is not less than $op2" }
//Equal
myAssert(10, 20-11) {op1, op2 -> assert op1 == op2, "$op1 is not equal to $op2" }
输出:
java.lang.AssertionError: 10 is not less than 9. Expression: (op1 < op2). Values: op1 = 10, op2 = 9
at Script1$_run_closure2.doCall(Script1.groovy:2)
at Script1$_run_closure1.doCall(Script1.groovy:1)
at Script1.run(Script1.groovy:2)
如果您想采用简单的方法并只使用 equal
断言,那么 方法 #2 是正确的方法。当然,你是更好的人,选择更适合你的需要。