12.4 Creando pruebas para el login

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.

public class Servicios
{
    private static HttpClient httpCliente;
    public static CaducaContext caducaContext;

    public static void Inicializa()
    {
        //Creamos un servidor de pruebas utilizando un ambiente
        //de testing
        var builder = new WebHostBuilder()
                .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 = new TestServer(builder);
        //Obtenemos el objeto caducaContext
        caducaContext = servidorPruebas.Host.Services.GetService(typeof(CaducaContext)) as CaducaContext;
        //Inicializamos la bd con datos de prueba
        InicializaDatos.Inicializar(caducaContext);
        //var total =caducaContext.Usuario.Count();
        httpCliente = servidorPruebas.CreateClient();
    }

    public static async Task<bool> PostAsync(string servicio, 
                                             object datos)
    {
        var contenido = new StringContent(JsonConvert
                         .SerializeObject(datos), 
                             Encoding.UTF8, 
                             "application/json");
        var response = await httpCliente
                                  .PostAsync(servicio, contenido);
        if (response.StatusCode == HttpStatusCode.OK)
            return true;
        return false;
    }
}

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  Nombre
Carlos   Carlos Hernández 
Maria    Maria Lopez
Juan     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

@Login
Scenario: 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]
public class LoginSteps
{
    private LoginDTO login = new LoginDTO();
    private TokenDTO token = new TokenDTO();

    [Given(@"Que Existe un usuario con la clave (.*)")]
    public void GivenQueExisteUnUsarioConLaClave(string usuario)
    {
        login.Usuario = usuario;
        login.Password = "DtfhkmTRQ8mNzgRY";
    }
    
    [When(@"Yo ejecuto el servicio (.*)")]
    public async Task WhenYoEjecutoElServicioAsync(string nombreServicio)
    {
        Servicios.Inicializa();
        var response = await Servicios.PostAsync(nombreServicio, login);
        if (!string.IsNullOrEmpty(response))
            token = JsonSerializer.Deserialize<TokenDTO>(response);
    }

    [Then(@"Obtengo el nombre (.*)")]
    public void ThenObtengoElNombre(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.

public void ConfigureServices(IServiceCollection services)
{
    if (CurrentEnvironment.IsEnvironment("Testing"))
    {
        //Conexión en Memoria
        services.AddDbContext<CaducaContext>(opt =>
                                   opt.UseInMemoryDatabase("Caltic")
                                   .ConfigureWarnings
                                   (x => x.Ignore(
                                   InMemoryEventId
                                        .TransactionIgnoredWarning)));
     }
     else
     {
        //Conexión MySQL
        services.AddDbContext<CaducaContext>(
            options => options.UseMySql(Configuration
                    .GetConnectionString("DefaultConnection")));
    } 
    services.AddSwaggerGen(c =>
    {
        c.SwaggerDoc("v1", new Info { Title = "Api Caduca REST", 
               Version = "v1" });
        //Obtenemos el nombre de la dll por medio de reflexión
        var assemblyName = System.Reflection.Assembly
                      .GetEntryAssembly().GetName().Name;
        if (assemblyName != "testhost")
        {
            //Obtenemos el directorio actual
            var 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.

Last updated