Tutorial: Prueba de una biblioteca de clases de .NET con .NET mediante Visual Studio

En este tutorial se muestra cómo automatizar las pruebas unitarias mediante la adición de un proyecto de prueba a una solución.

Requisitos previos

Crear un proyecto de prueba unitaria

Las pruebas unitarias proporcionan pruebas de software automatizadas durante el desarrollo y la publicación. MSTest es uno de los tres marcos de pruebas que puede elegir. Los otros son xUnit y nUnit.

  1. Inicie Visual Studio.

  2. Abra la solución ClassLibraryProjects que ha creado en Creación de una biblioteca de clases de .NET con Visual Studio.

  3. Agregue un nuevo proyecto de prueba unitaria denominado "StringLibraryTest" a la solución.

    1. Haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione Agregar>Nuevo proyecto.

    2. En el cuadro de búsqueda de la página Agregar un nuevo proyecto, escriba mstest. En la lista de lenguajes, elija C# o Visual Basic y, luego, en la lista de plataformas, elija Todas las plataformas.

    3. Seleccione la plantilla Proyecto de prueba de MSTest y luego Siguiente.

    4. En la página Configurar el nuevo proyecto, escriba StringLibraryTest en el cuadro Nombre del proyecto. Después, haga clic en Siguiente.

    5. En la página Información adicional, seleccione .NET 8 (versión preliminar) en el cuadro Marco de trabajo. Luego, elija Crear.

  4. Visual Studio crea el proyecto y abre el archivo de clase en la ventana de código con el siguiente código. Si no se muestra el idioma que quiere usar, cambie el selector de idioma en la parte superior de la página.

    namespace StringLibraryTest;
    
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    El código fuente creado por la plantilla de prueba unitaria hace lo siguiente:

    Cada método etiquetado con [TestMethod] en una clase de prueba etiquetada con [TestClass] se ejecuta automáticamente cuando se ejecuta la prueba unitaria.

Agregar una referencia de proyecto

Para que el proyecto de prueba funcione con la clase StringLibrary, agregue una referencia del proyecto StringLibraryTest al proyecto StringLibrary.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el nodo Dependencias del proyecto StringLibraryTest y seleccione Agregar referencia de proyecto del menú contextual.

  2. En el cuadro de diálogo Administrador de referencias, expanda el nodo Proyectos y active la casilla junto a StringLibrary. Al agregar una referencia al ensamblado StringLibrary, el compilador puede encontrar métodos StringLibrary al compilar el proyecto StringLibraryTest.

  3. Seleccione Aceptar.

Adición y ejecución de métodos de prueba unitaria

Cuando Visual Studio ejecuta una prueba unitaria, ejecuta cada método marcado con el atributo TestMethodAttribute en una clase que está marcada con el atributo TestClassAttribute. Un método de prueba finaliza cuando se encuentra el primer error, o cuando todas las pruebas contenidas en el método se han realizado correctamente.

Las pruebas más comunes llaman a los miembros de la clase Assert. Muchos métodos de aserción incluyen al menos dos parámetros, uno de los cuales es el resultado esperado de la prueba y el otro es el resultado real de la prueba. Algunos de los métodos Assert a los que se llama con más frecuencia se muestran en la tabla siguiente:

Métodos de aserción Función
Assert.AreEqual Comprueba que dos valores u objetos son iguales. La aserción da error si los valores o los objetos no son iguales.
Assert.AreSame Comprueba que dos variables de objeto hacen referencia al mismo objeto. La aserción da error si las variables hacen referencia a objetos diferentes.
Assert.IsFalse Comprueba si una condición es false. La aserción produce un error si la condición es true.
Assert.IsNotNull Comprueba que un objeto no es null. La aserción da error si el objeto es null.

También puede usar el método Assert.ThrowsException en un método de prueba para indicar el tipo de excepción que se espera que produzca. La prueba dará error si no se inicia la excepción especificada.

Al probar el método StringLibrary.StartsWithUpper, quiere proporcionar un número de cadenas que comiencen con un carácter en mayúsculas. Espera que el método devuelva true en estos casos, por lo que puede llamar al método Assert.IsTrue. Del mismo modo, quiere proporcionar un número de cadenas que comiencen con algo que no sea un carácter en mayúsculas. Espera que el método devuelva false en estos casos, por lo que puede llamar al método Assert.IsFalse.

