Another quick and dirty post regarding Elixir. This one will be really quick, but I was working on test unit recently, and was stuck for few minutes about where I could put my fixtures, and especially... some raw blobs. In Erlang, with common_test, the path is directly passed in the options and it is easy to use. In Elixir, it's a bit different, the relative path of the test suite is stored in the __DIR__ macro. This small trick get lost in my mind. Here an example.
$ mix new blob
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/blob.ex
* creating test
* creating test/test_helper.exs
* creating test/blob_test.exs
Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:
cd blob
mix test
Run "mix help" for more commands.
$ cd blob
A fixtures directory can be helpful, let creates one.
$ mkdir -p test/fixtures
To do the test, let create also a file called blob.txt containing an encoded string in base64 via openssl.
$ printf "this is a test" | openssl enc -base64 > test/fixture/blob.txt
The project created for this example is a simple library, the project configuration file mix.exs must be updated to allow other files to be loaded during the test execution. This is configured in :test_load_filters section, all files ending with _test.exs and _fixtures.exs must be loaded.
defmodule Blob.MixProject do
use Mix.Project
def project do
[
app: :blob,
version: "0.1.0",
elixir: "~> 1.19",
start_permanent: Mix.env() == :prod,
deps: deps(),
test_load_filters: [
&String.ends_with?(&1, "_test.exs"),
&String.ends_with?(&1, "_fixtures.exs")
]
]
end
# ...
end
An helper function to have access to the fixtures can be created. It's not mandatory, but it's easier to call something like BlobFixtures.read_blob/1 instead of recreating the same procedure everytime. DRY.
defmodule BlobFixtures do
def read_blob(relative_path) do
[__DIR__, "fixtures", relative_path]
|> Path.join()
|> File.read!()
end
end
The test suite can now be updated. The blob is read from the file system and pushed in the test suite.
defmodule BlobTest do
use ExUnit.Case
doctest Blob
# ...
test "read from file" do
assert "this is a test" ==
BlobFixtures.read_blob("blob.txt")
|> String.trim()
|> Base.decode64!()
# only for the example
|> IO.inspect()
end
end
Finally, mix test can be called, and it should be green. The decoded message should be printed as well.
$ mix test
Running ExUnit with seed: 423336, max_cases: 16
"this is a test"
...
Finished in 0.04 seconds (0.00s async, 0.04s sync)
1 doctest, 2 tests, 0 failures
Indeed, it was a quick note! As usual, have fun and happy hacking!
Cover Image by Connor Gan on Unsplash
Top comments (0)