ExUnit.Case
帮助定义测试用例。
该模块必须在其他模块中用作配置和准备测试的方式。
使用时,它接受以下选项:
:async
-将此特定测试用例配置为与其他测试用例并行运行。当此测试用例不更改任何全局状态时,可用于性能。默认为false
...中定义的所有回调自动包含此模块。ExUnit.Callbacks
有关以下内容的更多信息,请参见该模块setup
,,,start_supervised
,,,on_exit
以及测试过程生命周期。有关将测试分组在一起,请参见describe/2
在这个模块里。- 实例 defmodule AssertionTest do # Use the module use ExUnit.Case, async: true # The "test" macro is imported by ExUnit.Case test "always pass" do assert true end 语境所有测试都接收一个上下文作为参数。上下文对于在回调和测试之间共享信息特别有用:defmodule KVTest do use ExUnit.Case setup do {:ok, pid} = KV.start_link {:ok, pid: pid} end test "stores key-value pairs", context do assert KV.put(context[:pid], :hello, :world) == :ok assert KV.get(context[:pid], :hello) == :world end 由于上下文是一个map,因此可以匹配模式来提取信息:
test "stores key-value pairs", %{pid: pid} do assert KV.put(pid, :hello, :world) == :ok assert KV.get(pid, :hello) == :world end标签上下文用于从回调传递信息到测试。为了将信息从测试传递给回调,ExUnit提供了标记。通过标记测试,可以在上下文中访问标记值,从而允许开发人员自定义测试。让我们看看一个例子:defmodule FileTest do # Changing directory cannot be async use ExUnit.Case, async: false setup context do # Read the :cd tag value if cd = context[:cd] do prev_cd = File.cwd! File.cd!(cd) on_exit fn -> File.cd!(prev_cd) end end :ok end @tag cd: "fixtures" test "reads UTF-8 fixtures" do File.read("hello") end end在上面的例子中,我们已经定义了一个名为:cd的标签,它在setup回调中被读取以配置测试将要运行的工作目录。当使用案例模板(ExUnit.CaseTemplate)时,标记也可以非常有效地允许回调 在案例模板中自定义测试行为。注意标签可以通过两种不同的方式设置:@tag key:value
@tag:key#相当于设置@tag key:true如果给定一个标签不止一次,则最后一个值为wins.Module和describe tagsA可以为模块中的所有测试设置标签或通过设置@moduletag或@describetag 分别为:@moduletag:external如果通过@tag设置了相同的键,则@tag值的优先级更高。Known tags以下标记由ExUnit自动设置,因此是保留的:
:case
-测试用例模块
:file
-定义测试的文件
:line
-确定测试的界限
:test
-测试名称
:async
-如果测试用例处于异步模式
:type
-测试的类型(:test
,:property
等)
:registered
- 用于ExUnit.Case.register_attribute/3
的值
:describe
-测试属于的描述块
以下标记自定义测试的行为方式:
:capture_log
- 请参阅下面的“日志捕获”部分
:skip
-在给定的原因下跳过测试
:timeout
- 以毫秒为单位自定义测试超时(默认为60000)
:report
- 在错误报告中包含给定的标签和上下文关键字,请参阅“报告标签”部分
报告标签
ExUnit还允许您的上下文中的标签或任何其他密钥包含在错误报告中,使开发人员可以轻松查看在哪些情况下评估测试。为此,您使用:report
标签:
@moduletag report: [:user_id, :server]
现在,当发生错误时,有一个标记部分,其中包含每个报告字段的值:
代码:不合格的“OOPS”堆栈跟踪:
lib/my_lib/source.exs:148
标签:
user_id: 1
server: #PID<0.63.0>
Filters(过滤器)
标记也可以用于标识特定的测试,然后可以使用过滤器包括或排除这些测试。最常见的功能是排除某些特定测试的运行,这可以通过ExUnit.configure/1
*
# Exclude all external tests from running
ExUnit.configure(exclude: [external: true])
从今以后,ExUnit将不再运行任何具有external
设置为true
.这种行为可以通过:include
选项,通常通过命令行传递:
mix test --include external:true
运行mix help test
以获取更多关于如何通过Mix运行过滤器的信息。
标记和过滤器的另一个用例是排除默认情况下具有特定标记的所有测试,而不管其值如何,并仅包含特定的子集:
ExUnit.configure(exclude: :os, include: [os: :unix])
请记住,默认情况下所有测试都包括在内,因此除非它们首先被排除在外,否则include
选项没有效果。
日志捕获
ExUnit可以选择性地禁止打印测试期间生成的日志消息。在运行测试时生成的日志消息将被捕获,并且只有在测试失败时才会打印以帮助进行调试。
您可以选择在单个测试中使用这种行为,方法是将它们标记为:capture_log
或为ExUnit配置中的所有测试启用日志捕获:
ExUnit.start(capture_log: true)
这个默认值可以被@tag capture_log: false
或者@moduletag capture_log: false
覆盖。
自setup_all
块不属于特定的测试,在它们中生成的日志消息%28或测试之间的日志消息%29永远不会被捕获。如果您也想抑制这些消息,请全局删除控制台后端:
config :logger, backends: []
功能
describe(message, list)
共同描述测试
register_attribute(env,name,opts \ [])
注册ExUnit.Case
测试期间使用的新属性
register_test(map, type, name, tags)
注册要作为本例的一部分运行的函数。
测试(消息)
用字符串定义未实现的测试。
test(message,var \ quote()do _ end,contents)
用字符串定义测试
描述(消息,列表)(宏)
一起描述测试。
ExUnit.Callbacks.setup/1
可能会被调用,并且它将定义一个安装回调,仅为当前块运行。还将描述名添加为标记,允许开发人员运行特定块的测试。
实例
defmodule StringTest do
use ExUnit.Case, async: true
describe "String.capitalize/1" do
test "first grapheme is in uppercase" do
assert String.capitalize("hello") == "Hello"
end
test "converts remaining graphemes to lowercase" do
assert String.capitalize("HELLO") == "Hello"
end
end
end
当使用Mix时,可以在描述块中运行所有测试,如下所示:
mix test --only describe:"String.capitalize/1"
注描述块不能嵌套。开发人员不应依赖层次结构进行组合,而应构建在命名设置之上。例如:
defmodule UserManagementTest do
use ExUnit.Case, async: true
describe "when user is logged in and is an admin" do
setup [:log_user_in, :set_type_to_admin]
test ...
end
describe "when user is logged in and is a manager" do
setup [:log_user_in, :set_type_to_manager]
test ...
end
defp log_user_in(context) do
# ...
end
end
通过禁止支持命名设置的层次结构,开发人员可以简单地浏览每个描述块,并准确地了解所涉及的设置步骤。
register_attribute(env,name,opts \ [])
期间使用的新属性。ExUnit.Case
测试。
属性值将作为键/值对在context.registered
.键/值对将在每个键/值对之后清除。ExUnit.Case.test/3
类似于@tag
...
Module.register_attribute/3
用于注册属性,则此函数采用相同的选项。
实例
defmodule MyTest do
use ExUnit.Case
ExUnit.Case.register_attribute __ENV__, :foobar
@foobar hello: "world"
test "using custom test attribute", context do
assert context.registered.hello == "world"
end
end
register_test(map, type, name, tags)
注册一个函数作为这种情况的一部分运行。
这被第三方项目(如QuickCheck)用来实现像property/3
这样的宏,但是test
却定义了一个属性。有关test/3
调用此函数的示例,请参阅实现。
测试类型将被转换为字符串并进行复数显示。您可以使用ExUnit.plural_rule/2
设置自定义复数。
test(message) (macro)
用字符串定义未实现的测试。
提供一个方便的宏,允许用字符串定义测试,但尚未实现。由此产生的测试将始终失败并打印“未执行”错误消息。由此产生的测试用例也被标记为:not_implemented
。
实例
test "this will be a test in future"
test(message,var \ quote()do _ end,contents)(宏)
用字符串定义测试。
提供一个方便的宏,允许使用字符串定义测试。该宏自动插入原子:ok
作为测试的最后一行。也就是说,通过测试总是会返回:ok
,但更重要的是,它会迫使Elixir不要拖尾调用优化测试,因此避免从回溯中隐藏线。
实例
test "true is equal to true" do
assert true == true
end
本文档系腾讯云开发者社区成员共同维护,如有问题请联系 cloudcommunity@tencent.com