View
148
Download
2
Category
Preview:
Citation preview
AGENDAa Introducción al software testing
a Pruebas Unitarias (Introducción, FIRST, Dobles)
a Principios SOLID
a TDD (Introducción, patrones y Visual Studio)
a Inyección de dependencias
Software testingIntroducción
Software testing / Introducción
¿Qué son las pruebas de software?Forma automatizada de probar, empíricamente, que un software funciona como se
espera.
¿Qué ganamos realizando pruebas de software?Fiabilidad, consistencia, eficiencia, mantenibilidad, mejor software y facilidad para el
refactoring. Pero sobre todo, dormir mucho mejor.
¿Qué precio debemos pagar?• Diseñar nuestro software para que sea testable facilmente (altamente cohesionado,
bajamente acoplado, etc).
• Crear y mantener nuestros tests como si fuese código de producción.
Class Cohesion Revisited: http://www.iro.umontreal.ca/~sahraouh/qaoose/papers/Kabaili.pdf
Software testing / Introducción
Tipos de Tests• Tests unitarios
Comprueban el correcto funcionamiento de la mínima unidad de código posible (funcionalmente significativa).
• Tests de integraciónComprueban la interacción entre distintas entidades de nuestro software.
• Tests de regresiónAseguran la inmutabilidad del funcionamiento anterior a una modificación.
• Tests de Sistema (end-to-end)Prueban completamente un sistema integrado.
• Tests de aceptaciónPrueban la funcionalidad (habitualmente desde el punto de vista del usuario final).
Pruebas unitariasIntroducción
Pruebas unitarias / Introducción
Tests unitarios• Muy útiles por el alcance de su prueba (muy concreto).
• Imprescindibles para el practicante de TDD
• Solo comprobarán uno de los comportamientos de un método de una clase.
• Suelen ser tests de “caja blanca”.
• Cumpliran los principios FIRST.
Descritos por Robert C. Martín (Uncle Bob) en su libro Clean Code.
Pruebas unitarias / Introducción
Organización de proyectos de Testing
• El proyecto de testing estará separado
del código de producción.
• Cada clase de test tendrá
correspondencia con una clase de
producción.
Pruebas unitarias / Introducción
Atributos MSTESTS
• Obligatorios• TestClass / TestMethod
• Excepciones
• Comprobaciones (Asserts)
1 using Microsoft.VisualStudio.TestTools.UnitTesting;2 3 namespace LibraryTddCourseTests4 {5 [TestClass]6 public class MyProductionClassTests7 {8 [AssemblyInitialize]9 public static void AssemblyInit(TestContext context) {}10 11 [ClassInitialize]12 public static void ClassInit(TestContext context) {}13 14 [TestInitialize]15 public void Initialize() {}16 17 [TestMethod]18 public void TestMethod1() {}19 20 [TestCleanup]21 public void CleanUp() {}22 23 [ClassCleanup]24 public static void ClassCleanUp() { }25 26 [AssemblyCleanup]27 public static void AssemblyCleanup() { }28 }29 }
http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.classinitializeattribute.classinitializeattribute.aspx
[ExpectedException(typeof(System.DivideByZeroException))]
Assert.IsTrue(1 == 1);Assert.IsNull(null);Assert.AreEqual(2, 1 + 1);......
Pruebas unitarias / Introducción
Ejecución de Tests
• Desde el Test Explorer• Denominados Test Runners
Pruebas unitarias / Introducción
Partes de un Test Unitario• Arrange
Preparación del escenario a testear.
• Act
Acto de ejecución del código que va a
devolver el resultado a testear.
• Assert
Chequeo del resultado con las
comprobaciones de resultados.
// ArrangeMyProductionClass myProductionClass = new MyProductionClass();
// Actbool result = myProductionClass.GetBooleanResult();
// AssertAssert.IsTrue(result);
Veamos unUNIT TEST
Pruebas unitariasF.I.R.S.T.
Pruebas unitarias / F.I.R.S.T.
Tests unitarios
• FastRápidos, muy rápidos
Si no se ejecutan rápidamente, no son tests unitarios
Pruebas unitarias / F.I.R.S.T.
Tests unitarios
• Isolated (Independent)Solo tendrán una razón para fallar
Independientes del resto de tests, no afectan al estado final del SUT
El orden de ejecución no debe ser determinante
Deben poder lanzarse en paralelo
Pruebas unitarias / F.I.R.S.T.
Tests unitarios
• RepeatableRepetibles, pueden ejecutarse cuantas veces se desee ofreciendo siempre el mismo
resultado.
Pruebas unitarias / F.I.R.S.T.
Tests unitarios
• Self-ValidatingDe resultado booleano (no logs, no DB, etc).
Automático (no requiere comprobación manual).
Pruebas unitarias / F.I.R.S.T.
Tests unitarios
• TimelySerán construidos en el momento oportuno, preferiblemente antes del código que
tratan de testear.
Debemos saber qué queremos construir con antelación.
Pruebas unitariasDobles (Tests Doubles)
Dobles/ Escenario
¿Y si una clase tiene dependencias?Si tiene dependencias y testeamos también esas dependencias, ¿seguro que es un
test de unidad?
¿Y si una de nuestras dependencias tiene problemas?Nuestro test fallará. Pero…
¿Realmente es un problema de nuestro código?
¿Podemos solucionar el problema o está fuera de nuestra capacidad?
¿Y si el problema es aleatorio o la dependencia es pesada?Dobles al rescate
Dobles / Escenario
SUT
Dobles / Escenario
SUT
Punto de falloPunto de fallo
Dobles / Escenario
SUT
Dobles / Introducción
¿Qué son?Objetos falsos que reemplazan a los verdaderos con el objeto de eliminar su
dependencia y poder hacer tests con comodidad.
¿En que consiste?En crear falsas clases que tendrán respuestas pre-determinadas y que inyectaremos a
nuestro SUT.
¿Cómo podemos hacer esto?Manualmente o con ‘Isolation Frameworks’ (frameworks de mocking)
Dobles / Introducción
¿Distintos tipos de tests doubles?
Hay una fina línea que los diferencia que depende del autor.• Dummy
Objetos que son pasados como relleno de dependencias. Nunca son usados.
• FakeObjetos que tienen una implementación funcional pero con atajos que les impiden ser viables para
usarse en entornos de producción (una base de datos en memoria, por ejemplo).
• StubsObjetos que se preparan para ofrecer respuestas concretas a peticiones concretas. Pueden usar
verificación de estado (Assert).
• MocksObjetos sobre los que se tiene algún tipo de expectativa. Tienen Asserts que verifican
comportamiento.
Dobles / Ejemplo
Dobles / Ejemplo01 public class CustomerService02 {03 private ICustomerRepository _customerRepository;04 private IComplaintRepository _complaintRepository;05 private ICustomerCareNotificationService _customercareNotificationService;06 07 public CustomerService(ICustomerRepository customerRepository,08 IComplaintRepository complaintRepository,09 ICustomerCareNotificationService customerCareNotificationService)10 {11 this._customerRepository = customerRepository;12 this._complaintRepository = complaintRepository;13 this._customercareNotificationService = customerCareNotificationService;14 }15 16 public List<string> Complaints(int clientId)17 {18 var complaints = _complaintRepository.GetAllFromClientId(clientId);19 20 bool isAVipCustomer = _customerRepository.GetCustomerCategory(clientId);21 if (isAVipCustomer)22 SendNotificationToCustomerCare(clientId);23 24 var result = complaints.Select(c => c.Title);25 26 return result.ToList();27 }28 29 private void SendNotificationToCustomerCare(int clientId)30 {31 this._customercareNotificationService.SendNotificationAboutVipCustomerComplaint(clientId);32 }33 }
Hagamos los testsde ejemplo con Dobles
SOLID PrinciplesIntroducción
SOLID / Introducción
Serie de principios de desarrollo en programación orientada a objetos
Originalmente recopilados por Robert C. Martín en 1995
Proporcionan un camino para conseguir código bajamente acoplado,
altamente cohesivo que encapsule las necesidades de negocio correctamente
SOLID / Introducción
No es un framework
No es una librería
No son unos patrones
No son un objetivo
Son unos principios de diseño orientado a objetos
Son un medio para conseguir código desacoplado
Y por tanto un modo de hacer código más mantenible
SOLID Principles
SOLID
SOLID / Single Responsibility Principle (SRP)
“Una clase debería tener una, y solo una, razón para cambiar”
Una clase debería tener una única responsabilidad.
Podemos aplicarlo también a los métodos de la clase.
Beneficios
Proporciona un código más desacoplado y más fácil de mantener.
Proporciona unas clases más pequeñas y limpias.
SOLID / Single Responsibility Principle (SRP)
1 public class Reception2 {3 private string _receptionistName = "Peter";4 public string GetGreeting()5 {6 return string.Format("You are Welcome, my name is {0}", _receptionistName);7 }8 9 public string GetRoomKeys()
10 {11 return "room 101";12 }13 14 public string PrintInvoce(string roomKeys)15 {16 return string.Format("Your invoice for {0}", roomKeys);17 }18 }
SOLID / Single Responsibility Principle (SRP)
1 public class Reception2 {3 private string _receptionistName = "Peter";4 public string GetGreeting()5 {6 return string.Format("You are Welcome, my name is {0}", _receptionistName);7 }8 9 public string GetRoomKeys()
10 {11 return "room 101";12 }13 14 public string PrintInvoce(string roomKeys)15 {16 return string.Format("Your invoice for {0}", roomKeys);17 }18 }
SOLID - SRP
SOLID / Single Responsibility Principle (SRP)1 public class Reception2 {3 private string _receptionistName = "Peter";4 private RoomService _roomService = new RoomService();5 private InvoicePrinter _invoicePrinter = new InvoicePrinter();6 public string GetGreeting()7 {8 return string.Format("You are Welcome, my name is {0}", _receptionistName);9 }10 11 public string GetRoomKeys()12 {13 return _roomService.GetFreeRoom();14 }15 16 public string PrintInvoce(string roomKeys)17 {18 return _invoicePrinter.Print(roomKeys);19 }20 }
SOLID / Open-Closed Principle (OCP)
“Una clase debería estar abierta a extensión pero cerrada a modificación”
Deberíamos poder cambiar o extender el comportamiento de una clase, sin
modificarla en absoluto.
Beneficios
Podemos añadir nueva funcionalidad sin dañar el código existente
SOLID / Open-Closed Principle (OCP)
1 public class InvoicePrinter2 {3 public string Print(string roomKeys)4 {5 return string.Format("Your invoice for room {0}", roomKeys);6 }7 }
1 public class Reception2 {3 private string _receptionistName = "Peter";4 private RoomService _roomService = new RoomService();5 private InvoicePrinter _invoicePrinter = new InvoicePrinter();6 7 public string GetGreeting()8 {9 return string.Format("You are Welcome, my name is {0}", _receptionistName);10 }11 12 public string GetRoomKeys()13 {14 return _roomService.GetFreeRoom();15 }16 17 public string PrintInvoce(string roomKeys)18 {19 return _invoicePrinter.Print(roomKeys);20 }21 }
SOLID - OCP
SOLID / Open-Closed Principle (OCP)
1 public abstract class InvoicePrinter2 {3 public abstract string Print(string roomKeys);4 }
1 public class Reception2 {3 private string _receptionistName = "Peter";4 private RoomService _roomService = new RoomService();5 private InvoicePrinter _invoicePrinter = new InvoiceTextPrinter();6 7 public string GetGreeting()8 {9 return string.Format("You are Welcome, my name is {0}", _receptionistName);10 }11 12 public string GetRoomKeys()13 {14 return _roomService.GetFreeRoom();15 }16 17 public string PrintInvoce(string roomKeys)18 {19 return _invoicePrinter.Print(roomKeys);20 }21 }
SOLID / Open-Closed Principle (OCP)
1 public abstract class InvoicePrinter2 {3 public abstract string Print(string roomKeys);4 }
1 public class Reception2 {3 private string _receptionistName = "Peter";4 private RoomService _roomService = new RoomService();5 private InvoicePrinter _invoicePrinter = new InvoiceHtmlPrinter();6 7 public string GetGreeting()8 {9 return string.Format("You are Welcome, my name is {0}", _receptionistName);10 }11 12 public string GetRoomKeys()13 {14 return _roomService.GetFreeRoom();15 }16 17 public string PrintInvoce(string roomKeys)18 {19 return _invoicePrinter.Print(roomKeys);20 }21 }
SOLID / Liskov Substitution Principle (LSP)
“Sustituir un objeto por una subclase de ese objeto no debería cambiar el
comportamiento o el buen funcionamiento del programa (o de su clase base)”
Si una función recibe un objeto como parámetro, de tipo X y en su lugar le
pasamos otro de tipo Y, que hereda de X, dicha función debe proceder
correctamente.
Una función que no cumple LSP, habitualmente rompe OCP, pues necesita
saber demasiado de la clase ancestro para poder modificar su funcionamiento.
SOLID / Liskov Substitution Principle (LSP)
1 static void Main(string[] args)2 {3 // Management4 InvoiceCalculator invoiceCalculator = new InvoiceCalculator();5 invoiceCalculator.Base = 1000m;6 invoiceCalculator.IVA = 0.21m;7 8 var printerForReception = new InvoiceTextPrinter();9 var reception = new Reception();10 11 // Customer12 Console.WriteLine(reception.GetGreeting());13 var roomKeys = reception.GetRoomKeys();14 15 Console.WriteLine(printerForReception.Print(roomKeys, invoiceCalculator));16 17 Console.ReadKey();18 }
SOLID / Liskov Substitution Principle (LSP)
1 static void Main(string[] args)2 {3 // Management4 InvoiceCalculator invoiceCalculator = new InvoiceForeignCalculator();5 invoiceCalculator.Base = 1000m;6 invoiceCalculator.IVA = 0.21m;7 8 var printerForReception = new InvoiceTextPrinter();9 var reception = new Reception();10 11 // Customer12 Console.WriteLine(reception.GetGreeting());13 var roomKeys = reception.GetRoomKeys();14 15 Console.WriteLine(printerForReception.Print(roomKeys, invoiceCalculator));16 17 Console.ReadKey();18 }
SOLID / Liskov Substitution Principle (LSP)
Cuando un grupo de clases incumple LSP, es muy habitual que el problema
subyacente resida en el diseño y que la única solución sea un rediseño
completo de la jerarquía de clases.
SOLID - LSP
SOLID / Liskov Substitution Principle (LSP)1 class Program2 {3 static void Main(string[] args)4 {5 // Management6 InvoiceCalculator invoiceCalculator = new InvoiceLocalCalculator(1000m, 0.21m);7 InvoiceCalculator invoiceCalculator = new InvoiceForeignCalculator(1000m);8 9 var printerForReception = new InvoiceTextPrinter();10 var reception = new Reception();11 12 // Customer13 Console.WriteLine(reception.GetGreeting());14 var roomKeys = reception.GetRoomKeys();15 16 Console.WriteLine(printerForReception.Print(roomKeys, invoiceCalculator));17 18 Console.ReadKey();19 }20 }
SOLID / Interface Segregation Principle (ISP)
“Una clase cliente no debe ser forzada a depender de un interface que no
necesita”
Si una clase cliente usa un interface con más métodos de los que ella misma
necesita es muy probable que ese interface sirva a varias clases cliente con
responsabilidades diferentes.
ISP y SRP están muy ligados. Un buen SRP habitualmente implica un buen ISP.
SOLID / Interface Segregation Principle (ISP)1 public class Receptionist : IStaff2 {3 private string _name;4 public Receptionist(string name)5 {6 this._name = name;7 }8 9 public string GetName()10 {11 return _name;12 }13 public string GetDrink(string drinkName)14 {15 throw new NotImplementedException();16 }17 public bool CheckReservation(string clientName)18 {19 return true;20 }21 }
1 public class Reception2 {3 ...6 11 public string GetDrink()12 {13 return _receptionist.GetDrink("gin tonic");14 }
SOLID - ISP
SOLID / Interface Segregation Principle (ISP)
SOLID / Dependency Inversion Principle (DIP)
“Módulos de alto nivel no deberían depender de módulos de bajo nivel.
Ambos deberían depender de abstracciones”
“Abstracciones no deberían depender de los detalles. Los detalles deberían
depender de las abstracciones”
Una clase padre, accederá a sus dependencias a través de interfaces o clases
abstractas.
Diseñaremos nuestro sistema de arriba hacia abajo, no al revés.
SOLID / Dependency Inversion Principle (DIP)
SOLID - DIP
SOLID / Dependency Inversion Principle (DIP)
Cumplimos el primer punto del Principio de
Inversión de Dependencia
SOLID / Dependency Inversion Principle (DIP)
Cumplimos los dos puntos
del Principio
Test Driven
DevelopmentIntroducción
TDD / Introducción
TODO CODIGO
FALLA
HASTA QUE SE DEMUESTRE
LO CONTRARIO
TDD / Introducción
• Cuantas veces:• Has empezado a desarrollar con especificaciones confusas
• Has descubierto, demasiado tarde, fallos en la especificación
• Has tenido un código totalmente fiable justo en el momento de terminarlo
• Has desarrollado más código del necesario
• Que nivel de estrés
• Te produce tocar un código desconocido
• Y un código de altas implicaciones/afecciones.
TDD / Introducción
¿Qué ocurre cuando el nivel de estrés se eleva?
Circulo de retroalimentación:
“Kent Beck: Test Driven Development by Example”
TDD¿Qué es? ¿Cómo se hace? ¿Cómo me beneficia?
TDD / ¿ Qué es ?
• Escribir tests antes de escribir el código
• Testear antes como una actividad de diseño de software• No testeamos para validar código, testeamos para diseñarlo
• Testear antes para evidenciar/clarificar qué debe hacer el código
TDD / Pasos
¿Qué queremos que haga el código que vamos a desarrollar?
¿Qué hechos demostrarán que nuestro código funciona?
TDD / Pasos
¿Escribimos el test?
Pensamos en el comportamiento del código y su interface público
El test fallará porque la función todavía no existe
TDD / Pasos
Escribimos el código de producción
SOLO el código necesario para pasar el test
TDD / Pasos
Refactorizamos la funcionalidad desarrollada
Durante la refactorización NO DEBEMOS cambiar la semántica (sentido)
TDD / Beneficios
• Código bajo completa especificación
• Ausencia de YAGNI (You aren’t gonna need it)
• KISS (Keep it simple, stupid). Código más simple y funcional. Se persigue
el objetivo
• Facilidad para aplicar principios SOLID
• Disminución del estrés, aumento de la confianza.
TDDPatrones de Test Driven Development
TDD / Patrones para un buen TDD / Tests List
• Realizar una lista de tests
• por funcionalidad/tarea/historia que debemos realizar
• con lo que debe ser y, también, lo que no debe ser
• si surgen nuevos tests o dudas, apuntarlos en la lista
TDD / Patrones para un buen TDD / Tests First
• escribir los tests antes del código
• romper el circulo de retroalimentación
• si se empiezan a escribir los tests después, se dejará de hacer tests-first
completamente.
• ayuda a definir:
• cual es la respuesta correcta
• cómo voy a chequearla
• donde pertenece esta funcionalidad
• como debería llamarla
TDD / Patrones para un buen TDD / Assert First
• Escribe tu Assert lo primero de todo
Queremos comprobar que el cuentakilómetros de un coche mide correctamente.
Para obtener la medición final, el vehículo debe estar apagado.
Recorremos una distancia concreta y obtenemos esa distancia.
01 [TestClass]02 public void CarTravelDistanceTest()03 {04 Assert.IsTrue(car.IsPowerOff());05 Assert.Equals(300, distance.FromStart());06 }
TDD / Patrones para un buen TDD / Assert First
• Escribe tu Assert lo primero de todo
• crece según sea necesario para alcanzar el objetivo
¿De donde sale la distancia?Del cuenta kilómetros del propio vehículo, desde luego
01 [TestClass]02 public void CarTravelDistanceTest()03 {04 Distance distance = car.DistanceFromStart();05 Assert.IsTrue(car.IsPowerOff());06 Assert.Equals(300, distance.Kilometers());07 }
TDD / Patrones para un buen TDD / Assert First
• Escribe tu Assert lo primero de todo
• crece según sea necesario para alcanzar el objetivo
¿Y el vehículo?Lo creamos y debemos conducirlo a donde queremos ir01 [TestClass]
02 public void CarTravelDistanceTest()03 {04 Car car = new Car("Opel", "blue");05 car.DriveTo("Bilbao");06 Distance distance = car.DistanceFromStart();07 Assert.IsTrue(car.IsPowerOff());08 Assert.Equals(300, distance.Kilometers());09 }
TDD / Patrones para un buen TDD / Test Data
• Usa información que sea fácil de leer
• Recuerda que escribes tests para una audiencia
• Minimiza los datos que usas• Si una lista de 3 elementos es suficiente, no pongas 10
• Como alternativa al “Test Data” está el “Realistic Data”, donde usamos
datos del mundo real.• Sistemas de tiempo real
• Buscas equiparar salidas del sistema actual con el sistema anterior
• Estás refactorizando una simulación y se espera la misma respuesta.
• Sobre todo si la precisión de coma flotante puede ser un problema.
TDD / Patrones para un buen TDD / Evident Data
• Usa datos evidentes
• Estás escribiendo tests para otros, no para el ordenador
• Deja tantas pistas como sea posible• Es posible que alguien esté leyendo tus tests el año que viene
• Y es posible que seas tu mismo
• Es preferible explicitar los cálculos:
Esto:Assert.Equals(300, distance.Kilometers());
Es peor que esto:Assert.Equals(1300 - 1000, distance.Kilometers());
TDDPatrones de barra roja (Red Bar Patterns)
TDD / Patrones de barra roja / Starter Test
• ¿Con cual de los tests de tu lista deberías empezar?• empieza por testear una variante de una operación que no haga nada
• a menudo un Starter Test es un test de alto nivel, como un test de aplicación
var allAccounts = new IDictionary<Company, IList<Accounts>>();
Assert.AreEqual( 0, allCounts.SumAllAccounts());
TDD / Patrones de barra roja / One Step Test
• ¿Cual de los tests de tu lista es el siguiente a implementar?• uno que te enseñe algo del sistema
• sepas que puedes implementar sin problemas
• represente un paso hacía el objetivo global
No se sigue un desarrollo top-down o bottom-up.
Más bien se sigue un proceso de lo conocido a lo desconocido.
Aprendiendo por el camino.
TDD / Patrones de barra roja / Explanation Test
• ¿Cómo difundir el uso de tests automatizados?• pide y da explicaciones en términos de tests
“Veamos si lo he entendido. Por ejemplo si tenemos Foo con este valor y Bar con este otro, la
respuesta debería ser X”
TDD / Patrones de barra roja / Regression Test
• ¿Qué es lo primero que haces cuando un bug/defecto es reportado?• escribe el menor test posible que falle por ese motivo
• una vez ejecutado el test y comprobado su fallo, reparamos el bug
TDDPatrones de barra verde (Green Bar Patterns)
TDD / Patrones de barra verde / Fake it (‘Til you make it)
• ¿Cuál es tu primera implementación para arreglar un test roto?• devuelve justo lo necesario para arreglarlo y nada más
• seguramente una constante es suficiente (gradualmente se convertirá en una
expresión u operación que usará variables)
Fake it causa mucha fricción en las personas. Sobre todo en programadores
experimentados.
¿Por qué hacer algo que sabes que tendrás que quitar?
Porque es vital obtener un verde rápidamente y es mejor tener algo
funcionando que no tener nada o algo que falla.
TDD / Patrones de barra verde / Triangulate
• ¿Cuánto de conservador debo ser con la abstracción de los tests?• abstrae solo cuando tengas dos o más ejemplos
Cuidado con entrar en lo que podemos denominar como el bucle de
triangulación.
[TestMeethod]public void TestSum(){
Assert.Equals(4, Sum(3, 1));}
private int Sum(int x, int y){
return 4}
[TestMeethod]public void TestSum(){
Assert.Equals(4, Sum(3, 1));Assert.Equals(5, Sum(3, 2));
}
private int Sum(int x, int y){
return x + y;}
[TestMeethod]public void TestSum(){
Assert.Equals(4, Sum(3, 1));Assert.Equals(5, Sum(3, 2));
}
private int Sum(int x, int y){
return x + y;}
TDD / Patrones de barra verde / Obvious Implementation
• ¿Cómo implementas operaciones que, para ti, son simples?• simplemente impleméntalas
Fake it y Triangulation son patrones de muy pequeños pasos.
Algunas veces ya sabes cómo se implementa una operación. Adelante!!!
Pero permanece atento a cuan a menudo recibes sorpresas en forma de
barras rojas usando Obvious y, si son demasiadas, vuelve al origen.
Ten en cuenta que Obvious es una “segunda marcha”. Vuelve a la primera
en cuanto “muerdas más de lo que puedes tragar”.
TDD / Patrones de barra verde / One to Many
• ¿Cómo implementas una operación que trabaja con colecciones?• prepara el test y ponlo verde, sin la colección
01 [TestClass]02 public void SumTest()03 {04 Assert.AreEqual(5, Calculations.Sum(5));05 }
01 public static int Sum(int number)02 {03 return number;04 }
TDD / Patrones de barra verde / One to Many
• ¿Cómo implementas una operación que trabaja con colecciones?• prepara el test y ponlo verde, sin la colección
01 [TestClass]02 public void SumTest()03 {04 Assert.AreEqual(5, Calculations.Sum(5, new int[] { 5 }));05 }
01 public static int Sum(int number, int[] values)02 {03 return number;04 }
TDD / Patrones de barra verde / One to Many
• ¿Cómo implementas una operación que trabaja con colecciones?• prepara el test y ponlo verde, sin la colección
01 [TestClass]02 public void SumTest()03 {04 Assert.AreEqual(5, Calculations.Sum(5, new int[] { 5 }));05 }
01 public static int Sum(int number, int[] values)02 {03 int result = 0;04 for (int i = 0; i < values.Length; i++)05 {06 result += values[i];07 }08 return result;09 }
TDD / Patrones de barra verde / One to Many
• ¿Cómo implementas una operación que trabaja con colecciones?• prepara el test y ponlo verde, sin la colección
01 public static int Sum(int[] values)02 {03 int result = 0;04 for (int i = 0; i < values.Length; i++)05 {06 result += values[i];07 }08 return result;09 }
06 [TestClass]07 public void SumTest()08 {09 Assert.AreEqual(5, Calculations.Sum(new int[] { 3, 2 }));10 }
SEATTLE
www.plainconcepts.com
MADRID
General Rodrigo 6Cuerpo alto, 1ª planta28003(+34) 915 346 836
BILBAO
Nervión 36ª planta48001(+34) 946 008 168
1511 Third AvenueSuite 512WA 98101(+1) 206 708 1285
www.plainconcepts.com
SEVILLA
Avd. Innovación 3Hércules, 3º planta, modulo 441020(+34) 955 222 906
Recommended