recipes and tricks to develop integration test and unit test in c#

@javigm

@jecaestevez

List of points to see

  • Boring introduction
  • Testing Tips
  • Advanced Techniques of Testing 
  • Conclusion

@javigm

@jecaestevez

Boring introduction

  • Manual Testing vs Automated Testing
  • Definition of Testing and Properties
  • Testing pyramid
  • Properties of good unit testing
  • Good practices of unit testing

@javigm

@jecaestevez

Manual Testing    

Boring introduction

  • Take long time during the long term

  • Require complex configuration

  • Limit visibility, difficult to do Regression Tests

  • Flexible

Automated Testing

  • Executed by tools and computer, it’s significantly faster than manual.

  • Regression Testing easy with automation tools.

  • Find more bugs than a human tester

  • Better visibility into app performance

vs

@javigm

Definition of testing and properties

Boring introduction

@javigm

  • Definition
  • Properties:
    • Reduce bugs
    • Decrease the cost of fix errors
    • High quality of code
    • Code Coverage
    • Allow safe refactors.

Testing Pyramid

Boring introduction

Altered

@jecaestevez

Properties of Unit testing

Boring introduction

@javigm

  • Automated and Repeatable.

  • Easy to implement and run quickly.

  • Fully isolated (runs independently of the other tests)

  • Readable and in case of fail must be describable and understandable

  • AAA (Arrange / Act / Assert)

Good practices of Unit Testing

Boring introduction

@javigm

  • Importance to write good unit tests

  • Choose good testing framework (Nunit or Xunit)

  • Ignore Test we are not secure (not adding comments)

  • One Assert Per Test Method (Assert with message)

  • Limit Use of Mocks

  • Don't Mock Entity Framework completely

  • Clean Code (SOLID, design patterns, DRY)

  • Testing from "top" layers
     
  • Generating assets
     
  • Smart Asserts
     

        Testing Tips

@jecaestevez

Testing from "top" layers

Testing Tips

@jecaestevez

[Authorize]
public class LocationController : ApiController
{

    // PUT api/location/5
    public LocationBase Put(int id, [FromBody]LocationBase value)
    {
    }
}
    [TestClass]
    public class LocationControllerTest
    {
        LocationController locController;

        [TestInitialize]
        public void Setup()
        {
            locController = new LocationController();
        }














    }
    [TestClass]
    public class LocationControllerTest
    {
        LocationController locController;

        [TestInitialize]
        public void Setup()
        {
            locController = new LocationController();
        }

        [TestMethod]
        public void PutNewLocation_v1()
        {
            LocationBase newLocation = new LocationBase()
            { Id = 0, DisplayName = "Los Motriles", Name = "Motril", Latitude = 36, Longitude = -3 };

            var locationSaved = locController.Put(0, newLocation);

            Assert.IsTrue(locationSaved.Id > 0);
            Assert.AreEqual(locationSaved.DisplayName, newLocation.DisplayName);
            Assert.AreEqual(locationSaved.Name, newLocation.Name);
            Assert.AreEqual(locationSaved.Latitude, newLocation.Latitude);
            Assert.AreEqual(locationSaved.Longitude, newLocation.Longitude);
        }
    }

Generating static assets

Testing Tips

@jecaestevez

[Authorize]
public class LocationController : ApiController
{

    // PUT api/location/5
    public LocationBase Put(int id, [FromBody]LocationBase value)
    {
    }
}
    [TestClass]
    public class LocationControllerTest
    {
        ........

        [TestMethod]
        public void PutNewLocation_v1()
        {
            LocationBase newLocation = new LocationBase()
            { Id = 0, DisplayName = "Los Motriles", Name = "Motril", Latitude = 36, Longitude = -3 };

            var locationSaved = locController.Put(0, newLocation);

            Assert.IsTrue(locationSaved.Id > 0);
            Assert.AreEqual(locationSaved.DisplayName, newLocation.DisplayName);
            Assert.AreEqual(locationSaved.Name, newLocation.Name);
            Assert.AreEqual(locationSaved.Latitude, newLocation.Latitude);
            Assert.AreEqual(locationSaved.Longitude, newLocation.Longitude);
        }
    }
    [TestClass]
    public class LocationControllerTest
    {
        ........

        [TestMethod]
        public void PutNewLocation_GeneratingAssets()
        {
            //First generate the json asset for example 
            //  new JavaScriptSerializer().Serialize(newLocation);

            var locJson = TestUtil.ReadJsonFile("Motril_Location.json", "..\\Assets");
            LocationBase newLocation = JsonConvert.DeserializeObject<LocationBase>(locJson);

            var locationSaved = locController.Put(0, newLocation);

            Assert.IsTrue(locationSaved.Id > 0);
            Assert.AreEqual(locationSaved.DisplayName, newLocation.DisplayName);
            Assert.AreEqual(locationSaved.Name, newLocation.Name);
            Assert.AreEqual(locationSaved.Latitude, newLocation.Latitude);
            Assert.AreEqual(locationSaved.Longitude, newLocation.Longitude);

        }
    }

Smart asserts

Testing Tips

@jecaestevez

    [TestClass]
    public class LocationControllerTest
    {
        ........

        [TestMethod]
        public void PutNewLocation_GeneratingAssets()
        {
            //First generate the json asset for example 
            //  new JavaScriptSerializer().Serialize(newLocation);

            var locJson = TestUtil.ReadJsonFile("Motril_Location.json", "..\\Assets");
            LocationBase newLocation = JsonConvert.DeserializeObject<LocationBase>(locJson);

            var locationSaved = locController.Put(0, newLocation);

            Assert.IsTrue(locationSaved.Id > 0);
            Assert.AreEqual(locationSaved.DisplayName, newLocation.DisplayName);
            Assert.AreEqual(locationSaved.Name, newLocation.Name);
            Assert.AreEqual(locationSaved.Latitude, newLocation.Latitude);
            Assert.AreEqual(locationSaved.Longitude, newLocation.Longitude);

        }
    }
    [TestClass]
    public class LocationControllerTest
    {
        ........

        [TestMethod]
        public void PutNewLocation_SmartAsserts()
        {
            
            LocationBase newLocation = ArrageLocation("Motril_Location.json", "..\\Assets");
            LocationBase resultLocation = ArrageLocation("Motril_GeoLocated.json", "..\\Assets");

            var locationSaved = locController.Put(0, newLocation);

            Assert.AreEqual(locationSaved, resultLocation);

        }

        private LocationBase ArrageLocation(string fileName,string path)
        {
            var locJson = TestUtil.ReadJsonFile(fileName, path);
            return JsonConvert.DeserializeObject<LocationBase>(locJson);
        }
    }

Smart DB asserts

Testing Tips

@jecaestevez

    [Authorize]
    public class LocationController : ApiController
    {
        // POST api/Account/Copy
        [Route("Copy")]
        public IHttpActionResult Copy(int sourceLocationId)
        {
            return Ok();
        }
    



    }
    [TestClass]
    public class LocationControllerTest
    {
        ........

        [TestMethod]
        public void PutNewLocation_SmartAsserts()
        {
            //Arrange
            LocationBase newLocation = ArrageLocation("Motril_Location.json", "..\\Assets");        
            var locationSaved = locController.Put(0, newLocation);
           
             //Act
            var locationCopied = locController.Copy(locationSaved.Id);

            //Asert
            Assert.IsTrue(ExecuteSqlStoreProcedure("assert_Copy",locationSaved.Id, locationSaved.Id));

        }

        private bool ExecuteSqlStoreProcedure(string spName,int sourceId , int destinationId)
        {
            ...........
        }
    }
  • Mocks & Stubs
  • Arrange assets with AutoFixture
  • FluentAssertions
  • Integration Test

Advanced Techniques of Testing

@javigm

We'll see

Advanced Techniques of Testing

  • Moq

  • FluentAssertions

  • AutoFixture

  • Integration Tests

Project: AdventureWorks2017 Api:

Swagger, Ninject, AutoMapper, WebActivatorEx, EF6

@javigm

Mock , Fixture & FluentAssertions

@javigm

Advanced Techniques of Testing

Stub, Fixture & FluentAssertions

@javigm

Advanced Techniques of Testing

Testing from Top Layer

@javigm

Advanced Techniques of Testing

Transaction Scope

@javigm

Advanced Techniques of Testing

  • Boring introduction
  • Advanced Techniques of Testing
  • Testing Tips
  • Conclusions & Biography

List of points to see 

@javigm

@jecaestevez

Conclusions

@jecaestevez

@javigm

Biography

The Art Of Unit Testing  

Clean Code:
A Handbook of Agile   Software Craftsmanship

@javigm

@jecaestevez

recipes and tricks to develop integration test and unit test in c#

By Jesús Estévez

recipes and tricks to develop integration test and unit test in c#

  • 701