Skip to content
This repository has been archived by the owner on Aug 23, 2020. It is now read-only.

Latest commit

 

History

History
288 lines (219 loc) · 9.97 KB

Clase4.1_Testing.md

File metadata and controls

288 lines (219 loc) · 9.97 KB

Clase 4 - Testing

Como toda plataforma, el testing es una parte esencial del desarrollo del software. En particular en este caso, hablaremos sobre el unit testing en .NET Core.

Testing en .NET Core

Existen varias opciones para crear tests en .NET Core. La primera es elegir con que framework hacerlos:

  • xUnit: El ya visto en materias anteriores
  • NUnit: Otro framework muy conocido utilizado para hacer pruebas unitarias
  • MSTest: MSTest es un framework de microsoft muy facil de utilizar. Este sera el seleccionado para el curso

Cabe aclarar que la creacion de los proyectos de tests y la ejecución de los mismos (no importa el framework seleccionado) son realizados facilmente desde la consola y/o desde alguna extension del Visual Studio Code.

Setup

Primero agregaremos algunas extensions a VSCode que nos seran de suma utilidad.

Instalaremos .NET Core Test Explorer, esta nos permitirá explorar las pruebas creadas con mayor facilidad. Podemos buscarla desde el buscador de extensiones o en este link

.NET Core Test Explorer in marketplace

Luego lo configuraremos para que detecte nuestros proyectos de prueba. Para esto vamos a la opcion Extension Settings que se encuentra en la llave del plugin abajo a la derecha. Podemos acceder a el si nos dirijimos a donde estan todos los plugins que instalamos. Una vez encontrados ahi cambiamos la opcion de User a Workspace

work space

Aqui introdujimos una pequeña expresion regular. Los proyectos que cumplan con ella sera los que la extension utilizará para correr tests.

Creación de proyecto

Para crear un proyecto de tests, utilizaremos el comando dotnet new mstest.

dotnet new mstest -n Moodle.BusinessLogic.Test

Dentro de este proyecto, vamos a agregar un archivo de testing que se llame LogicTest.cs muy simple. Lo primero que haremos sera agregar la declaracion using using Microsoft.VisualStudio.TestTools.UnitTesting;, para indicar que estamos utilizando el framework de UnitTesting

Muy similarmente a xUnit, el framework utiliza tags (como [TestClass] o [TestMethod]) para indicar que una clase contiene tests o que un metodo es de tests. Tambien se utilizan tags para otras funcionalidades, como pasar parametros a los tests, etc. Crearemos dentro del archivo la clase LogicTest con el metodo sumIsOk.

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Moodle.BusinessLogic.Test
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void SumIsOk()
        {
        }
    }
}

Test exitoso

Es hora de crear el test. Para esto, haremos una simple suma y verificaremos que su resultado sea correcto. Lo haremos usando el metodo de Assert, Assert.IsEqual(valor1, valor2), que verifica que dos valores sean iguales

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Moodle.BusinessLogic.Test
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void SumIsOk()
        {
            int sum = 2 + 2;
            Assert.AreEqual(4, sum);
        }
    }
}

Una vez creado el test, debemos correrlo. Para esto, tenemos dos opciones. Podemos correrlo desde la consola, donde se nos mostrara el output ahi mismo:

dotnet tests

Output: consola

O podemos correrlo utilizando la extension que instalamos previamente. Para eso la seleccionamos (La proveta que se encuentra en la barra de la izquierda del VSCode) y seleccionamos el boton de play.

Output:

plugin

Test que falla

Igualmente que como creamos el anterior test, crearemos uno que falle para ver el resultado. Agregamos el siguiente test.

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Moodle.BusinessLogic.Test
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void SumIsOk()
        {
            int sum = 2 + 2;
            Assert.AreEqual(4, sum);
        }

        [TestMethod]
        public void SumIsNotReallyOk()
        {
            int sum = 2 + 3;
            Assert.AreEqual(6, sum);
        }
    }
}

Luego de correrlos nuevamente, podemos ver como el test falla:

enter image description here

Y hasta se muestra la razon de porque fallo inline:

Inline explanation

Test coverage

A pesar de no existir herramientas integradas a un IDE, como si nos pasaba con visual studio, eso no significa que sea dificil obtener el test coverage de nuestros tests. Para ellos existen excelentes herramientas que nos permitiran obtener el test coverage de manera simple. La que usaremos se llama Coverlet, y es tan facil como agregar un paquete a la libreria.

Haremos un pequeño ejemplo para mostrar como funciona esta herramienta.

Nos moveremos al proyecto de tests (cd Moodle.BusinessLogic.Test) y agregaremos una referencia al proyecto de business logic.

dotnet add reference ../Moodle.BusinessLogic

Por ultimo, dentro del proyecto de tests (Moodle.BusinessLogic.Test) agregaremos como dependencia Coverlet

dotnet add package coverlet.msbuild  

Luego para probar esta herramienta mas rapido lo que haremos es modificar la clase StudentLogic para que no haga uso del repositorio. Quedando asi:

using  System;
using  System.Collections.Generic;
using  Moodle.DataAccess;
using  Moodle.Domain;

namespace  Moodle.BusinessLogic
{
	public  class  StudentLogic
	{
		private  readonly  StudentRepository  studentRepository;

		public  StudentLogic()
		{
			MoodleContext  moodleContext = ContextFactory.GetNewContext();
			this.studentRepository = new  StudentRepository(moodleContext);
		}

		public  List<Student> GetAll()
		{
			return  this.studentRepository.GetAll();
		}

		public  Student  Get(int  id)
		{
			//return  this.studentRepository.Get(id);
			return new Student()
			{
				Id = id
			};
		}

		public  void  Add(Student  student)
		{
			this.studentRepository.Add(student);
			this.studentRepository.Save();
		}
		
	}
}

El cambio lo podemos ver en el metodo Get(int id) donde comento la linea de retorno con el repositorio e implemento un retorno simple.

Ahora pasaremos a probar este metodo desde la clase del paquete de prueba.

Agregamos la referencia a Moodle.Domain para comparar estudiantes.

Si estamos en la raiz:

dotnet add Moodle.BusinessLogic.Test reference ../Moodle.Domain

Si estamos en Moodle.BusinessLogic.Test

dotnet add reference Moodle.Domain
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moodle.BusinessLogic;

namespace Moodle.BusinessLogic.Test
{
    [TestClass]
    public class UnitTest1
    {
        private readonly StudentLogic studentLogic;

        public LogicTest()
        {
            this.studentLogic = new StudentLogic();
        }

        [TestMethod]
        public void FirstMethodIsOk()
        {
	        Student studentExpected = new Student()
	        {
		        Id = 2,
		        Name = "Daniel",
		        StudentNumber = "123456" 
	        };
            Student result = this.studentLogic.Get(2);
            
            Assert.AreEqual(studentExpected, result);
        }
    }
}

Para que esto funcione debemos implementar el metodo equals en la clase Student que solamente compare por Id;

using  System.Collections.Generic;
using System;  

namespace  Moodle.Domain
{
	public  class  Student
	{
		public  int  Id { get; set; }
		public  string  Name { get; set; }
		public  string  StudentNumber { get; set; }
		
		public  virtual  List<StudentCourse> Courses { get; set; }
		
		public  Student()
		{
			this.Courses = new  List<StudentCourse>();
		}
	
		public bool Equals(object other)
		{
			Student s = obj as Student;
			bool equals;

			if (u is null)
			{
				equals = false;
			}
			else
			{
				equals = this.Id == s.Id;
			}

			return equals;
		}
	}
}

Si corremos los tests desde la extension de VS Code, podemos ver que el test pasa correctamente.

Sin embargo, para poder ver el output del test coverage, debemos correrlo desde la consola. Dentro del proyecto, corremos el siguiente comando

dotnet test /p:CollectCoverage=true

Este comando corre los tests, y con la flat CollectCoverage=true le indicamos que efectivamente busque el code coverage. Luego de ejecutarlo, vemos el siguiente resultado:

Cobertura

Coverlet tiene muchas mas funcionalidades que pueden investigar en su documentación. Por ultimo, pueden revisar el archivo .json que es creado (su ubicación se muestra en el output de consola).