【Elixir】テストを書いてみる
2022/12/03
Elixir でのテストを触りだけやる
バージョン
$ elixir -v
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Elixir 1.14.2 (compiled with Erlang/OTP 25)
$ mix -v
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Mix 1.14.2 (compiled with Erlang/OTP 25)
プロジェクト作成
mix new でプロジェクトを作成する
$ mix new hello
以下のファイル群が生成された
$ cd hello
$ tree .
.
├── README.md
├── lib
│ └── hello.ex
├── mix.exs
└── test
├── hello_test.exs
└── test_helper.exs
2 directories, 5 files
hello.ex には、:world を返す hello 関数が定義されている
$ iex -S mix
Erlang/OTP 25 [erts-13.1.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit:ns] [dtrace]
Interactive Elixir (1.14.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Hello.hello
:world
mix test でテストを実行する
$ mix test
Compiling 1 file (.ex)
Generated hello app
..
Finished in 0.01 seconds (0.00s async, 0.01s sync)
1 doctest, 1 test, 0 failures
Randomized with seed 96636
もちろん通る
テストを変更する
hello(文字列) で Hello, 文字列! を返す関数を想定してテストを書き換えてみる
テストは doctest と ExUnit が使われているらしい
それぞれ、以下のような変更をした
doctest
lib/hello.ex
defmodule Hello do
@moduledoc """
Documentation for `Hello`.
"""
@doc """
Hello world.
## Examples
- iex> Hello.hello()
- :world
+ iex> Hello.hello("world")
+ "Hello, world!"
"""
def hello do
:world
end
end
ExUnit
test/hello_test.exs
defmodule HelloTest do
use ExUnit.Case
doctest Hello
test "greets the world" do
- assert Hello.hello() == :world
+ assert Hello.hello("world") == "Hello, world!"
end
end
テストを実行
$ mix test
warning: Hello.hello/1 is undefined or private. Did you mean:
* hello/0
Invalid call found at 2 locations:
(for doctest at) lib/hello.ex:11: HelloTest."doctest Hello.hello/0 (1)"/1
test/hello_test.exs:6: HelloTest."test greets the world"/1
1) test greets the world (HelloTest)
test/hello_test.exs:5
** (UndefinedFunctionError) function Hello.hello/1 is undefined or private. Did you mean:
* hello/0
code: assert Hello.hello("World") == "Hello, World!"
stacktrace:
(hello 0.1.0) Hello.hello("World")
test/hello_test.exs:6: (test)
2) doctest Hello.hello/0 (1) (HelloTest)
test/hello_test.exs:3
** (UndefinedFunctionError) function Hello.hello/1 is undefined or private. Did you mean:
* hello/0
stacktrace:
(hello 0.1.0) Hello.hello("world")
(for doctest at) lib/hello.ex:11: (test)
Finished in 0.03 seconds (0.00s async, 0.03s sync)
1 doctest, 1 test, 2 failures
Randomized with seed 202919
当然テストはコケる
関数を修正する
テストが通るように関数を修正する
lib/hello.ex
defmodule Hello do
@moduledoc """
Documentation for `Hello`.
"""
@doc """
Hello world.
## Examples
iex> Hello.hello("world")
"Hello, world!"
"""
def hello(text) do
- :world
+ "Hello, #{text}!"
end
end
テストを実行する
$ mix test
..
Finished in 0.01 seconds (0.00s async, 0.01s sync)
1 doctest, 1 test, 0 failures
無事、通った