First steps in a new Phoenix project
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.config
in 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 :test
to 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.watch
in 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: