Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#, NUnit Assert in a Loop

I have a school assignment where I need to create a data-driven style of NUnit testing. Using the below code, I am able to get the data from the database, but everytime an 'Assert' call fails, the test is stopped.

Is there any way in which I can actually show the results of the loop as six different tests (considering I have six rows in my database)?

namespace TestClasses
{
    [TestFixture]
    public class TestingClass : ConnectionClass
    {
        private ProductManagement pm;

        [TestFixtureSetUp]
        public void CreateTestClass()
        {
            pm = new ProductManagement();
        }

        [TestCase]
        public void GetProductDetailsTest()
        {
            SqlDataAdapter da = new SqlDataAdapter("Select * From GetProductDetailsTest;", Connection);
            Database1DataSet.GetProductDetailsTestDataTable dt = new Database1DataSet.GetProductDetailsTestDataTable();
            da.Fill(dt);

            foreach (Database1DataSet.GetProductDetailsTestRow dr in dt.Rows)
            {
                if (pm.GetProductById(dr.productId) == null)
                    Assert.Fail("Id of test case: " + dr.id + ", Product id of failure: " + dr.productId);
            }
        }
    }
}

Basically what I am looking for is, for NUnit to display 3 passed tests and 3 failed tests, if possible! Any help would be greatly appreciated, thanks! :)

like image 722
Andrew Avatar asked Feb 15 '11 14:02

Andrew


3 Answers

The [TestCaseSource] attribute will allow you to do this. You can create a function that returns an enumerable list of test cases

public IEnumerable<Database1DataSet.GetProductDetailsTestRow> GetTestCases()
{
    SqlDataAdapter da = new SqlDataAdapter("Select * From GetProductDetailsTest;", Connection);
    Database1DataSet.GetProductDetailsTestDataTable dt = new Database1DataSet.GetProductDetailsTestDataTable();
    da.Fill(dt);

    foreach (Database1DataSet.GetProductDetailsTestRow dr in dt.Rows)
    {
        yield return dr;
    }
}

then you can pass a TestCaseSource in:

    [Test, TestCaseSource("GetTestCases")]
    public void GetProductDetailsTest(Database1DataSet.GetProductDetailsTestRow dr)
    {
        if (pm.GetProductById(dr.productId) == null)
            Assert.Fail("Id of test case: " + dr.id + ", Product id of failure: " + dr.productId);
        }
    }
like image 55
Mark Heath Avatar answered Oct 30 '22 18:10

Mark Heath


you can do this using the data driven tests in nunit, but i'm not sure you can do it for data that comes from the database. something along the lines of:

[TestFixture]
public class RowTestSample
{
     [RowTest]
     [Row( 1)]
     [Row( 2)]
     [Row( 3)]
     [Row( 4)]
     [Row( 5)]
     [Row( 6)]
     public void GetProductById(int productId)
     {
          Assert.That(pm.GetProductById(productId),Is.Not.Null);
     }
}

where the values in Row(n) are the product ids you want to test. This will show as 6 tests, each one with a different value.

I'm not sure if these can come from the DB, but probably this is not a good thing to be doing in the test anyway.

I'm not sure of the value in these tests either, I suppose it depends on what ProductManager is doing.

like image 32
Sam Holder Avatar answered Oct 30 '22 16:10

Sam Holder


Beside using the RowTest extension as suggested by Sam Holder you can also use the TestCaseAttribute for this:

[TestFixture]
public class TestCaseSample 
{      
    [TestCase(1)]
    [TestCase(2)]
    [TestCase(3)]
    [TestCase(4)]
    [TestCase(5)]
    [TestCase(6)]
    public void GetProductById(int productId)
    {           
        Assert.That(pm.GetProductById(productId),Is.Not.Null);
    } 
} 
like image 31
Simon Fischer Avatar answered Oct 30 '22 18:10

Simon Fischer