Showing posts with label Unit Testing. Show all posts
Showing posts with label Unit Testing. Show all posts

Tuesday, October 8, 2019

What are the benefits of unit testing?

Unit testing is a software testing mechanism to determine a unit of code is working correctly and also it enforces to segregate the programming code into a smaller unit and a small unit will be always easy for developer to design, code and test compare to big module.


unit testing life cycle
Unit Testing Life Cycle


There is always a discussion happened in team, why we should spend time to write the unit testing and what’s benefit of having it.

In this article, on basis of my many years’ experience in writing unit test, I will try to explain what’s benefit you will be have to introducing the unit testing into development process.

1.   Better Design:
Before writing of actual code, we should write the unit test, it enforce you to think about the better design and deeply understanding of responsibility of component, which you are going to develop.

2.   Quality of Code
Unit testing improves the quality of the code.  In early phase, it identifies every defect that may have come up before code is sent further for deployment. Unit testing also enforce you to write the more decouple and reusable of code.

3.   Enforce Agile Process:
    It is very risky to change of old design code. In agile process, we should always ready for new requirement or changes in existing requirement and changing in existing and testable design code is very risky but if unit test is proper placed it gives confidence to developer to modify existing design or re-introduce new design.

4.   Reduce of Cost:
if you think in long term of project, unit testing always reduce the project cost, if unit test is written for developed software, the maintenance becomes more easy for developer and he can confidently modified existing code and quickly test modified code with help of unit testing and also for new development, the bugs are found early, unit testing helps reduce the cost of bug fixes. Imagine the cost of a bug found during the later stages of development, like during system testing or during acceptance testing. Of course, bugs detected earlier are easier to fix because bugs detected later are usually the result of many changes, and you don’t really know which one caused the bug.

Wednesday, August 14, 2019

C# Unit Testing – How Do Verify Exception has been thrown in unit test

In this blog, we will learn how to write the unit test that verify, the exception has been thrown in case of invalid input or validation rules violation.
There are two way, we can verify that calling method has been throw specified type exception:

·         Assert.ThrowException method
·         ExpectedException attribute 

Here is a business class, which perform the validation rule and create or update person record and if validation rule is dishonored, it throw validation exception

What are the benefits of unit testing?

public class PersonEngine
    {
        IPersonReposirty _personReposirty;

        public PersonEngine(IPersonReposirty personReposirty)
        {
            _personReposirty = personReposirty;
        }

        public Person CreatePerson(Person person)
        {
            if(person.PersonName == null)
            {
                throw new ValidationException("Person Name Cannot be blank");
            }

            if (!validSSN(person.SSN))
            {
                throw new ValidationException("SSN is not valid");
            }

           return _personReposirty.CreatePerson(person);

        }      

        private bool validSSN(string ssn)
        {
            return Regex.IsMatch(ssn, @"^(?:\d{9}|\d{3}-\d{2}-\d{4})$");        
        }
    }


The PersonEngine Class performs the below validations before call to repository object to create a new person record.

·         Person Name should not be blank.
·         SSN should be invalid format.

By Using Assert.ThrowsException method:

Here are unit tests which use Assert.ThrowsException method to verify that if the business or validation are failed, it throw Validation Exception

1.   Verify Person Name, Person Name is required

        [TestMethod]
        public void Verify_Person_Name_Blank()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = null,
                SSN = "123456789"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            Assert.ThrowsException<ValidationException>(() =>                          personEngine.CreatePerson(person));
        }

2.   Verify SSN Length, It should be 9 digit

            [TestMethod]
        public void Verify_SSN_InValid_Length()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "12345678"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            Assert.ThrowsException<ValidationException>(() =>                          personEngine.CreatePerson(person));
        }

3.   Verify SSN Format , It should be {3}-{2}-{4}

        [TestMethod]
        public void Verify_SSN_InValid_Format()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "1234-567-89"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            Assert.ThrowsException<ValidationException>(() =>                          personEngine.CreatePerson(person));
        }


Here is unit test result:




By Using ExpectedException Attribute:

Here are unit tests which use  ExpectedException Attribute to verify that if the business or validation are failed, it throw Validation Exception

1.   Verify Person Name, Person Name is required

         [TestMethod]
        [ExpectedException(typeof(ValidationException))]
        public void Verify_Person_Name_Blank()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = null,
                SSN = "123456789"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            personEngine.CreatePerson(person);          
        }

2.   Verify SSN Length, It should be 9 digit

          [TestMethod]
        [ExpectedException(typeof(ValidationException))]
        public void Verify_SSN_InValid_Length()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "12345678"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            personEngine.CreatePerson(person);
        }

3.   Verify SSN Format , It should be {3}-{2}-{4}

        [TestMethod]
        [ExpectedException(typeof(ValidationException))]
        public void Verify_SSN_InValid_Format()
        {
            PersonEngine personEngine;

            Mock<IPersonReposirty> _mockRepository = new Mock<IPersonReposirty>();
            Person person = new Person
            {
                PersonName = new PersonName { FirstName = "Tom", LastName = "Dick" },
                SSN = "1234-567-89"
            };

            _mockRepository.Setup(x => x.CreatePerson(person)).Returns(person);

            personEngine = new PersonEngine(_mockRepository.Object);

            personEngine.CreatePerson(person);
        }

Tuesday, August 6, 2019

C# - Unit Testing - How to write Data Driven Unit Test in C#

In this blog, we will discuss how to write the data driven unit test in C# and read data from csv file sequentially and iterate of unit test for each row.

Microsoft Test Framework Provides the TestContext object, which returns the current context 0f data means current iteration of data row.



    [TestClass]
    public class DataDriven_UnitTest
    {
        public TestContext TestContext { get; set; }

    }
Microsoft Test Framework provides DataSource Attribute which specifies connection string, table name and row access method like random or
Sequentially


Unit Test Data Source


Here is an example to read CSV File (Persons.csv) in unit test.

CSV File:

File Location: Data\Persons.csv
  
Data Driven Unit Test in C#


Persons.csv:

Data Driven Unit Test in C#


Unit Test Class:

[TestClass]
    public class DataDriven_UnitTest
    {
        public TestContext TestContext { get; set; }

        [TestMethod]
        [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV",
         @"|DataDirectory|\Data\Persons.csv", "Persons#csv",
         DataAccessMethod.Sequential)]
        public void Verify_Person_Name()
        {
            string _firstName =  TestContext.DataRow[0].ToString();
            string _lastName = TestContext.DataRow[1].ToString();
            string _name = TestContext.DataRow[2].ToString();

            Person person = new Person(_firstName, _lastName);
            Assert.IsTrue(person.Name == _name);

        }
    }


The Data Row object provides the collection of columns of current data row and you can read each column value by passing Column Name or Column Index

By Column Name:

string _firstName = TestContext.DataRow[FirstName].ToString();

By Column Index:

string _firstName = TestContext.DataRow[0].ToString();

Here is result of data driven unit test:
 
Data Driven Unit Test Result  in C#
Happy Testing !!

Saturday, August 3, 2019

C# - Unit Test Exception - The unit test adapter failed to connect to the data source or to read the data.

I recently tried to convert my unit test into data driven unit test, so that my unit test can able to test multiple scenarios.

For this purpose, I added one CSV data file which have multiple row and used DataSource attribute to access CSV file.

       [DataSource("Microsoft.VisualStudio.TestTools.DataSource.CSV"@"|DataDirectory|\Data\Persons.csv""Persons#csv"DataAccessMethod.Sequential)]
        public void Verify_Person_Name()
        {
            string _firstName =  TestContext.DataRow[0].ToString();
            string _lastName = TestContext.DataRow[1].ToString();
            string _name = TestContext.DataRow[2].ToString();

            Person person = new Person(_firstName, _lastName);
            Assert.IsTrue(person.Name == _name);

        }

When I ran above unit test, I got below error.

Message: The unit test adapter failed to connect to the data source or to read the data. For more information on troubleshooting this error, see "Troubleshooting Data-Driven Unit Tests" (http://go.microsoft.com/fwlink/?LinkId=62412) in the MSDN Library. Error details: The Microsoft Jet database engine could not find the object 'Persons.csv'.  Make sure the object exists and that you spell its name and the path name correctly

C# - Unit Test Exception - The unit test adapter failed to connect to the data source or to read the data.

  
I followed the below steps to fix this problem.

Step 1. Open the Property of Pesons.csv File

C# - Unit Test Exception - The unit test adapter failed to connect to the data source or to read the data.


Step 2.  Change the "Build Action" property of CSV File to Content and "Copy to Output Directory" to Copy always OR Copy if newer.


Copy to Output Directory


After made above change, ran unit test



Happy Testing!!

SQL Server - Identify unused indexes

 In this blog, we learn about the index usage information (SYS.DM_DB_INDEX_USAGE_STATS) and analyze the index usage data (USER_SEEKS, USER_S...