Giter Site home page Giter Site logo

verify's Introduction

Verify

Build status NuGet Status NuGet Status NuGet Status NuGet Status

Verification tool to enable simple approval of complex models and documents.

Support is available via a Tidelift Subscription.

Contents

NuGet packages

Verification versus Assertion

Given the following method:

Class being tested

public static class ClassBeingTested
{
    public static Person FindPerson()
    {
        return new Person
        {
            Id = new Guid("ebced679-45d3-4653-8791-3d969c4a986c"),
            Title = Title.Mr,
            GivenNames = "John",
            FamilyName = "Smith",
            Spouse = "Jill",
            Children = new List<string>
            {
                "Sam",
                "Mary"
            },
            Address = new Address
            {
                Street = "4 Puddle Lane",
                Country = "USA"
            }
        };
    }
}

snippet source | anchor

Tests

Compare a traditional assertion based test to a verification test.

Traditional assertion test:

[Fact]
public void TraditionalTest()
{
    var person = ClassBeingTested.FindPerson();
    Assert.Equal(new Guid("ebced679-45d3-4653-8791-3d969c4a986c"), person.Id);
    Assert.Equal(Title.Mr, person.Title);
    Assert.Equal("John", person.GivenNames);
    Assert.Equal("Smith", person.FamilyName);
    Assert.Equal("Jill", person.Spouse);
    Assert.Equal(2, person.Children.Count);
    Assert.Equal("Sam", person.Children[0]);
    Assert.Equal("Mary", person.Children[1]);
    Assert.Equal("4 Puddle Lane", person.Address.Street);
    Assert.Equal("USA", person.Address.Country);
}

snippet source | anchor

Verification test

[Fact]
public Task Simple()
{
    var person = ClassBeingTested.FindPerson();
    return Verify(person);
}

snippet source | anchor

Comparing Verification to Assertion

  • Less test code: verification test require less code to write.
  • Reduced risk of incorrect test code: Given the above assertion based test it would be difficult to ensure that no property is missing from the assertion. For example if a new property is added to the model. In the verification test that change would automatically be highlighted when the test is next run.
  • Test failure visualization: Verification test allows visualization in a diff tool that works for complex models and binary documents.
  • Multiple changes visualized in singe test run: In the assertion approach, if multiple assertions require changing, this only becomes apparent over multiple test runs. In the verification approach, multiple changes can be visualized in one test run.
  • Simpler creation of test "contract": In the assertion approach, complex models can require significant code to do the initial assertion. In the verification approach, the actual test and code-under-test can be used to create that "contract". See initial verification.
  • Verification files committed to source control: All resulting verified files are committed to source control in the most appropriate format. This means these files can be viewed at any time using any tooling. The files can also be diff'd over the history of the code base. This works for any file type, for example:
    • Html content can be committed as .html files.
    • Office documents can be committed as a rendered .png (see Verify.Aspose).
    • Database schema can be committed as .sql (see Verify.SqlServer).

Usage

Class being tested

Given a class to be tested:

public static class ClassBeingTested
{
    public static Person FindPerson()
    {
        return new Person
        {
            Id = new Guid("ebced679-45d3-4653-8791-3d969c4a986c"),
            Title = Title.Mr,
            GivenNames = "John",
            FamilyName = "Smith",
            Spouse = "Jill",
            Children = new List<string>
            {
                "Sam",
                "Mary"
            },
            Address = new Address
            {
                Street = "4 Puddle Lane",
                Country = "USA"
            }
        };
    }
}

snippet source | anchor

xUnit

Support for xUnit

public class SampleTest :
    VerifyBase
{
    [Fact]
    public Task Simple()
    {
        var person = ClassBeingTested.FindPerson();
        return Verify(person);
    }

    public SampleTest(ITestOutputHelper output) :
        base(output)
    {
    }
}

snippet source | anchor

NUnit

Support for NUnit

[TestFixture]
public class SampleTest
{
    [Test]
    public Task Simple()
    {
        var person = ClassBeingTested.FindPerson();
        return Verifier.Verify(person);
    }
}

snippet source | anchor

MSTest

Support for MSTest

[TestClass]
public class SampleTest :
    VerifyBase
{
    [TestMethod]
    public Task Simple()
    {
        var person = ClassBeingTested.FindPerson();
        return Verify(person);
    }
}

snippet source | anchor

bunit

Support for rendering a Blazor Component to a verified file via bunit.

Component test

Given the following Component:

<div>
    <h1>@Title</h1>
    <button>MyButton</button>
</div>

@code {
    [Parameter]
    public string Title { get; set; } = "My Test Component";
}

snippet source | anchor

This test:

[Fact]
public Task Component()
{
    var component = RenderComponent<TestComponent>();
    return Verify(component);
}

snippet source | anchor

Will produce:

The component rendered as html ...Component.verified.html:

<div>
    <h1>My Test Component</h1>
    <button>MyButton</button>
</div>

snippet source | anchor

And the current model rendered as txt ...Component.info.verified.txt:

{
  Instance: {
    Title: 'My Test Component'
  }
}

snippet source | anchor

Initial Verification

When the test is initially run will fail with:

First verification. SampleTest.Simple.verified.txt not found.
Verification command has been copied to the clipboard.

The clipboard will contain the following:

move /Y "C:\Code\Sample\SampleTest.Simple.received.txt" "C:\Code\Sample\SampleTest.Simple.verified.txt"

If a Diff Tool is detected it will display the diff:

InitialDiff

To verify the result:

  • Execute the command from the clipboard, or
  • Use the diff tool to accept the changes, or
  • Manually copy the text to the new file

This will result in the SampleTest.Simple.verified.txt being created:

{
  GivenNames: 'John',
  FamilyName: 'Smith',
  Spouse: 'Jill',
  Address: {
    Street: '4 Puddle Lane',
    Country: 'USA'
  },
  Children: [
    'Sam',
    'Mary'
  ],
  Id: Guid_1
}

snippet source | anchor

Subsequent Verification

If the implementation of ClassBeingTested changes:

public static class ClassBeingTested
{
    public static Person FindPerson()
    {
        return new Person
        {
            Id = new Guid("ebced679-45d3-4653-8791-3d969c4a986c"),
            Title = Title.Mr,
            // Middle name added
            GivenNames = "John James",
            FamilyName = "Smith",
            Spouse = "Jill",
            Children = new List<string>
            {
                "Sam",
                "Mary"
            },
            Address = new Address
            {
                // Address changed
                Street = "64 Barnett Street",
                Country = "USA"
            }
        };
    }
}

snippet source | anchor

And the test is re run it will fail with

Verification command has been copied to the clipboard.
Assert.Equal() Failure
                                  ↓ (pos 21)
Expected: ···\n  GivenNames: 'John',\n  FamilyName: 'Smith',\n  Spouse: 'Jill···
Actual:   ···\n  GivenNames: 'John James',\n  FamilyName: 'Smith',\n  Spouse:···
                                  ↑ (pos 21)

The clipboard will again contain the following:

move /Y "C:\Code\Sample\SampleTest.Simple.received.txt" "C:\Code\Sample\SampleTest.Simple.verified.txt"

And the Diff Tool is will display the diff:

SecondDiff

The same approach can be used to verify the results and the change to SampleTest.Simple.verified.txt is committed to source control along with the change to ClassBeingTested.

Disable Clipboard

The clipboard behavior can be disable using the following:

Per Test

var settings = new VerifySettings();
settings.DisableClipboard();

snippet source | anchor

For all tests

SharedVerifySettings.DisableClipboard();

snippet source | anchor

If clipboard is disabled for all tests, it can be re-enabled at the test level:

var settings = new VerifySettings();
settings.EnableClipboard();

snippet source | anchor

For a machine

Set a Verify.DisableClipboard environment variable to true. This overrides the above settings.

AutoVerify

In some scenarios it makes sense to auto-accept any changes as part of a given test run. For example:

  • Keeping a text representation of a Database schema in a .verified.sql file (see Verify.SqlServer).

This can be done using AutoVerify():

var settings = new VerifySettings();
settings.AutoVerify();

snippet source | anchor

Note that auto accepted changes in .verified. files remain visible in source control tooling.

OnHandlers

OnFirstVerify is called when there is no verified file.

OnVerifyMismatch is called when a received file does not match the existing verified file.

public async Task OnHandlersSample()
{
    var settings = new VerifySettings();
    settings.OnFirstVerify(
        receivedFile =>
        {
            Debug.WriteLine(receivedFile);
            return Task.CompletedTask;
        });
    settings.OnVerifyMismatch(
        (receivedFile, verifiedFile, message) =>
        {
            Debug.WriteLine(receivedFile);
            Debug.WriteLine(verifiedFile);
            Debug.WriteLine(message);
            return Task.CompletedTask;
        });
    await Verify("value", settings);
}

snippet source | anchor

Received and Verified

  • All *.verified.* files should be committed to source control.
  • All *.received.* files should be excluded from source control.

Not valid json

Note that the output is technically not valid json. Single quotes are used and names are not quoted. The reason for this is to make the resulting output easier to read and understand.

Videos

Extensions

Alternatives

Projects/tools that may be a better alternative to Verify

Security contact information

To report a security vulnerability, use the Tidelift security contact. Tidelift will coordinate the fix and disclosure.

Icon

Helmet designed by Leonidas Ikonomou from The Noun Project.

verify's People

Contributors

actions-user avatar chrissie1 avatar dependabot-preview[bot] avatar dlemstra avatar mfkl avatar simoncropp avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.