Fl4m3Ph03n1x

Fl4m3Ph03n1x

Separate mix commands for unit and integration tests

Background

I have a project where I have separated my tests into two categories: Unit tests and Integration tests.

My objective is to have 3 commands that do the following:

  • mix test.unit: executes all unit tests
  • mix test.integration: executes all integration tests
  • mix test: executes mix test.unit and then mix test.integration

I can somewhat replicate my first objective, instead of mix test.unit I am using environment variables and I am running MIX_ENV=unit mix test.

Problem

There are however a few problems with this approach:

  • It is way more verbose than the intended command
  • The only way I know of taking advantage of this is by littering my mix.exs with environment variables and pattern matching function that do something depending on the environment
  • It is very easy to miss the environment variable name only to see things blow up
  • I dont get help not auto complete if I type mix help

Research

I thought about using a mix alias like in this post:

But not only am I unsure on how to do it, I don’t even think I can change the default behavior of mix test to run both unit and integration tests separately.

Code

Thus far, all I have no is a half-broken mix.exs file that works:

defmodule MarketManager.MixProject do
  use Mix.Project

  @test_envs [:unit, :integration]

  ##########
  # Public #
  ##########

  def project do
    [
      app: :market_manager,
      version: "0.1.0",
      elixir: "~> 1.9",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      elixirc_paths: elixirc_paths(Mix.env),
      test_paths: test_paths(Mix.env)
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: applications(Mix.env),
      mod: {MarketManager.Application, [env: Mix.env]}
    ]
  end

  ###########
  # Private #
  ###########

  defp applications(:integration), do: applications(:default) ++ [:cowboy, :plug]
  defp applications(_),     do: [:logger]

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      {:httpoison, "~> 1.6"},
      {:jason, "~> 1.2"},

      # Testing and Dev
      {:hammox, "~> 0.2", only: @test_envs},
      {:mix_test_watch, "~> 1.0", only: @test_envs, runtime: false},
      {:plug_cowboy, "~> 2.0", only: @test_envs}
    ]
  end

  defp elixirc_paths(env) when env in @test_envs, do: ["test/support", "lib"]
  defp elixirc_paths(_),     do: ["lib"]

  defp test_paths(:integration), do: ["test/integration"]
  defp test_paths(:unit), do: ["test/unit"]
  defp test_paths(_), do: ["test/unit"]

end

Which was inspired in the blog:

Questions

As you can probably tell from reading my mix.exs file, it is a half broken mess where, in order to compile, I have to mix the definitions of MIX_ENV=unit mix test and mix test (check the test_paths) functions.

This brings all sorts of pain when developing.

How can I fix this file, so it has the desired behavior?

Marked As Solved

Fl4m3Ph03n1x

Fl4m3Ph03n1x

This is from a blog I saw:


# mix.exs
def application do
  [
    extra_applications: [:logger],
    mod: {GithubClient.Application, [env: Mix.env]},
    applications: applications(Mix.env)
  ]
end

I think the author made a little confusion because she uses both applications and extra_applications and one of them was discontinued iirc, but overall it has valuable information.

Also Liked

Fl4m3Ph03n1x

Fl4m3Ph03n1x

The issue I see with that approach is that I have to add an extra @moduletag to every module, while if I manage to do it my way, all I have to do is put the test files inside the “integration” and “unit” folders and it will be self explanatory.

This said, that is a valid approach. Depending on how much trouble the setup I am looking for takes, I may consider your approach.

Where Next?

Popular in Questions Top

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
magnetic
Hey :wave:t3: Elixir community, I’ve been learning Elixir, and working on some side projects. My editor of choice is VSCode, and althoug...
New

We're in Beta

About us Mission Statement