Dado que el método de biblioteca administra cadenas, quiere asegurarse también de que administra correctamente una cadena vacía (String.Empty), una cadena válida que no tenga caracteres y cuyo Length sea 0, y una cadena null que no se haya inicializado. Se puede llamar a StartsWithUpper directamente como un método estático y pasar un argumento String único. También puede llamar a StartsWithUpper como método de extensión en una variable de string asignada a null.

Definirá tres métodos, cada uno de los cuales llama a un método Assert para cada elemento de una matriz de cadenas. Llamará a una sobrecarga de método que le permite especificar que se muestre un mensaje de error en caso de error en la prueba. El mensaje identifica la cadena que causó el error.

Para crear los métodos de prueba:

  1. En la ventana de código UnitTest1.cs o UnitTest1.vb, reemplace el código por el siguiente:

    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    La prueba de caracteres en mayúsculas en el método TestStartsWithUpper incluye la letra mayúscula griega alfa (U + 0391) y la letra mayúscula cirílica EM (U + 041C). La prueba de caracteres en minúsculas en el método TestDoesNotStartWithUpper incluye la letra griega minúscula alfa (U + 03B1) y la letra cirílica minúscula Ghe (U + 0433).

  2. En la barra de menús, seleccione Archivo>Guardar UnitTest1.cs como o Archivo>Guardar UnitTest1.vb como. En el cuadro de diálogo Guardar archivo como, seleccione la flecha junto al botón Guardar y seleccione Guardar con codificación.

    Visual Studio Save File As dialog

  3. En el cuadro de diálogo Confirmar guardar como, seleccione el botón para guardar el archivo.

  4. En el cuadro de diálogo Opciones avanzadas para guardar, seleccione Unicode (UTF-8 con firma) - Página de códigos 65001 desde la lista desplegable Codificación y seleccione Aceptar.

    Visual Studio Advanced Save Options dialog

    Si obtiene un error al guardar el código fuente en un archivo con codificación UTF-8, Visual Studio puede guardarlo como un archivo ASCII. Cuando eso suceda, el tiempo de ejecución no descodifica correctamente los caracteres UTF-8 del rango ASCII, y los resultados de la prueba no serán correctos.

  5. En la barra de menús, seleccione Prueba>Ejecutar todas las pruebas. Si no se abre la ventana Explorador de pruebas, ábrala mediante Prueba>Explorador de pruebas. Las tres pruebas se muestran en la sección Pruebas superadas y en la sección Resumen se informa del resultado de la serie de pruebas.

    Test Explorer window with passing tests

Administración de errores de prueba

Si está realizando el desarrollo controlado por pruebas (TDD), escribirá las pruebas, y estas generarán un error cuando las ejecute por primera vez. Después, agregará un código a la aplicación para que la prueba se realice correctamente. En este tutorial, ha creado la prueba después de escribir el código de la aplicación que valida, por lo que no ha podido comprobar si la prueba genera un error. Para asegurarse de que una prueba genera un error cuando espera que lo haga, agregue un valor no válido a la entrada de prueba.

  1. Modifique la matriz words en el método TestDoesNotStartWithUpper para incluir la cadena "Error". No necesita guardar el archivo porque Visual Studio guarda automáticamente archivos abiertos cuando se crea una solución para ejecutar pruebas.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Ejecute la prueba seleccionando Prueba>Ejecutar todas las pruebas de la barra de menús. En la ventana Explorador de pruebas se indica que dos pruebas se han realizado correctamente y que una ha finalizado con errores.

    Test Explorer window with failing tests

  3. Seleccione la prueba con errores, TestDoesNotStartWith.

    En la ventana Explorador de pruebas se muestra el mensaje generado por la instrucción Assert: "Error de Assert.IsFalse. Se esperaba para "Error": false; real: True". Debido al error, no se probaron todas las cadenas de la matriz después de "Error".

    Test Explorer window showing the IsFalse assertion failure

  4. Quite la cadena "Error" que agregó en el paso 1. Vuelva a ejecutar la prueba y se superarán las pruebas.

Prueba de la versión de la biblioteca

Ahora que se han superado todas las pruebas al ejecutar la versión de depuración de la biblioteca, ejecute las pruebas una vez más con la versión de lanzamiento de la biblioteca. Varios factores, como las optimizaciones del compilador, a veces pueden producir un comportamiento diferente entre las compilaciones de depuración y versión.

Para probar la compilación de versión:

  1. En la barra de herramientas de Visual Studio, cambie la configuración de compilación de Depurar a Versión.

    Visual Studio toolbar with release build highlighted

  2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto StringLibrary y seleccione Compilar desde el menú contextual para volver a compilar la biblioteca.

    StringLibrary context menu with build command

  3. Ejecute las pruebas unitarias seleccionando Prueba>Ejecutar todas las pruebas de la barra de menús. Las pruebas se superan.

Depuración de pruebas

Si usa Visual Studio como IDE, puede emplear el mismo proceso que se muestra en Tutorial: Depuración de una aplicación de consola de .NET con Visual Studio para depurar el código mediante el proyecto de prueba unitaria. En lugar de iniciar el proyecto de aplicación ShowCase, haga clic con el botón derecho en el proyecto StringLibraryTests y seleccione Depurar pruebas en el menú contextual.

Visual Studio inicia el proyecto de prueba con el depurador asociado. La ejecución se detendrá en cualquier punto de interrupción que haya agregado al proyecto de prueba o al código de la biblioteca subyacente.

Recursos adicionales

Pasos siguientes

En este tutorial, ha realizado una prueba unitaria de una biblioteca de clases. Puede poner la biblioteca a disposición de otros usuarios si la publica en NuGet como un paquete. Para obtener información sobre cómo hacerlo, realice este tutorial de NuGet:

Si publica una biblioteca como un paquete NuGet, otros usuarios pueden instalarla y usarla. Para obtener información sobre cómo hacerlo, realice este tutorial de NuGet:

No es necesario distribuir una biblioteca como un paquete. Se puede agrupar con una aplicación de consola que la use. Para aprender a publicar una aplicación de consola, vea el tutorial anterior de esta serie:

En este tutorial se muestra cómo automatizar las pruebas unitarias mediante la adición de un proyecto de prueba a una solución.

Requisitos previos

Crear un proyecto de prueba unitaria

Las pruebas unitarias proporcionan pruebas de software automatizadas durante el desarrollo y la publicación. MSTest es uno de los tres marcos de pruebas que puede elegir. Los otros son xUnit y nUnit.

  1. Inicie Visual Studio.

  2. Abra la solución ClassLibraryProjects que ha creado en Creación de una biblioteca de clases de .NET con Visual Studio.

  3. Agregue un nuevo proyecto de prueba unitaria denominado "StringLibraryTest" a la solución.

    1. Haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione Agregar>Nuevo proyecto.

    2. En el cuadro de búsqueda de la página Agregar un nuevo proyecto, escriba mstest. En la lista de lenguajes, elija C# o Visual Basic y, luego, en la lista de plataformas, elija Todas las plataformas.

    3. Seleccione la plantilla Proyecto de prueba de MSTest y luego Siguiente.

    4. En la página Configurar el nuevo proyecto, escriba StringLibraryTest en el cuadro Nombre del proyecto. Después, haga clic en Siguiente.

    5. En la página Información adicional, seleccione .NET 7 (compatibilidad estándar) en el cuadro Marco. Luego, elija Crear.

  4. Visual Studio crea el proyecto y abre el archivo de clase en la ventana de código con el siguiente código. Si no se muestra el idioma que quiere usar, cambie el selector de idioma en la parte superior de la página.

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    El código fuente creado por la plantilla de prueba unitaria hace lo siguiente:

    Cada método etiquetado con [TestMethod] en una clase de prueba etiquetada con [TestClass] se ejecuta automáticamente cuando se ejecuta la prueba unitaria.

Agregar una referencia de proyecto

Para que el proyecto de prueba funcione con la clase StringLibrary, agregue una referencia del proyecto StringLibraryTest al proyecto StringLibrary.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el nodo Dependencias del proyecto StringLibraryTest y seleccione Agregar referencia de proyecto del menú contextual.

  2. En el cuadro de diálogo Administrador de referencias, expanda el nodo Proyectos y active la casilla junto a StringLibrary. Al agregar una referencia al ensamblado StringLibrary, el compilador puede encontrar métodos StringLibrary al compilar el proyecto StringLibraryTest.

  3. Seleccione Aceptar.

Adición y ejecución de métodos de prueba unitaria

Cuando Visual Studio ejecuta una prueba unitaria, ejecuta cada método marcado con el atributo TestMethodAttribute en una clase que está marcada con el atributo TestClassAttribute. Un método de prueba finaliza cuando se encuentra el primer error, o cuando todas las pruebas contenidas en el método se han realizado correctamente.

Las pruebas más comunes llaman a los miembros de la clase Assert. Muchos métodos de aserción incluyen al menos dos parámetros, uno de los cuales es el resultado esperado de la prueba y el otro es el resultado real de la prueba. Algunos de los métodos Assert a los que se llama con más frecuencia se muestran en la tabla siguiente:

Métodos de aserción Función
Assert.AreEqual Comprueba que dos valores u objetos son iguales. La aserción da error si los valores o los objetos no son iguales.
Assert.AreSame Comprueba que dos variables de objeto hacen referencia al mismo objeto. La aserción da error si las variables hacen referencia a objetos diferentes.
Assert.IsFalse Comprueba si una condición es false. La aserción produce un error si la condición es true.
Assert.IsNotNull Comprueba que un objeto no es null. La aserción da error si el objeto es null.

También puede usar el método Assert.ThrowsException en un método de prueba para indicar el tipo de excepción que se espera que produzca. La prueba dará error si no se inicia la excepción especificada.

Al probar el método StringLibrary.StartsWithUpper, quiere proporcionar un número de cadenas que comiencen con un carácter en mayúsculas. Espera que el método devuelva true en estos casos, por lo que puede llamar al método Assert.IsTrue. Del mismo modo, quiere proporcionar un número de cadenas que comiencen con algo que no sea un carácter en mayúsculas. Espera que el método devuelva false en estos casos, por lo que puede llamar al método Assert.IsFalse.

Dado que el método de biblioteca administra cadenas, quiere asegurarse también de que administra correctamente una cadena vacía (String.Empty), una cadena válida que no tenga caracteres y cuyo Length sea 0, y una cadena null que no se haya inicializado. Se puede llamar a StartsWithUpper directamente como un método estático y pasar un argumento String único. También puede llamar a StartsWithUpper como método de extensión en una variable de string asignada a null.

Definirá tres métodos, cada uno de los cuales llama a un método Assert para cada elemento de una matriz de cadenas. Llamará a una sobrecarga de método que le permite especificar que se muestre un mensaje de error en caso de error en la prueba. El mensaje identifica la cadena que causó el error.

Para crear los métodos de prueba:

  1. En la ventana de código UnitTest1.cs o UnitTest1.vb, reemplace el código por el siguiente:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    La prueba de caracteres en mayúsculas en el método TestStartsWithUpper incluye la letra mayúscula griega alfa (U + 0391) y la letra mayúscula cirílica EM (U + 041C). La prueba de caracteres en minúsculas en el método TestDoesNotStartWithUpper incluye la letra griega minúscula alfa (U + 03B1) y la letra cirílica minúscula Ghe (U + 0433).

  2. En la barra de menús, seleccione Archivo>Guardar UnitTest1.cs como o Archivo>Guardar UnitTest1.vb como. En el cuadro de diálogo Guardar archivo como, seleccione la flecha junto al botón Guardar y seleccione Guardar con codificación.

    Visual Studio Save File As dialog

  3. En el cuadro de diálogo Confirmar guardar como, seleccione el botón para guardar el archivo.

  4. En el cuadro de diálogo Opciones avanzadas para guardar, seleccione Unicode (UTF-8 con firma) - Página de códigos 65001 desde la lista desplegable Codificación y seleccione Aceptar.

    Visual Studio Advanced Save Options dialog

    Si obtiene un error al guardar el código fuente en un archivo con codificación UTF-8, Visual Studio puede guardarlo como un archivo ASCII. Cuando eso suceda, el tiempo de ejecución no descodifica correctamente los caracteres UTF-8 del rango ASCII, y los resultados de la prueba no serán correctos.

  5. En la barra de menús, seleccione Prueba>Ejecutar todas las pruebas. Si no se abre la ventana Explorador de pruebas, ábrala mediante Prueba>Explorador de pruebas. Las tres pruebas se muestran en la sección Pruebas superadas y en la sección Resumen se informa del resultado de la serie de pruebas.

    Test Explorer window with passing tests

Administración de errores de prueba

Si está realizando el desarrollo controlado por pruebas (TDD), escribirá las pruebas, y estas generarán un error cuando las ejecute por primera vez. Después, agregará un código a la aplicación para que la prueba se realice correctamente. En este tutorial, ha creado la prueba después de escribir el código de la aplicación que valida, por lo que no ha podido comprobar si la prueba genera un error. Para asegurarse de que una prueba genera un error cuando espera que lo haga, agregue un valor no válido a la entrada de prueba.

  1. Modifique la matriz words en el método TestDoesNotStartWithUpper para incluir la cadena "Error". No necesita guardar el archivo porque Visual Studio guarda automáticamente archivos abiertos cuando se crea una solución para ejecutar pruebas.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Ejecute la prueba seleccionando Prueba>Ejecutar todas las pruebas de la barra de menús. En la ventana Explorador de pruebas se indica que dos pruebas se han realizado correctamente y que una ha finalizado con errores.

    Test Explorer window with failing tests

  3. Seleccione la prueba con errores, TestDoesNotStartWith.

    En la ventana Explorador de pruebas se muestra el mensaje generado por la instrucción Assert: "Error de Assert.IsFalse. Se esperaba para "Error": false; real: True". Debido al error, no se probaron todas las cadenas de la matriz después de "Error".

    Test Explorer window showing the IsFalse assertion failure

  4. Quite la cadena "Error" que agregó en el paso 1. Vuelva a ejecutar la prueba y se superarán las pruebas.

Prueba de la versión de la biblioteca

Ahora que se han superado todas las pruebas al ejecutar la versión de depuración de la biblioteca, ejecute las pruebas una vez más con la versión de lanzamiento de la biblioteca. Varios factores, como las optimizaciones del compilador, a veces pueden producir un comportamiento diferente entre las compilaciones de depuración y versión.

Para probar la compilación de versión:

  1. En la barra de herramientas de Visual Studio, cambie la configuración de compilación de Depurar a Versión.

    Visual Studio toolbar with release build highlighted

  2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto StringLibrary y seleccione Compilar desde el menú contextual para volver a compilar la biblioteca.

    StringLibrary context menu with build command

  3. Ejecute las pruebas unitarias seleccionando Prueba>Ejecutar todas las pruebas de la barra de menús. Las pruebas se superan.

Depuración de pruebas

Si usa Visual Studio como IDE, puede emplear el mismo proceso que se muestra en Tutorial: Depuración de una aplicación de consola de .NET con Visual Studio para depurar el código mediante el proyecto de prueba unitaria. En lugar de iniciar el proyecto de aplicación ShowCase, haga clic con el botón derecho en el proyecto StringLibraryTests y seleccione Depurar pruebas en el menú contextual.

Visual Studio inicia el proyecto de prueba con el depurador asociado. La ejecución se detendrá en cualquier punto de interrupción que haya agregado al proyecto de prueba o al código de la biblioteca subyacente.

Recursos adicionales

Pasos siguientes

En este tutorial, ha realizado una prueba unitaria de una biblioteca de clases. Puede poner la biblioteca a disposición de otros usuarios si la publica en NuGet como un paquete. Para obtener información sobre cómo hacerlo, realice este tutorial de NuGet:

Si publica una biblioteca como un paquete NuGet, otros usuarios pueden instalarla y usarla. Para obtener información sobre cómo hacerlo, realice este tutorial de NuGet:

No es necesario distribuir una biblioteca como un paquete. Se puede agrupar con una aplicación de consola que la use. Para aprender a publicar una aplicación de consola, vea el tutorial anterior de esta serie:

