Skip to content

Extracts testable C# code from structured comments to test files.

License

Notifications You must be signed in to change notification settings

robinkrahl/doctest-csharp

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

doctest-csharp

Check Coverage Status Nuget

Doctest-csharp extracts the <code>...</code> snippets from the structured comments and generates the corresponding test files (so called "doctests").

Motivation

It is important to test your documented code snippets to avoid the code rot. Otherwise, future changes to the code base might render the recorded instructions in those documentation snippets invalid. This is both confusing and misleading since the reader is not sure anymore whether it is a mistake in the documentation, a bug in the code or something else.

Such a tool is an established standard in many programming languages ( e.g., Python's doctest), but somewhat surprisingly as of this writing in July 2020, C# lacks it. Therefore we decided to roll out dead-csharp.

Installation

Doctest-csharp is distributed and run as a dotnet tool.

To install it globally:

dotnet tool -g DoctestCsharp

or locally (if you use tool manifest, see this Microsoft tutorial):

dotnet tool install DoctestCsharp

Usage

Mark the code snippets. You need to explicitly mark which <code>...</code> snippets in your documentation should be tested by adding the doctest attribute and setting it to true.

For example:

/// <code doctest="true">
/// DoSomething("xyz")
/// </code>

Input and output. You need to specify the project folder (--input) and the folder containing the generated doctests (--output). Doctest-csharp will scan all the **/*.cs files in the input and generate the unit tests in the output.

The relative paths will be preserved. The resulting doctest files will be prefixed with DocTest.

For example:

dotnet doctest-csharp \
    --input SomeProject
    --output SomeProject.Test/doctests

Assume there exists SomeProject/SomeFile.cs. Doctest-csharp will scan it and generate the corresponding doctests to SomeProject.Test/doctests/DocTestSomeFile.cs.

Exclude. If you want to exclude certain files from the scan, use --exclude with a Glob pattern.

For example:

dotnet doctest-csharp \
    --input SomeProject
    --output SomeProject.Test/doctests
    --exclude '**/obj/**'

Using directives. You can specify using directives in the "header" of the snippet and separate them with // --- from the body of the doctest.

Only using directives, and no other statements, are allowed in the header.

For example:

/// <code doctest="true">
/// using IO = System.IO;
/// using SomeNamespace;
/// // ---
/// DoSomething(
///     new SomeNamespace.SomeClass(
///         new IO.DirectoryInfo("xyz")));
/// </code>

Generated code. We heavily use NUnit 3 in other projects, so we decided to base the generated code on that framework. Please let us know by submitting a new issue if you would like to use it with a different testing framework.

The tests will live in the same namespace as the code snippets suffixed by .Test. The doctests will be identified by line and column in the source file.

The using directives of the individual code snippets will be de-duplicated and NUnit.Framework will be automatically added.

For example, assume the following code snippet:

namespace Some.Namespace
{
    // ...

    /// <code doctest="true">
    /// using Another = AnotherNamespace;
    /// // ---
    /// Assert.AreEqual(
    ///     "abc", 
    ///     TransformSomehow(
    ///         Another.Parse("xyz")));
    /// </code>

    // ...
}

The generated test code will be similar to:

using Another = AnotherNamespace;

using NUnit.Framework;

namespace Some.Namespace.Tests
{
    // ...

    public class Doctests
    {
        public void AtLine123AndColumn8() {
            Assert.AreEqual(
                "abc", 
                TransformSomehow(
                    Another.Parse("xyz")));
        }
    }

    // ...
}

Check against a dry run. You can use doctest-csharp with --check to verify that all the available test files have been generated as in a dry run (and no obsolete test files remain).

This is particularly useful in continuous integrations where you check in your doctests in the version control and want to make sure that the developer re-generated the doctests appropriately.

For example:

dotnet doctest-csharp \
    --input SomeProject
    --output SomeProject.Test/doctests \
    -- check

Contributing

Feature requests, bug reports etc. are highly welcome! Please submit a new issue.

If you want to contribute in code, please see CONTRIBUTING.md.

Versioning

We follow Semantic Versioning. The version X.Y.Z indicates:

  • X is the major version (backward-incompatible w.r.t. command-line arguments),
  • Y is the minor version (backward-compatible), and
  • Z is the patch version (backward-compatible bug fix).

Alpha and beta pre-release versions are suffixed (e.g., 1.0.0-beta3) and do not follow the semantic versioning (i.e., final release version might be different).

About

Extracts testable C# code from structured comments to test files.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 98.9%
  • PowerShell 1.1%