Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
World desk4 min

How to Test Binary Data and File Paths in ExUnit

Use a binary for byte-processing tests and a uniquely named temporary file when your code reads a path. ExUnit setup and on_exit handle fixture creation and cleanup.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For bytes-only code, pass an in-memory binary. If the code opens a file path, create a temporary file in ExUnit setup and register its removal with on_exit. “Blob fixture” is not a special ExUnit feature; it is ordinary test setup combined with Elixir’s binary and file APIs.

Choose a binary or a file path based on what the code accepts

Test the interface your application actually exposes. A function that receives bytes can usually be tested with a binary value, without filesystem setup. A function that opens a path should receive a real file if the test is meant to cover reading, path handling, or file errors.

As an Amazon Associate I earn from qualifying purchases.

Fixture Best fit Trade-off
In-memory binary Testing byte-processing behavior No file creation or cleanup, but does not exercise file IO
Temporary file Testing code that opens or reads a path More faithful to file IO, with setup and cleanup to manage

For binary-processing code, choose cases that match its contract. Depending on the behavior under test, useful inputs may include empty content, embedded zero bytes, non-UTF-8 bytes, or a representative larger payload. A binary can contain arbitrary byte values; that does not mean every application-level API accepts every encoding or size.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Create a per-test file fixture with setup and on_exit

ExUnit runs setup before each test. A setup callback can return a map or keyword list, which ExUnit merges into that test’s context. That makes the path and expected bytes explicit in the test rather than hidden in shared state.

defmodule BlobReaderTest do
  use ExUnit.Case, async: true

  setup do
    path = Path.join(System.tmp_dir!(), "blob-#{System.unique_integer([:positive])}.bin")
    bytes = <<0, 1, 2, 255>>

    :ok = File.write(path, bytes)
    on_exit(fn -> File.rm(path) end)

    %{blob_path: path, blob_bytes: bytes}
  end

  test "reads the fixture bytes", %{blob_path: path, blob_bytes: bytes} do
    assert {:ok, ^bytes} = File.read(path)
  end
end

This illustrative pattern uses a per-test unique filename to reduce collisions when tests run concurrently. It uses the non-bang File.write/2 and File.rm/1 APIs and matches the expected success result for creation. If writing fails, the match fails the setup; adapt error handling and temporary-path choices to your project and supported platforms. The official ExUnit example uses File.write!/2 and removes the file with File.rm!/1.

Register cleanup as soon as the resource has been created. ExUnit runs an on_exit callback in a separate process, so do not make it depend on mutable state held only by the test process. In the per-test setup pattern above, the path is captured when the callback is registered.

Use the right binary IO API

Elixir’s File documentation says files default to binary mode and points to IO.binread/2 and IO.binwrite/2 for binary IO. Use APIs that match the code under test: File.read/1 is suitable when the application reads a whole file by path, while code that works through an IO device should be tested through its corresponding binary IO operations.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Decide whether setup_all is appropriate

setup_all runs once before the module’s tests, rather than once per test. Use it only when sharing fixture state is intentional and safe. ExUnit runs setup_all in a separate process from the tests, which can affect resource ownership and sharing; per-test setup is a simpler choice when each test needs an independent file.

ExUnit runs registered exit callbacks in a separate process. Callbacks registered in a test or setup run in a blocking fashion after that test and before the next test in the case. A callback registered in setup is therefore suited to removing that test’s fixture before the next test proceeds. ExUnit also documents that a registered on_exit/2 callback will run, while failures in setup or setup_all stop remaining setup callbacks from executing.

Keep concurrent tests from sharing a filename

Do not give parallel tests the same fixed temporary filename: one test could overwrite or remove another test’s fixture. A unique per-test path plus immediate cleanup keeps each file’s lifecycle tied to its test. Elixir v1.18 introduced parameterized ExUnit tests and test groups; parameterized scenarios can run concurrently when async: true is used, and groups allow concurrency across groups while tests in the same group do not run concurrently. Account for shared external state when choosing how to group or isolate scenarios.

For process-based fixtures, ExUnit’s supervised-process helpers address a different cleanup concern: its callbacks documentation says supervised processes are guaranteed to terminate before on_exit callbacks run and recommends start_supervised/2 to ensure processes have fully terminated before the next test. A file still needs explicit filesystem cleanup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check version compatibility for your project

The official Elixir documentation page accessed in 2026 marked Elixir v1.20.4 stable and listed Erlang/OTP 27, 28, and 29 as supported. Documentation labels and compatibility change over time, so check the versioned documentation that matches the Elixir and OTP versions used by your project.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.