En este tutorial se muestra cómo automatizar las pruebas unitarias mediante la adición de un proyecto de prueba a una solución.

Requisitos previos

Crear un proyecto de prueba unitaria

Las pruebas unitarias proporcionan pruebas de software automatizadas durante el desarrollo y la publicación. MSTest es uno de los tres marcos de pruebas que puede elegir. Los otros son xUnit y nUnit.

  1. Inicie Visual Studio.

  2. Abra la solución ClassLibraryProjects que ha creado en Creación de una biblioteca de clases de .NET con Visual Studio.

  3. Agregue un nuevo proyecto de prueba unitaria denominado "StringLibraryTest" a la solución.

    1. Haga clic con el botón derecho en la solución en el Explorador de soluciones y seleccione Agregar>Nuevo proyecto.

    2. En el cuadro de búsqueda de la página Agregar un nuevo proyecto, escriba mstest. En la lista de lenguajes, elija C# o Visual Basic y, luego, en la lista de plataformas, elija Todas las plataformas.

    3. Seleccione la plantilla Proyecto de prueba de MSTest y luego Siguiente.

    4. En la página Configurar el nuevo proyecto, escriba StringLibraryTest en el cuadro Nombre del proyecto. Después, haga clic en Siguiente.

    5. En la página Información adicional, seleccione .NET 6 (Compatibilidad a largo plazo) en el cuadro de plataforma. Luego, elija Crear.

  4. Visual Studio crea el proyecto y abre el archivo de clase en la ventana de código con el siguiente código. Si no se muestra el idioma que quiere usar, cambie el selector de idioma en la parte superior de la página.

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Sub TestSub()
    
            End Sub
        End Class
    End Namespace
    

    El código fuente creado por la plantilla de prueba unitaria hace lo siguiente:

    Cada método etiquetado con [TestMethod] en una clase de prueba etiquetada con [TestClass] se ejecuta automáticamente cuando se ejecuta la prueba unitaria.

Agregar una referencia de proyecto

Para que el proyecto de prueba funcione con la clase StringLibrary, agregue una referencia del proyecto StringLibraryTest al proyecto StringLibrary.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el nodo Dependencias del proyecto StringLibraryTest y seleccione Agregar referencia de proyecto del menú contextual.

  2. En el cuadro de diálogo Administrador de referencias, expanda el nodo Proyectos y active la casilla junto a StringLibrary. Al agregar una referencia al ensamblado StringLibrary, el compilador puede encontrar métodos StringLibrary al compilar el proyecto StringLibraryTest.

  3. Seleccione Aceptar.

Adición y ejecución de métodos de prueba unitaria

Cuando Visual Studio ejecuta una prueba unitaria, ejecuta cada método marcado con el atributo TestMethodAttribute en una clase que está marcada con el atributo TestClassAttribute. Un método de prueba finaliza cuando se encuentra el primer error, o cuando todas las pruebas contenidas en el método se han realizado correctamente.

Las pruebas más comunes llaman a los miembros de la clase Assert. Muchos métodos de aserción incluyen al menos dos parámetros, uno de los cuales es el resultado esperado de la prueba y el otro es el resultado real de la prueba. Algunos de los métodos Assert a los que se llama con más frecuencia se muestran en la tabla siguiente:

Métodos de aserción Función
Assert.AreEqual Comprueba que dos valores u objetos son iguales. La aserción da error si los valores o los objetos no son iguales.
Assert.AreSame Comprueba que dos variables de objeto hacen referencia al mismo objeto. La aserción da error si las variables hacen referencia a objetos diferentes.
Assert.IsFalse Comprueba si una condición es false. La aserción produce un error si la condición es true.
Assert.IsNotNull Comprueba que un objeto no es null. La aserción da error si el objeto es null.

También puede usar el método Assert.ThrowsException en un método de prueba para indicar el tipo de excepción que se espera que produzca. La prueba dará error si no se inicia la excepción especificada.

Al probar el método StringLibrary.StartsWithUpper, quiere proporcionar un número de cadenas que comiencen con un carácter en mayúsculas. Espera que el método devuelva true en estos casos, por lo que puede llamar al método Assert.IsTrue. Del mismo modo, quiere proporcionar un número de cadenas que comiencen con algo que no sea un carácter en mayúsculas. Espera que el método devuelva false en estos casos, por lo que puede llamar al método Assert.IsFalse.

