在erlang eunit failure中打印测试夹具描述

时间:2018-06-08 17:18:13

标签: erlang eunit

有没有办法打印使用灯具的erlang测试生成器的测试说明?使用生成器很难说出哪些测试实际上失败了,打印描述会有所帮助。

示例:

-module(math_test).

-include_lib("eunit/include/eunit.hrl").
-define(test(Desc, F), {Desc, {setup, fun setup/0, fun cleanup/1, F}}).

setup() ->
  ok.

cleanup(_) ->
  ok.

math_test_ () ->
  [
    ?test("adds two numbers", fun add_two_numbers/0),
    ?test("subtract two numbers", fun subtract_two_numbers/0),
    ?test("undefined method called", fun undefined_error/0)
  ].

add_two_numbers () ->
  ?assertEqual(2, 1 + 3).

subtract_two_numbers () ->
  ?assertEqual(1, 2 - 2).

undefined_error () ->
  undefined_module:uh_oh().

然后运行它

[root@a7c901c022bb src]# rebar3 eunit --module=math_test
===> Verifying dependencies...
===> Compiling math
===> Performing EUnit tests...
FFF
Failures:

  1) math_test:math_test_/0
     Failure/Error: ?assertEqual(2, 1 + 3)
       expected: 2
            got: 4
     %% /src/_build/test/lib/math/src/math_test.erl:20:in `math_test:-add_two_numbers/0-fun-0-/1`
     Output: 
     Output: 
  2) math_test:math_test_/0
     Failure/Error: ?assertEqual(1, 2 - 2)
       expected: 1
            got: 0
     %% /src/_build/test/lib/math/src/math_test.erl:23:in `math_test:-subtract_two_numbers/0-fun-0-/1`
     Output: 
     Output: 
  3) math_test:math_test_/0
     Failure/Error: {error,undef,[{undefined_module,uh_oh,[],[]}]}
     Output: 

前两个错误是可以的,但不是很好 - 你至少可以在断言中看到事情确实出错了。

然而,第三个错误(调用未定义的模块/方法)是可怕的错误 - 没有真正的方法可以告诉它来自哪里!

有没有办法改进,比如用故障日志打印测试说明?

2 个答案:

答案 0 :(得分:2)

您可以做的一件事是将测试描述放在测试本身上,而不是整个workflow Set-AzureSqlDatabaseEdition { param ( # Name of the Azure SQL Database server (Ex: bzb98er9bp) [parameter(Mandatory=$true)] [string] $SqlServerName, # Target Azure SQL Elastic Pool [parameter(Mandatory=$true)] [string] $ElasticPoolName, # Desired Azure SQL Elastic Pool edition {Basic, Standard, Premium} [parameter(Mandatory=$true)] [string] $Edition, # Desired DTU [parameter(Mandatory=$true)] [string] $DTU, # DatabaseDtuMin [parameter(Mandatory=$true)] [string] $DatabaseDtuMin, # DatabaseDtuMax [parameter(Mandatory=$true)] [string] $DatabaseDtuMax, # Credentials for $SqlServerName stored as an Azure Automation credential asset # When using in the Azure Automation UI, please enter the name of the credential asset for the "Credential" parameter [parameter(Mandatory=$true)] [PSCredential] $Credential ) inlinescript { Write-Output "Begin vertical scaling script..." # Establish credentials for Azure SQL Database server $Servercredential = new-object System.Management.Automation.PSCredential($Using:Credential.UserName, (($Using:Credential).GetNetworkCredential().Password | ConvertTo-SecureString -asPlainText -Force)) # Create connection context for Azure SQL Database server $CTX = New-AzureSqlDatabaseServerContext -ManageUrl “https://$Using:SqlServerName.database.windows.net” -Credential $ServerCredential # Get Azure Elastic Pool context $EP = Get-AzureRmSqlElasticPool $CTX ElasticPoolName $Using:ElasticPoolName # Specify the specific performance level for the target $DatabaseName $DTU = Get-AzureRmSqlElasticPool $CTX ElasticPoolName $Using:DTU # Set the new edition/performance level Set-AzureRmSqlElasticPool $CTX ElasticPoolName $DTU –ServiceObjective $DTU –Edition $Using:Edition -Force # Output final status message Write-Output "Scaled the performance level of $Using:DatabaseName to $Using:Edition - $Using:PerfLevel" Write-Output "Completed vertical scale" } } 元组。也就是说,改变这一行:

setup

为:

-define(test(Desc, F), {Desc, {setup, fun setup/0, fun cleanup/1, F}}).

通过该更改,将打印测试说明:

-define(test(Desc, F), {setup, fun setup/0, fun cleanup/1, {Desc, F}}).

要尝试的另一件事是使用Failures: 1) math_test:math_test_/0: adds two numbers Failure/Error: ?assertEqual(2, 1 + 3) expected: 2 got: 4 %% /tmp/math_test/mylib/_build/test/lib/mylib/test/math_test.erl:20:in `math_test:-add_two_numbers/0-fun-0-/0` Output: Output: 2) math_test:math_test_/0: subtract two numbers Failure/Error: ?assertEqual(1, 2 - 2) expected: 1 got: 0 %% /tmp/math_test/mylib/_build/test/lib/mylib/test/math_test.erl:23:in `math_test:-subtract_two_numbers/0-fun-0-/0` Output: Output: 3) math_test:math_test_/0: undefined method called Failure/Error: {error,undef,[{undefined_module,uh_oh,[],[]}]} Output: 宏指定测试函数,而不是使用普通?_test术语:

fun

math_test_ () -> [ ?test("adds two numbers", ?_test(add_two_numbers())), ?test("subtract two numbers", ?_test(subtract_two_numbers())), ?test("undefined method called", ?_test(undefined_error())) ]. 宏会记住它出现的行号,并在测试失败时将其包含在输出中:

?_test

现在,您可以确定从哪个行调用这些测试。

另一种方法是让各个函数返回eunit"测试对象"而不是仅仅运行测试。这将涉及使用 1) math_test:math_test_/0:14: adds two numbers [...] 2) math_test:math_test_/0:15: subtract two numbers [...] 3) math_test:math_test_/0:16: undefined method called [...] 代替?_assertEqual,或将整个内容包装在?assertEqual中:

?_test

然后输出包含行号和各个测试函数的名称:

math_test_ () ->
  [
    ?test("adds two numbers", add_two_numbers()),
    ?test("subtract two numbers", subtract_two_numbers()),
    ?test("undefined method called", undefined_error())
  ].

add_two_numbers () ->
  ?_assertEqual(2, 1 + 3).

subtract_two_numbers () ->
  ?_assertEqual(1, 2 - 2).

undefined_error () ->
  ?_test(undefined_module:uh_oh())

答案 1 :(得分:2)

@legoscia的答案很好,但我也怀疑rebar3实施的错误报告对于那种错误来说是次优的。直接从eunit运行测试及其默认输出,你得到:

2> eunit:test(math_test). 
math_test: math_test_...*failed*
in function math_test:'-add_two_numbers/0-fun-0-'/0 (math_test.erl, line 22)
**error:{assertEqual,[{module,math_test},
                      {line,22},
                      {expression,"1 + 3"},
                      {expected,2},
                      {value,4}]}
  output:<<"">>

math_test: math_test_...*failed*
in function math_test:'-subtract_two_numbers/0-fun-0-'/0 (math_test.erl, line 25)
**error:{assertEqual,[{module,math_test},
                      {line,25},
                      {expression,"2 - 2"},
                      {expected,1},
                      {value,0}]}
  output:<<"">>

math_test: math_test_...*failed*
in function undefined_module:uh_oh/0
  called as uh_oh()
**error:undef 
  output:<<"">>

=======================================================
  Failed: 3.  Skipped: 0.  Passed: 0.

使用&#39;详细&#39;选项,它还会在每次设置之前打印说明。此外,将描述移动到测试乐趣,并使用?_test(...)宏创建具有更多位置信息的测试乐趣而不是简单的乐趣,正如@legoscia建议的那样,您得到此输出:

  math_test:18: math_test_ (undefined method called)...*failed*
in function undefined_module:uh_oh/0
  called as uh_oh()
**error:undef 
  output:<<"">>

您可以向rebar3维护者报告此事。