Packages
nous
0.14.3
0.17.0
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.17
0.12.16
0.12.15
0.12.14
0.12.13
0.12.12
0.12.11
0.12.9
0.12.7
0.12.6
0.12.5
0.12.3
0.12.2
0.12.0
0.11.3
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.5.0
AI agent framework for Elixir with multi-provider LLM support
Current section
Files
Jump to
Current section
Files
lib/nous/skills/elixir_testing.ex
defmodule Nous.Skills.ElixirTesting do
@moduledoc "Built-in skill for Elixir testing with ExUnit, Mox, and property-based testing."
use Nous.Skill, tags: [:elixir, :testing, :exunit, :mox], group: :testing
@impl true
def name, do: "elixir_testing"
@impl true
def description,
do: "ExUnit testing patterns, Mox mocking, and property-based testing for Elixir"
@impl true
def instructions(_agent, _ctx) do
"""
You are an Elixir testing specialist. Follow these patterns:
1. **Test structure**: Mirror `lib/` structure in `test/`. Use `async: true` by default:
```elixir
defmodule MyApp.AccountsTest do
use ExUnit.Case, async: true
# ...
end
```
2. **Setup blocks**: Use `setup` for shared state, return as map for pattern matching:
```elixir
setup do
user = insert(:user)
{:ok, user: user}
end
test "updates user", %{user: user} do
assert {:ok, _} = Accounts.update_user(user, %{name: "New"})
end
```
3. **Mox — mock only external boundaries**: Define behaviours for external services, mock those in tests:
```elixir
# Define behaviour
defmodule MyApp.HTTPClient do
@callback get(String.t()) :: {:ok, map()} | {:error, term()}
end
# In test
Mox.defmock(MockHTTP, for: MyApp.HTTPClient)
expect(MockHTTP, :get, fn _url -> {:ok, %{status: 200}} end)
```
Never mock internal modules — test real implementations.
4. **Use `verify_on_exit!`** to ensure all expectations were called.
5. **Property-based testing** with StreamData for invariants:
```elixir
use ExUnitProperties
property "reverse is idempotent" do
check all list <- list_of(integer()) do
assert list |> Enum.reverse() |> Enum.reverse() == list
end
end
```
6. **Tag slow/integration tests**: `@tag :integration`, run with `mix test --only integration`.
7. **Descriptive test names**: Describe the behavior, not the implementation.
"""
end
@impl true
def match?(input) do
input = String.downcase(input)
String.contains?(input, [
"exunit",
"elixir test",
"mix test",
"mox",
"test elixir",
"property test",
"stream_data"
])
end
end