Dado que el método de biblioteca administra cadenas, quiere asegurarse también de que administra correctamente una cadena vacía (String.Empty), una cadena válida que no tenga caracteres y cuyo Length sea 0, y una cadena null que no se haya inicializado. Se puede llamar a StartsWithUpper directamente como un método estático y pasar un argumento String único. También puede llamar a StartsWithUpper como método de extensión en una variable de string asignada a null.

Definirá tres métodos, cada uno de los cuales llama a un método Assert para cada elemento de una matriz de cadenas. Llamará a una sobrecarga de método que le permite especificar que se muestre un mensaje de error en caso de error en la prueba. El mensaje identifica la cadena que causó el error.

Para crear los métodos de prueba:

  1. En la ventana de código UnitTest1.cs o UnitTest1.vb, reemplace el código por el siguiente:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using UtilityLibraries;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestStartsWithUpper()
            {
                // Tests that we expect to return true.
                string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsTrue(result,
                           string.Format("Expected for '{0}': true; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void TestDoesNotStartWithUpper()
            {
                // Tests that we expect to return false.
                string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " " };
                foreach (var word in words)
                {
                    bool result = word.StartsWithUpper();
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word, result));
                }
            }
    
            [TestMethod]
            public void DirectCallWithNullOrEmpty()
            {
                // Tests that we expect to return false.
                string?[] words = { string.Empty, null };
                foreach (var word in words)
                {
                    bool result = StringLibrary.StartsWithUpper(word);
                    Assert.IsFalse(result,
                           string.Format("Expected for '{0}': false; Actual: {1}",
                                         word == null ? "<null>" : word, result));
                }
            }
        }
    }
    
    Imports Microsoft.VisualStudio.TestTools.UnitTesting
    Imports UtilityLibraries
    
    Namespace StringLibraryTest
        <TestClass>
        Public Class UnitTest1
            <TestMethod>
            Public Sub TestStartsWithUpper()
                ' Tests that we expect to return true.
                Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsTrue(result,
                           $"Expected for '{word}': true; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub TestDoesNotStartWithUpper()
                ' Tests that we expect to return false.
                Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                                   "1234", ".", ";", " "}
                For Each word In words
                    Dim result As Boolean = word.StartsWithUpper()
                    Assert.IsFalse(result,
                           $"Expected for '{word}': false; Actual: {result}")
                Next
            End Sub
    
            <TestMethod>
            Public Sub DirectCallWithNullOrEmpty()
                ' Tests that we expect to return false.
                Dim words() As String = {String.Empty, Nothing}
                For Each word In words
                    Dim result As Boolean = StringLibrary.StartsWithUpper(word)
                    Assert.IsFalse(result,
                           $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}")
                Next
            End Sub
        End Class
    End Namespace
    

    La prueba de caracteres en mayúsculas en el método TestStartsWithUpper incluye la letra mayúscula griega alfa (U + 0391) y la letra mayúscula cirílica EM (U + 041C). La prueba de caracteres en minúsculas en el método TestDoesNotStartWithUpper incluye la letra griega minúscula alfa (U + 03B1) y la letra cirílica minúscula Ghe (U + 0433).

  2. En la barra de menús, seleccione Archivo>Guardar UnitTest1.cs como o Archivo>Guardar UnitTest1.vb como. En el cuadro de diálogo Guardar archivo como, seleccione la flecha junto al botón Guardar y seleccione Guardar con codificación.

    Visual Studio Save File As dialog

  3. En el cuadro de diálogo Confirmar guardar como, seleccione el botón para guardar el archivo.

  4. En el cuadro de diálogo Opciones avanzadas para guardar, seleccione Unicode (UTF-8 con firma) - Página de códigos 65001 desde la lista desplegable Codificación y seleccione Aceptar.

    Visual Studio Advanced Save Options dialog

    Si obtiene un error al guardar el código fuente en un archivo con codificación UTF-8, Visual Studio puede guardarlo como un archivo ASCII. Cuando eso suceda, el tiempo de ejecución no descodifica correctamente los caracteres UTF-8 del rango ASCII, y los resultados de la prueba no serán correctos.

  5. En la barra de menús, seleccione Prueba>Ejecutar todas las pruebas. Si no se abre la ventana Explorador de pruebas, ábrala mediante Prueba>Explorador de pruebas. Las tres pruebas se muestran en la sección Pruebas superadas y en la sección Resumen se informa del resultado de la serie de pruebas.

    Test Explorer window with passing tests

