Vamos a crear una nueva clase para simular un servidor para nuestros servicios y vamos a mandar a llamar a nuestro servicio Login que es de tipo Post.
Agregamos una clase llamada Servicios donde incluiremos las llamadas a nuestros servicios.
Utilizaremos un environment de testing, de esta forma en nuestro archivo Startup.cs de nuestro proyecto CaducaRest vamos a saber si el ambiente es de pruebas o de producción, si es de testing vamos a utilizar una base de datos en memoria, si no utilizaremos la de producción en este caso MySQL
También creamos un servidor de Pruebas, con la instrucción TestServer
Obtenemos nuestra base de datos y la inicializamos con valores por default.
publicclassServicios{privatestaticHttpClient httpCliente;publicstaticCaducaContext caducaContext;publicstaticvoidInicializa() { //Creamos un servidor de pruebas utilizando un ambiente //de testingvar builder =newWebHostBuilder() .UseEnvironment("IntegrationTesting") .ConfigureAppConfiguration((c, config) => {config.SetBasePath(Path.Combine(Directory.GetCurrentDirectory(),"..","..","..","..","CaducaRest"));config.AddJsonFile("appsettings.json"); }) .UseStartup<Startup>(); //Esto nos crea un servidor con los servicios rest var servidorPruebas =newTestServer(builder); //Obtenemos el objeto caducaContext caducaContext =servidorPruebas.Host.Services.GetService(typeof(CaducaContext)) asCaducaContext; //Inicializamos la bd con datos de pruebaInicializaDatos.Inicializar(caducaContext); //var total =caducaContext.Usuario.Count(); httpCliente =servidorPruebas.CreateClient(); }publicstaticasyncTask<bool> PostAsync(string servicio,object datos) {var contenido =newStringContent(JsonConvert .SerializeObject(datos),Encoding.UTF8,"application/json");var response =await httpCliente .PostAsync(servicio, contenido);if (response.StatusCode==HttpStatusCode.OK)returntrue;returnfalse; }}
En specflow, los casos de prueba se crean en archivos llamados Feature. Agregamos un nuevo Feature, damos clic con el botón derecho del mouse y damos clic en Agregar , seleccionamos SpecFlow y luego SpecFlow Feature File, tecleamos Login.feature
Nos crea un ejemplo para sumar 2 números
En Feature ponemos las precondiciones de nuestra prueba. En mi caso por simplicidad utilizaré los mismos usuarios y passwords que creamos.
Feature: Login Dado que ya existen los siguientes usuarios: Usuario NombreCarlos Carlos Hernández Maria Maria LopezJuan Juan Peréz
Puedes crear usuario de prueba en tu archivo InicializaDatos para probar con usuarios ficticios.
En specflow utilizamos escenarios para probar los diferentes casos de prueba. Agregamos un Scenario
@LoginScenario: Login con usuario Given Que Existe un usuario con la clave Carlos When Yo ejecuto el servicio Usuarios/Login Then Obtengo el nombre Carlos Hernández
Se muestran el color morado porque no hemos escrito el código para cada paso, para esto da clic con el botón derecho del mouse y da clic en Generate Step Definitinions
Esto nos creará los pasos faltantes de código, seleccionamos Generate para que nos cree los pasos en una clase nueva.
Seleccionamos la ruta donde deseamos que nos cree la clase
Nos crea una clase con cada uno de los pasos de nuestro escenario.
Podemos indicar que ciertos textos son parámetros sustituyendo el texto por (.*) y agregando una variable por cada valor que deseamos sustituir
Tecleamos el código para probar el login.
[Binding]publicclassLoginSteps{privateLoginDTO login =newLoginDTO();privateTokenDTO token =newTokenDTO(); [Given(@"Que Existe un usuario con la clave (.*)")]publicvoidGivenQueExisteUnUsarioConLaClave(string usuario) {login.Usuario= usuario;login.Password="DtfhkmTRQ8mNzgRY"; } [When(@"Yo ejecuto el servicio (.*)")]publicasyncTaskWhenYoEjecutoElServicioAsync(string nombreServicio) {Servicios.Inicializa();var response =awaitServicios.PostAsync(nombreServicio, login);if (!string.IsNullOrEmpty(response)) token =JsonSerializer.Deserialize<TokenDTO>(response); } [Then(@"Obtengo el nombre (.*)")]publicvoidThenObtengoElNombre(string nombreUsuario) {Assert.AreEqual(nombreUsuario,token.Nombre,"El nombre del usuario no coincide"); }}
Compilamos la solución para que se nos agregue al panel de Pruebas
De esta forma nuestras pruebas de integración nos pueden servir como documentación
Puedes ver la documentación aquí.
En nuestro proyecto CaducaRest cambiamos en la clase Startup.cs el método ConfigureServices la configuración de swagger para leer los comentarios xml, ya que toma en cuenta la ruta de la dll del proyecto CaducaRest y estamos simulando un servidor, no tenemos acceso a los comentarios xml agregamos un if para excluir esa parte si el assembly es TestHost el cual es el servidor de pruebas que creamos.
También cambiamos la configuración de la base de datos, para indicar que si el environment es Testing se utilice la base de datos en memoria.
publicvoidConfigureServices(IServiceCollection services){if (CurrentEnvironment.IsEnvironment("Testing")) { //Conexión en Memoriaservices.AddDbContext<CaducaContext>(opt =>opt.UseInMemoryDatabase("Caltic") .ConfigureWarnings (x =>x.Ignore( InMemoryEventId .TransactionIgnoredWarning))); }else { //Conexión MySQLservices.AddDbContext<CaducaContext>( options =>options.UseMySql(Configuration .GetConnectionString("DefaultConnection"))); } services.AddSwaggerGen(c => {c.SwaggerDoc("v1",newInfo { Title ="Api Caduca REST", Version ="v1" }); //Obtenemos el nombre de la dll por medio de reflexiónvar assemblyName =System.Reflection.Assembly .GetEntryAssembly().GetName().Name;if (assemblyName !="testhost") { //Obtenemos el directorio actualvar basePath =AppContext.BaseDirectory; //Demás código
Puedes correr las pruebas en Visual Studio y ver si cumple o no con el caso que estas probando.
Mas adelante se incluirá una sección para no almacenar los password en código.