unitarias unitaria unit una test software que pruebas prueba para metodologia interfaz diseñar c# unit-testing mstest bdd mspec

c# - test - que es una prueba unitaria de software



¿Cómo escribo pruebas de unidad de estilo de especificación/contexto con un marco MSTest/xUnit? (5)

He estado usando MSpec para escribir mis pruebas unitarias y realmente prefiero el estilo BDD, creo que es mucho más legible. Ahora estoy usando Silverlight, que MSpec no admite, así que tengo que usar MSTest, pero me gustaría mantener un estilo BDD, así que estoy tratando de encontrar una manera de hacerlo.

Solo para explicar lo que estoy tratando de lograr, así es como escribiría una prueba de MSpec

[Subject(typeof(Calculator))] public class when_I_add_two_numbers : with_calculator { Establish context = () => this.Calculator = new Calculator(); Because I_add_2_and_4 = () => this.Calculator.Add(2).Add(4); It should_display_6 = () => this.Calculator.Result.ShouldEqual(6); } public class with_calculator { protected static Calculator; }

Así que con MSTest intentaría escribir la prueba de esta manera (aunque puedes ver que no funcionará porque he puesto 2 atributos de TestInitialize, pero obtienes lo que estoy tratando de hacer ...)

[TestClass] public class when_I_add_two_numbers : with_calculator { [TestInitialize] public void GivenIHaveACalculator() { this.Calculator = new Calculator(); } [TestInitialize] public void WhenIAdd2And4() { this.Calculator.Add(2).Add(4); } [TestMethod] public void ThenItShouldDisplay6() { this.Calculator.Result.ShouldEqual(6); } } public class with_calculator { protected Calculator Calculator {get;set;} }

¿Alguien puede proponer algunas sugerencias más elegantes para escribir pruebas de esta manera con MSTest?


Aunque he estado dando muchas preguntas a este tipo recientemente. Hay muchas opciones razonables y puedes crear las tuyas fácilmente, como se muestra en algunas de las respuestas de esta publicación. He estado trabajando en un marco de prueba de BDD con la intención de hacer que se extienda fácilmente a cualquier marco de prueba de unidad. Actualmente apoyo MSTest y NUnit. Se llama Given , y es de código abierto. La idea básica es bastante simple, Given proporciona envoltorios para conjuntos comunes de funciones que luego pueden implementarse para cada corredor de prueba.

El siguiente es un ejemplo de una prueba NUnit Given:

[Story(AsA = "car manufacturer", IWant = "a factory that makes the right cars", SoThat = "I can make money")] public class when_building_a_toyota : Specification { static CarFactory _factory; static Car _car; given a_car_factory = () => { _factory = new CarFactory(); }; when building_a_toyota = () => _car = _factory.Make(CarType.Toyota); [then] public void it_should_create_a_car() { _car.ShouldNotBeNull(); } [then] public void it_should_be_the_right_type_of_car() { _car.Type.ShouldEqual(CarType.Toyota); } }

Hice lo mejor que pude para mantenerme fiel a los conceptos del blog Introducing BDD de Dan North , y como tal, todo se hace usando el tipo de especificación, cuándo y luego. La forma en que se implementa le permite tener múltiples givens e incluso múltiples cuándo, y deben ejecutarse en orden (todavía verificando esto).

Además, hay un conjunto completo de extensiones de Should incluido directamente en Given. Esto permite cosas como la llamada ShouldEqual() vista anteriormente, pero está llena de métodos agradables para la comparación de colecciones y tipos, etc. Para aquellos de ustedes que están familiarizados con MSpec, básicamente los eliminé e hice algunas modificaciones para hacer que funcionen fuera de MSpec.

Sin embargo, creo que la recompensa está en el informe. El corredor de prueba está lleno del escenario que ha creado, de modo que de un vistazo puede obtener detalles sobre lo que realmente está haciendo cada prueba sin sumergirse en el código:

Además, se crea un informe HTML utilizando plantillas t4 basadas en los resultados de las pruebas para cada ensamblaje. Las clases con historias coincidentes se anidan juntas, y cada nombre de escenario se imprime para una referencia rápida. Para las pruebas anteriores, el informe se vería así:

Las pruebas fallidas se colorearán de rojo y se puede hacer clic para ver los detalles de la excepción.

Eso es practicamente todo. Lo estoy utilizando en varios proyectos en los que estoy trabajando, por lo que aún se está desarrollando activamente, pero describiría el núcleo como bastante estable. Estoy buscando una manera de compartir contextos por composición en lugar de herencia, por lo que probablemente será uno de los próximos cambios que vendrán a la luz. Llevar a la crítica. :)


Lo que piensas de esto:

[TestClass] public class when_i_add_two_numbers : with_calculator { public override void When() { this.calc.Add(2, 4); } [TestMethod] public void ThenItShouldDisplay6() { Assert.AreEqual(6, this.calc.Result); } [TestMethod] public void ThenTheCalculatorShouldNotBeNull() { Assert.IsNotNull(this.calc); } } public abstract class with_calculator : SpecificationContext { protected Calculator calc; public override void Given() { this.calc = new Calculator(); } } public abstract class SpecificationContext { [TestInitialize] public void Init() { this.Given(); this.When(); } public virtual void Given(){} public virtual void When(){} } public class Calculator { public int Result { get; private set; } public void Add(int p, int p_2) { this.Result = p + p_2; } }


Puedes usar NUnit.Specifications y escribir pruebas como esta:

using NUnit.Specifications; using Should; public class OrderSpecs { [Component] public class when_a_customer_places_an_order : ContextSpecification { static OrderService _orderService; static bool _results; static Order _order; Establish context = () => { _orderService = new OrderService(); _order = new Order(); }; Because of = () => _results = _orderService.PlaceOrder(_order); It should_successfully_place_the_order = () => _results.ShouldBeTrue(); } }


MSTestEnhancer puede ayudarlo, y usted puede obtener el paquete a través de NuGet.org .

Aquí está el código de ejemplo:

[TestClass] public class TheTestedClassTest { [ContractTestCase] public void TheTestedMethod() { "When Xxx happens, results in Yyy.".Test(() => { // Write test case code here... }); "When Zzz happens, results in Www.".Test(() => { // Write test case code here... }); } }

Y cuando vea el resultado de su prueba, obtendrá esto a continuación:

He escrito un post para presentar más información al respecto. Consulte Introducción a MSTestEnhancer para hacer que el resultado de la prueba de la unidad sea fácil de leer - walterlv para obtener más detalles.


Mark Nijhof tiene un ejemplo de hacer pruebas de estilo Given-When-Then con NUnit en su repositorio de github Fohjin.DDD .

Aquí hay un extracto del ejemplo mencionado anteriormente:

public class When_registering_an_domain_event : BaseTestFixture<PreProcessor> { /* ... */ protected override void When() { SubjectUnderTest.RegisterForPreProcessing<ClientMovedEvent>(); SubjectUnderTest.Process(); } [Then] public void Then_the_event_processors_for_client_moved_event_will_be_registered() { IEnumerable<EventProcessor> eventProcessors; EventProcessorCache.TryGetEventProcessorsFor(typeof(ClientMovedEvent), out eventProcessors); eventProcessors.Count().WillBe(1); } }

Y usted puede ver el Dado en la implementación de la clase base :

[Given] public void Setup() { CaughtException = new NoExceptionWasThrownException(); Given(); try { When(); } catch (Exception exception) { CaughtException = exception; } finally { Finally(); } }