Administración de errores de prueba

Si está realizando el desarrollo controlado por pruebas (TDD), escribirá las pruebas, y estas generarán un error cuando las ejecute por primera vez. Después, agregará un código a la aplicación para que la prueba se realice correctamente. En este tutorial, ha creado la prueba después de escribir el código de la aplicación que valida, por lo que no ha podido comprobar si la prueba genera un error. Para asegurarse de que una prueba genera un error cuando espera que lo haga, agregue un valor no válido a la entrada de prueba.

  1. Modifique la matriz words en el método TestDoesNotStartWithUpper para incluir la cadena "Error". No necesita guardar el archivo porque Visual Studio guarda automáticamente archivos abiertos cuando se crea una solución para ejecutar pruebas.

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
    Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " }
    
    
  2. Ejecute la prueba seleccionando Prueba>Ejecutar todas las pruebas de la barra de menús. En la ventana Explorador de pruebas se indica que dos pruebas se han realizado correctamente y que una ha finalizado con errores.

    Test Explorer window with failing tests

  3. Seleccione la prueba con errores, TestDoesNotStartWith.

    En la ventana Explorador de pruebas se muestra el mensaje generado por la instrucción Assert: "Error de Assert.IsFalse. Se esperaba para "Error": false; real: True". Debido al error, no se probaron todas las cadenas de la matriz después de "Error".

    Test Explorer window showing the IsFalse assertion failure

  4. Quite la cadena "Error" que agregó en el paso 1. Vuelva a ejecutar la prueba y se superarán las pruebas.

Prueba de la versión de la biblioteca

Ahora que se han superado todas las pruebas al ejecutar la versión de depuración de la biblioteca, ejecute las pruebas una vez más con la versión de lanzamiento de la biblioteca. Varios factores, como las optimizaciones del compilador, a veces pueden producir un comportamiento diferente entre las compilaciones de depuración y versión.

Para probar la compilación de versión:

  1. En la barra de herramientas de Visual Studio, cambie la configuración de compilación de Depurar a Versión.

    Visual Studio toolbar with release build highlighted

  2. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto StringLibrary y seleccione Compilar desde el menú contextual para volver a compilar la biblioteca.

    StringLibrary context menu with build command

  3. Ejecute las pruebas unitarias seleccionando Prueba>Ejecutar todas las pruebas de la barra de menús. Las pruebas se superan.

Depuración de pruebas

Si usa Visual Studio como IDE, puede emplear el mismo proceso que se muestra en Tutorial: Depuración de una aplicación de consola de .NET con Visual Studio para depurar el código mediante el proyecto de prueba unitaria. En lugar de iniciar el proyecto de aplicación ShowCase, haga clic con el botón derecho en el proyecto StringLibraryTests y seleccione Depurar pruebas en el menú contextual.

Visual Studio inicia el proyecto de prueba con el depurador asociado. La ejecución se detendrá en cualquier punto de interrupción que haya agregado al proyecto de prueba o al código de la biblioteca subyacente.

Recursos adicionales

Pasos siguientes

En este tutorial, ha realizado una prueba unitaria de una biblioteca de clases. Puede poner la biblioteca a disposición de otros usuarios si la publica en NuGet como un paquete. Para obtener información sobre cómo hacerlo, realice este tutorial de NuGet:

Si publica una biblioteca como un paquete NuGet, otros usuarios pueden instalarla y usarla. Para obtener información sobre cómo hacerlo, realice este tutorial de NuGet:

No es necesario distribuir una biblioteca como un paquete. Se puede agrupar con una aplicación de consola que la use. Para aprender a publicar una aplicación de consola, vea el tutorial anterior de esta serie: