0

I just had to write test for a fairly standard scenario: Does one date range overlap another date range. To test that, I defined 36 cases and their expected results like this...:

[TestClass]
public class DateTimeRangeTests
{
    [TestMethod]
    public void TestDateOverlaps()
    {
        DateTime periodFrom = new DateTime(2022, 02, 01);
        DateTime periodTo = new DateTime(2022, 05, 01);

        var rangedItems = new List<RangedItemTestRow>()
        {
            new RangedItemTestRow(){ Id = 1, Start = new DateTime(2022, 01, 01), End =  new DateTime(2022, 01, 15), ExpectedOverlap = false},
            new RangedItemTestRow(){ Id = 2, Start = new DateTime(2022, 02, 01), End =  new DateTime(2022, 01, 15), ExpectedOverlap = false},
            new RangedItemTestRow(){ Id = 3, Start = new DateTime(2022, 02, 02), End =  new DateTime(2022, 01, 15), ExpectedOverlap = false},
            //etc etc etc, 36 different test-cases and their expected results

        List<RangedItemTestRow> overlappingItems = rangedItems
            .Where(x =>
                    (x.Start >= periodFrom && x.Start <= periodTo) ||
                    (x.End == periodFrom) ||
                    (x.End >= periodFrom && x.End <= periodTo) ||
                    (x.Start <= periodFrom && x.End >= periodTo)
            )
            .ToList();

        foreach (RangedItemTestRow item in rangedItems)
        {

            bool inOverlapped = overlappingItems.Any(x => x.Id == item.Id);
            Assert.AreEqual(item.ExpectedOverlap, inOverlapped, $"Id: {item.Id} | {item.Start} => {item.End} | Expected: {item.ExpectedOverlap} | Was: {inOverlapped}");
        }

    }
}

public class RangedItemTestRow
{
    public int Id { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public bool ExpectedOverlap { get; set; }
}

The important thing here is not my code and how much that LINQ-solutiuon might suck, this is just to illustrate my question.

I would love each item in the collection to show up as individual tests (because they sort of are), but writing 36 functions (which are essentially the same).

I bet this is a pretty common test scenario, and that there is some sort of best practice/method for handling/structuring it without writing xx almost identical test cases, but my google searches have given me nothing. It is probably one of those "if you know the name of the concept, easy to find - if you do not - no way to find it.

Kjensen
  • 12,447
  • 36
  • 109
  • 171
  • 2
    You haven't told us which test framework you're using. With xUnit you'd use Theory, for example. With NUnit you can use TestCase. Whichever framework you're using, research "parameterized tests". – Jon Skeet Sep 16 '22 at 14:02
  • 1
    @Jon `[TestClass]` and `[TestMethod]` should give away it's MSTest. :) – CodeCaster Sep 16 '22 at 14:03
  • 2
    @CodeCaster: That was my *guess* - but I figured there could easily be other test frameworks I'm not aware of, or compatibility attributes that could be applied to NUnit or xUnit... fundamentally, we shouldn't have to guess. – Jon Skeet Sep 16 '22 at 14:12
  • @JonSkeet Fair point, I should have specified MSTest. I added a tag now. :) – Kjensen Sep 16 '22 at 14:51
  • Looks like you want DataRow: https://www.meziantou.net/mstest-v2-data-tests.htm – Jon Skeet Sep 16 '22 at 14:54

0 Answers0