Showing posts with label Theory. Show all posts
Showing posts with label Theory. Show all posts

Thursday, March 31, 2016

xUnit.net: Extensions Config v3.3.0

I recently made several updates to the xunit.extensions.config library, which allows you to configure theory data from your app.config file. Here are the links to the source and the NuGet package:

New Features

  • Named Parameter Support

You no longer need to configure your data by parameter index. You can now name your data for each parameter, making the configuration much easier to read and understand.

  • AppSettings Support

You can now use the standard AppSettings section of the App.config to configure your data. If no settings are found, then the framework will fallback to trying to use the standard config section.

  • Default Namespace Option

You can now provide a default namespace for your tests. This reduced the amount of redundant text in your config file, and makes test names much more concise and easy to read.

  • Extensible Data Provider

Don't want to use the existing data providers? Would you rather use a database? Now you can! Just add an AppSettings key for "TestData.ServiceFactory" that provides the fully qualified name of a static method that returns an IConfigTestDataService, and the framework will try to use that to load configuration data.

Sunday, July 13, 2014

Use RavenDB to power Data Driven xUnit Theories

I love xUnit's data driven unit tests, I also really enjoy working with RavenDB, and now I can use them together!

Data driven unit tests are very powerful tools that allow you to execute the same test code against multiple data sets. Testing frameworks such as xUnit makes this extremely easy to develop by offering an out of the box set attributes to quickly and easily annotate your test methods with dynamic data sources.

Below is some simple code that adds a RavenDataAttribute to xUnit. This attribute will pull arguments from a document database and pass them into your unit test, using the fully qualified method name as a key.

Example Unit Tests

public class RavenDataTests
{
    [Theory]
    [RavenData]
    public void PrimitiveArgs(int number, bool isDivisibleBytwo)
    {
        var remainder = number % 2;
        Assert.Equal(isDivisibleBytwo, remainder == 0);
    }
 
    [Theory]
    [RavenData]
    public void ComplexArgs(ComplexArgsModel model)
    {
        var remainder = model.Number % 2;
        Assert.Equal(model.IsDivisibleByTwo, remainder == 0);
    }
 
    [Fact(Skip = "Only run once for setup")]
    public void Setup()
    {
        var type = typeof(RavenDataTests);
 
        var primitiveArgsMethod = type.GetMethod("PrimitiveArgs");
        var primitiveArgs = new object[] { 3, false };
        RavenDataAttribute.SaveData(primitiveArgsMethod, primitiveArgs);
 
        var complexArgsMethod = type.GetMethod("ComplexArgs");
        var complexArgsModel = new ComplexArgsModel
        {
            IsDivisibleByTwo = true,
            Number = 4
        };
        RavenDataAttribute.SaveData(complexArgsMethod, complexArgsModel);
    }
 
    public class ComplexArgsModel
    {
        public int Number { get; set; }
        public bool IsDivisibleByTwo { get; set; }
    }
}

Saturday, June 14, 2014

NUnit TestCase, the Data Driven Unit Test

A while back I wrote a blog post about data driven unit testing with xUnit. Back then a reader had to correct me because I did not think that NUnit had support for such things.

NUnit 2.5 added a slew of great features for authoring your own data driven unit tests. Perhaps best of all is the amazing support that ReSharper offers for the NUnit test cases.

You really should be using these amazing features when authoring your unit tests!

Data Driven NUnit Samples

// Here is a simple example that is the equivalent of an
// inline data attribute from xUnit.
 
[TestCase(1, 2, 3)]
[TestCase(2, 3, 5)]
public void SimpleSumCase(int a, int b, int expected)
{
    var actual = a + b;
    Assert.AreEqual(expected, actual);
}
 

Saturday, April 14, 2012

xUnit Theory, the Data Driven Unit Test

Update: I have also written a post about NUnit's Data Driven TestCaseAttribute.

Do you like copying and pasting code? Neither do I.

A good set of unit tests often end up reusing the same code with varied inputs. Rather than copy and paste that test code over and over, we can use the pattern of data driven unit tests to help streamline our test fixtures. This is the practice of having a single test definition be invoked and count as multiple tests at run time. This also enables us to do other dynamic things, such as configuring our unit tests from external sources. :)

I frequently use MSTest, but it's data driven tests inconveniently require you to define a DataSource. (Updated) Come to find out NUnit does offer data driven unit tests with their TestCaseSource attribute. Meanwhile xUnit offers several lightweight and simple options for defining data driven tests, which it refers to as theories.

Let's take a look at some of xUnit's Theory data sources:

InlineData Example

public class StringTests1
{
    [Theory,
    InlineData("goodnight moon", "moon", true),
    InlineData("hello world", "hi", false)]
    public void Contains(string input, string sub, bool expected)
    {
        var actual = input.Contains(sub);
        Assert.Equal(expected, actual);
    }
}

PropertyData Example

public class StringTests2
{
    [Theory, PropertyData("SplitCountData")]
    public void SplitCount(string input, int expectedCount)
    {
        var actualCount = input.Split(' ').Count();
        Assert.Equal(expectedCount, actualCount);
    }
 
    public static IEnumerable<object[]> SplitCountData
    {
        get
        {
            // Or this could read from a file. :)
            return new[]
            {
                new object[] { "xUnit", 1 },
                new object[] { "is fun", 2 },
                new object[] { "to test with", 3 }
            };
        }
    }
}

ClassData Example

public class StringTests3
{
    [Theory, ClassData(typeof(IndexOfData))]
    public void IndexOf(string input, char letter, int expected)
    {
        var actual = input.IndexOf(letter);
        Assert.Equal(expected, actual);
    }
}
 
public class IndexOfData : IEnumerable<object[]>
{
    private readonly List<object[]> _data = new List<object[]>
    {
        new object[] { "hello world", 'w', 6 },
        new object[] { "goodnight moon", 'w', -1 }
    };
 
    public IEnumerator<object[]> GetEnumerator()
    { return _data.GetEnumerator(); }
 
    IEnumerator IEnumerable.GetEnumerator()
    { return GetEnumerator(); }
}
kick it on DotNetKicks.com

Happy testing!
Tom

Real Time Web Analytics