First steps in a new Phoenix project

The morning sun in down-town Ulaan Batar, Mongolia credits: Volker Holloh

Before I start a new project and write a single line of code, I set it up to support me with writing nice and secure code. To keep me from starting the test suite every time on my own, I set up mix test to watch the project tree and, if any change occurs, to start the test suite.

The test suite consists of the elixir mix test itself and credo for code consistency and sobelow for security-focused code analysis.

Coming from Rails, where I used Brakeman, Rubocop, and Guard, I am happy that the Elixir community provides the same functionalities.

So let's start.

Install Credo

link: https://github.com/rrrene/credo

Add {:credo, "~> 1.4", only: [:dev, :test], runtime: false} to mix.exs file then run mix deps.get in your terminal.

Run mix credo gen.configin terminal to create the credo config file.

Run mix credo for a first check. You probably see a few errors, perhaps some "Modules should have a @moduledoc tag." You can fix those with "@moduledoc false" at the start of the modules, like so:

defmodule MyappWeb.Telemetry do
  use Supervisor
  import Telemetry.Metrics

  def start_link(arg) do
    Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
  end

  @impl true

  @moduledoc false ## <-- this here

  @spec init(any) :: {:ok, {%{intensity: any, period: any, strategy: any}, [any]}}


Install Sobelow

https://github.com/nccgroup/sobelow

Like we did before, we add {:sobelow, "~> 0.8", only: [:dev, :test]} to our mix.exs file, then we run mix deps.get in our terminal.

Please note that I added :testto the environments of Sobelow. We will need it when we let Sobelow run after every file change.

Run sobelow with "mix sobelow" and fix the problems it is showing.

You could add a Sobelow config file with touch .sobelow-conf.

My preferred config:


# .sobelow-conf
[
  verbose: false,
  private: false,
  skip: false,
  router: "",
  exit: "false",
  format: "txt",
  out: "",
  threshold: "low",
  ignore: ["Config.CSP","Config.CSWH"],
  ignore_files: [""]
]


Setup tests

https://github.com/lpil/mix-test.watch

Add the dependency to you mix.exs: {:mix_test_watch, "~> 1.0", only: :dev, runtime: false}, If you run mix test.watchin your terminal, test.watch, well, watches your project directory and runs all tests everytime you save a file.



Automate everything

You can configure Test.watch to run additional test tasks. You can do it in your config/config.exs file


# config/config.exs

# mix test setup
if Mix.env() == :dev do
  config :mix_test_watch,
    tasks: [
      "test --stale",
      "sobelow --config",
      "credo"
    ]
end

When you now run mix test.watch, you get:

output of mix test.watch