Skip to content

Repository files navigation

Dotnet Test Traitor

A simple test runner for .NET projects that lets you run selected tests using predefined filters.

Example for xUnit, where you can define a Trait to categorize your tests:

using Xunit;

[Fact]
[Trait("Category", "Integration")]
public void SampleTest()
{
    Assert.True(true);
}

To run only tests with this trait, you would typically execute:

  • VS Test: dotnet test --filter "Category=Integration"

  • MTP: dotnet test --treenode-filter /*/*/*/*[Category=Integration]

This plugin simplifies the process by allowing you to predefine reusable filters that can later be selected interactively. Failed tests are automatically inserted into the Neovim quickfix list and displayed via trouble.nvim, making it easy to locate and fix them.

It integrates with:

  • trouble.nvim for displaying failed tests in the quickfix list

alt text

Installation

Using lazy.nvim

{
  "sebastianstudniczek/dotnet-test-traitor.nvim",
  ft = "cs",
  dependencies = {
    "folke/trouble.nvim"
  },
  --- @type dotnet-test-traitor.Configuration
  opts = {
    -- define your own filters
    filters = {
      {
        name = "Unit Tests",
        value = "Category!=Manual&Category!=E2E&Category!=Integration&Category!=Performance&Category!=Service|Type=Service-InMemory",
        is_vstest = true
      },
      { name = "Integration", value = "Category=Integration" },
      { name = "E2E Tests", value = "Category=E2E" },
    },
  },
    keys = {
      { "<leader>tc", "<Plug>(DotnetTestTraitorRun)", mode = "n", desc = "Run Test Category (Dotnet)" },
    },
},

You can define your own filters in the configuration under the opts.filters field. Each filter has a name (used for display) and a value — a filter expression passed to the dotnet test --filter command.

Important

By default filter assumes using MTP syntax (--treenode-filter)

Remote usage

It's possible to invoke test execution from outside nvim. For example from git hook.

To store neovim address you can use autocmd like this:

local function write_server_file()
  local server = vim.v.servername

  if server == "" then
    return
  end

  local root = vim.fs.root(0, ".git")
  if not root then
    return
  end

  vim.fn.writefile({ server }, root .. "/.nvim.server")
end

vim.api.nvim_create_autocmd("VimEnter", {
  callback = write_server_file,
})

and later invoke it via:

if [ -f .nvim.server ]; then
  FILTER="/*/*/*/*[Category!=Service]"
  RESULT_FILE=$(mktemp)

  trap 'rm -f "$RESULT_FILE"' EXIT

  nvim --headless --server "$SERVER" --remote-expr "v:lua.require('dotnet-test-traitor.run')({ 'value': '$FILTER' }, '$RESULT_FILE')" > /dev/null

  while [ ! -s "$RESULT_FILE" ]; do
    sleep 0.2
  done

  EXIT_CODE=$(cat "$RESULT_FILE")
  exit "$EXIT_CODE"
fi

About

Run tests with predefined filters and quickly identify failed ones with quickfix list

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages