檢視原始碼 ExUnit.CaptureIO (ExUnit v1.16.2)

用於擷取 IO 以進行測試的功能。

範例

defmodule AssertionTest do
  use ExUnit.Case

  import ExUnit.CaptureIO

  test "example" do
    assert capture_io(fn -> IO.puts("a") end) == "a\n"
  end

  test "another example" do
    assert with_io(fn ->
      IO.puts("a")
      IO.puts("b")
      2 + 2
    end) == {4, "a\nb\n"}
  end
end

摘要

函式

擷取評估 fun 時產生的 IO。

擷取評估 fun 時產生的 IO。

擷取評估 fun 時產生的 IO。

呼叫指定的 fun 並傳回結果和擷取的輸出。

呼叫指定的 fun 並傳回結果和擷取的輸出。

呼叫指定的 fun 並傳回結果和擷取的輸出。

函式

@spec capture_io((-> any())) :: String.t()

擷取評估 fun 時產生的 IO。

傳回擷取的輸出的二進位檔。

預設情況下,capture_io 會取代目前程序的 group_leader (:stdio)。擷取 group leader 是針對每個程序進行,因此可以同時進行。

不過,擷取任何其他已命名裝置(例如 :stderr)時,會在全域進行,而且會持續到函式結束為止。雖然這表示在許多情況下,使用 async: true 執行測試是安全的,但擷取的輸出可能會包含來自其他測試的輸出,因此在非同步使用 capture_io 時,必須特別小心。

開發人員可以設定字串作為輸入。預設輸入為空字串。如果非同步擷取已命名裝置,則只能將輸入提供給第一次擷取。任何進一步提供給該裝置上擷取的擷取都會引發例外狀況,並表示測試應該同步執行。

類似地,一旦開始擷取已命名裝置,就無法在後續同時擷取中變更該裝置的編碼。這種情況下會引發錯誤。

IO 裝置

您可以擷取任何已註冊 IO 裝置的 IO。提供的裝置名稱必須是表示已註冊程序名稱的原子。此外,Elixir 提供兩個捷徑

  • :stdio - :standard_io 的捷徑,對應到 Erlang 中目前的 Process.group_leader/0

  • :stderr - Erlang 中提供的命名程序 :standard_error 的捷徑

選項

  • :input - IO 裝置的輸入,預設為 ""

  • :capture_prompt - 定義是否應擷取提示(指定為 IO.get* 函式的引數)。預設為 true。對於 :stdio 以外的 IO 裝置,將忽略此選項。

  • :encoding(自 v1.10.0 起)- IO 裝置的編碼。允許的值為 :unicode(預設)和 :latin1

範例

要擷取標準 IO

iex> capture_io(fn -> IO.write("john") end) == "john"
true

iex> capture_io("this is input", fn ->
...>   input = IO.gets("> ")
...>   IO.write(input)
...> end) == "> this is input"
true

iex> capture_io([input: "this is input", capture_prompt: false], fn ->
...>   input = IO.gets("> ")
...>   IO.write(input)
...> end) == "this is input"
true

請注意,在標準 IO 中使用 == 是可以的,因為內容會針對每個測試程序擷取。但是,:stderr 會在所有測試中共用,因此如果你使用非同步測試,則會想要對 :stderr 的宣告使用 =~ 而不是 ==

iex> capture_io(:stderr, fn -> IO.write(:stderr, "john") end) =~ "john"
true

iex> capture_io(:standard_error, fn -> IO.write(:stderr, "john") end) =~ "john"
true

特別是,避免在非同步測試中對 :stderr 進行空擷取

iex> capture_io(:stderr, fn -> :nothing end) == ""
true

否則,如果擷取任何其他測試的標準錯誤,測試將會失敗。

傳回值

如上方的範例所示,capture_io 會傳回擷取的輸出。如果你也想要擷取執行函式的結果,請使用 with_io/2

連結至這個函式

capture_io(device_input_or_options, fun)

檢視原始碼
@spec capture_io(atom() | String.t() | keyword(), (-> any())) :: String.t()

擷取評估 fun 時產生的 IO。

請參閱 capture_io/1 以取得更多資訊。

連結至這個函式

capture_io(device, input_or_options, fun)

檢視原始碼
@spec capture_io(atom(), String.t() | keyword(), (-> any())) :: String.t()

擷取評估 fun 時產生的 IO。

請參閱 capture_io/1 以取得更多資訊。

連結至這個函式

with_io(fun)

檢視原始碼 (自 1.13.0 起)
@spec with_io((-> any())) :: {any(), String.t()}

呼叫指定的 fun 並傳回結果和擷取的輸出。

它接受與 capture_io/1 相同的引數和選項。

範例

{result, output} =
  with_io(fn ->
    IO.puts("a")
    IO.puts("b")
    2 + 2
  end)

assert result == 4
assert output == "a\nb\n"
連結至這個函式

with_io(device_input_or_options, fun)

檢視原始碼 (自 1.13.0 起)
@spec with_io(atom() | String.t() | keyword(), (-> any())) :: {any(), String.t()}

呼叫指定的 fun 並傳回結果和擷取的輸出。

請參閱 with_io/1 以取得更多資訊。

連結至這個函式

with_io(device, input_or_options, fun)

檢視原始碼 (自 1.13.0 起)
@spec with_io(atom(), String.t() | keyword(), (-> any())) :: {any(), String.t()}

呼叫指定的 fun 並傳回結果和擷取的輸出。

請參閱 with_io/1 以取得更多資訊。