xUnit Resumen - Notas de Estudio

xUnit.net se aplica a .NET  Framework es, de código abierto, herramientas gratuitas de pruebas unitarias centrados en la comunidad.

Las ventajas de la prueba automatizada de #

  • Puede ser probado frecuentemente
  • Puede ser probado en cualquier momento, también puede ser programado de acuerdo al plan, por ejemplo: automatizado prueba puede llevarse a cabo en el medio de la noche
  • La velocidad es más rápido que las pruebas manuales
  • Puede encontrar más rápidamente los errores
  • Básicamente es muy fiable
  • Código de ensayo y código de producción de cerca
  • Haciendo equipos de desarrollo más felicidad

Las pruebas automatizadas Categoría #

unidad de control La prueba una clase o método, que tiene una profundidad mayor, la cobertura de aplicación es muy funcional.
Las pruebas de integración tiene una mejor amplitud, que puede poner a prueba los recursos web, recursos de bases de datos.
prueba prueba subcutánea en la web para un nodo en el controlador.
pruebas de interfaz de usuario es la aplicación de interfaz de prueba funcional.
De hecho comúnmente utilizado es una prueba de la unidad de pruebas e integración.

test métodos privados o de comportamiento #

Método general pública se prueba en contra de la clase, que es llevar a cabo la prueba, si es necesario cambiar los métodos privados de modificador a prueba

xUnit.Net Características: #

  • Cuando soportar múltiples plataformas / Run
  • Prueba paralelo
  • prueba controlada por datos
  • escalable

plataformas soportadas xUnit: #

Net Framework
.Net Core
Net Standard
uwp
Xamarin

sitio web oficial:
https://xunit.net

Las herramientas de prueba:

VS自带的测试浏览器(右键测试或者ctrl+r,t)
resharper,
cmd命令行(.net cli): 
	dotnet test
		dotnet test --help

Un simple ejemplo:

1, creado en VS una solución, la creación de una biblioteca de clases núcleo .NET, añadir una clase Calculadora:

namespace Demo
{
    public class Calculator
    {
        public int Add(int x,int y)
        {
            return x + y;
        }
    }
}

2, en la misma solución, cree un proyecto de prueba xUnit: DemoPrueba, para las pruebas del proyecto, por lo general lleva el nombre del nombre del proyecto + proyecto de test. Creación de una clase: CalculatorTests:

public class CalculatorTests
{
    
    [Fact]
	public void ShouldAddEquals5() //注意命名规范
	{
	    //Arrange
	    var sut = new Calculator(); //sut-system under test,通用命名
	    //Act
	    var result = sut.Add(3, 2);
	    //Assert
	    Assert.Equal(5, result);

	}
}

3,

  1. Ejecutar la prueba (ya sea el método):
    1. Vs prueba llega a través de Explorer, encontrar el proyecto de prueba, seleccione Ejecutar;

Prueba de comportamiento o métodos de ensayo privadas:

public void IncreaseHeartBeatRate()
{
    HeartBeatRate = CalculateHeartBeatRate() + 2
}

private int CalculateHeartBeatRate()
{
    var random = new Random();
    return random.Next(1,100);
}

    1. ShouldAddEquals5 por el método, la prueba de marcha o el derecho de seleccionar la tecla de acceso directo (ctrl + r, t)
    1. Por cmd, en un directorio de proyecto de prueba prueba de funcionamiento dotnet

    1. ReSharper (no se instala, consume demasiado tiempo la memoria)

Tres etapas de la prueba: AAA #

Organizar: Aquí para hacer un poco de pre-establecido. Por ejemplo, crear una instancia de objeto, la entrada de datos y similares.
Actuar: Aquí ejecutar código de producción y devuelve el resultado. Tal como llamar a métodos o configuración de las propiedades.
Afirman: resultados de la prueba Aquí, pasan o no pasan la prueba producirá dos resultados.


Afirmar

Assert caso basado en el valor de retorno del código, el estado final del objeto, tales como si el evento ocurrió para evaluar los resultados de la prueba de
los resultados puede ser Assert Pass o Falla
si todo afirma pase, después se pasa toda la prueba.
Si cualquier aserción falla, entonces los resultados hubieran fallado.

Debe haber una prueba de cuántas afirma

  1. Un enfoque simple es que cada prueba sólo hay una manera de afirmar.
  2. Y hay una sugerencia de que cada prueba que puede tener múltiples afirma, siempre y cuando éstos son afirma el mismo comportamiento para.
    xUnit proporciona los siguientes tipos de Assert:

Métodos de aserción #

Demostración:
primera construcción de un .NET  proyecto de biblioteca de clases base y, a continuación, crear un proyecto de prueba xUnit (véase el último ejemplo completo)

Assert.True, Assert.False #

 

Copiar

[Fact] [Trait("Category","New")] public void BeNewWhenCreated() { _output.WriteLine("第一个测试"); // Arrange var patient = new Patient(); // Act var result = patient.IsNew; // Assert Assert.True(result); }

Cadena de resultados de la prueba: Assert.Equal #

 

Copiar

[Fact] public void HaveCorrectFullName() { //var patient = new Patient(); _patient.FirstName = "Nick"; _patient.LastName = "Carter"; var fullName = _patient.FullName; Assert.Equal("Nick Carter", fullName); //相等 Assert.StartsWith("Nick", fullName);//以开头 Assert.EndsWith("Carter", fullName);//以结尾 Assert.Contains("Carter", fullName);//包含 Assert.Contains("Car", fullName); Assert.NotEqual("CAR", fullName);//不相等 Assert.Matches(@"^[A-Z][a-z]*\s[A-Z][a-z]*", fullName);//正则表达式 }

Digital resultados de la prueba #

 

Copiar

[Fact] [Trait("Category", "New")] public void HaveDefaultBloodSugarWhenCreated() { var p = new Patient(); var bloodSugar = p.BloodSugar; Assert.Equal(4.9f, bloodSugar,5); //判断是否相等 Assert.InRange(bloodSugar, 3.9, 6.1);//判断是否在某一范围内 }

Juicio nulo, no es nulo #

 

Copiar

[Fact] public void HaveNoNameWhenCreated() { var p = new Patient(); Assert.Null(p.FirstName); Assert.NotNull(_patient); }

Conjunto de prueba #

 

Copiar

[Fact] public void HaveHadAColdBefore() { //Arrange var _patient = new Patient(); //Act var diseases = new List<string> { "感冒", "发烧", "水痘", "腹泻" }; _patient.History.Add("发烧"); _patient.History.Add("感冒"); _patient.History.Add("水痘"); _patient.History.Add("腹泻"); //Assert //判断集合是否含有或者不含有某个元素 Assert.Contains("感冒",_patient.History); Assert.DoesNotContain("心脏病", _patient.History); //判断p.History至少有一个元素,该元素以水开头 Assert.Contains(_patient.History, x => x.StartsWith("水")); //判断集合的长度 Assert.All(_patient.History, x => Assert.True(x.Length >= 2)); //判断集合是否相等,这里测试通过,说明是比较集合元素的值,而不是比较引用 Assert.Equal(diseases, _patient.History); }

Prueba objeto #

 

Copiar

/// <summary> /// 测试Object /// </summary> [Fact] public void BeAPerson() { var p = new Patient(); var p2 = new Patient(); Assert.IsNotType<Person>(p); //测试对象是否相等,注意这里为false Assert.IsType<Patient>(p); Assert.IsAssignableFrom<Person>(p);//判断对象是否继承自Person,true //判断是否为同一个实例 Assert.NotSame(p, p2); //Assert.Same(p, p2); }

Determinar si la anormal #

 

Copiar

/// <summary> /// 判断是否发生异常 /// </summary> [Fact] public void ThrowException() //注意不能使用ctrl+R,T快捷键,因为会中断测试,抛出异常 { var p = new Patient(); //判断是否返回指定类型的异常 var ex = Assert.Throws<InvalidOperationException>(()=> { p.NotAllowed(); }); //判断异常信息是否相等 Assert.Equal("not able to create", ex.Message); }

Determinar si el evento de disparo #

 

Copiar

/// <summary> /// 判断是否触发事件 /// </summary> [Fact] public void RaizeSleepEvent() { var p = new Patient(); Assert.Raises<EventArgs>( handler=>p.PatientSlept+=handler, handler=>p.PatientSlept -= handler, () => p.Sleep()); }

Determinar si el cambio de propiedad de evento de disparo #

 

Copiar

/// <summary> /// 测试属性改变事件是否触发 /// </summary> [Fact] public void RaisePropertyChangedEvent() { var p = new Patient(); Assert.PropertyChanged(p, nameof(p.HeartBeatRate), () => p.IncreaseHeartBeatRate()); }

La agrupación, no haga caso, registro, contexto compartido

Prueba de paquetes #

Use características de rasgo, grupo de prueba: [rasgo ( "Nombre", "valor")] se pueden aplicar a los métodos y nivel de Clase clase
del mismo paquete utilizando las mismas características.

 

Copiar

[Fact] [Trait("Category","New")] public void BeNewWhenCreated() { _output.WriteLine("第一个测试"); // Arrange //var patient = new Patient(); // Act var result = _patient.IsNew; // Assert Assert.True(result); //Assert.False(result); }

Búsqueda paquete de prueba: puede pulsar dispuestos en grupos, buscar, ejecutar las pruebas en la prueba Explorador

En dotnet cli paquete de prueba:

 

Copiar

dotnew test --filter “Category=New” //运行单个分类测试 dotnew test --filter “Category=New|Category=Add”//运行多个分类测试 dotnet test --filter Category --logger:trx //输出测试日志

Haciendo caso omiso de las pruebas #

Use características: [Hecho (Skip = "no ejecutar esta prueba")], se puede ignorar la prueba ignora prueba icono de advertencia de color amarillo

prueba personalizada contenido de la salida #

Uso ITestOutputHelper puede personalizar el contenido de la salida de prueba
dotnet --filter prueba Categoría --logger: trx trx terminará prueba de salida del archivo de registro

 

Copiar

public class PatientShould:IClassFixture<LongTimeFixture>,IDisposable { private readonly ITestOutputHelper _output; private readonly Patient _patient; private readonly LongTimeTask _task; public PatientShould(ITestOutputHelper output,LongTimeFixture fixture) { this._output = output; _patient = new Patient(); //_task = new LongTimeTask(); _task = fixture.Task; } [Fact] [Trait("Category","New")] public void BeNewWhenCreated() { _output.WriteLine("第一个测试"); // Arrange //var patient = new Patient(); // Act var result = _patient.IsNew; // Assert Assert.True(result); //Assert.False(result); } }

Reducir la duplicación de código #

  1. Reducir nuevo objeto en la nueva constructor puede usarse en el método.
  2. implementos IDispose clase de prueba de una interfaz, versión de prueba completa de los recursos, la atención se llame al método Dispose después del final de cada prueba.

contexto compartido #

La misma clase de prueba #

Cuando se ejecuta un método, se necesita un evento de largo, mientras que la nueva en el constructor, cada prueba va a ser objetos nuevos o método de ejecución, que está causando la prueba muy lento. solución:

  1. Crear una clase:
 

Copiar

using Demo2; using System; namespace Demo2Test { public class LongTimeFixture : IDisposable { public LongTimeTask Task { get; } public LongTimeFixture() { } public void Dispose() { } } }

  1. implementa la clase de prueba IClassFixture <LongTimeFixture> interfaz de adquisición y método en el constructor
 

Copiar

public class PatientShould:IClassFixture<LongTimeFixture>,IDisposable { private readonly ITestOutputHelper _output; private readonly Patient _patient; private readonly LongTimeTask _task; public PatientShould(ITestOutputHelper output,LongTimeFixture fixture) { this._output = output; _patient = new Patient(); //_task = new LongTimeTask(); _task = fixture.Task;//获取方法 } }

Prueba de clase diferente #

1. En la sucesión de una, crear primero una clase que implementa TaskCollection ICollectionFixture <LongTimeFixture> Interfaz, tenga cuidado de no tener efectos secundarios, si no afectará a los resultados

 

Copiar

using Xunit; namespace Demo2Test { [CollectionDefinition("Lone Time Task Collection")] public class TaskCollection:ICollectionFixture<LongTimeFixture> { } }

  1. Uso, además de [Collection ( "Colección de tareas Lone Tiempo")]
 

Copiar

[Collection("Lone Time Task Collection")] public class PatientShould:IClassFixture<LongTimeFixture>,IDisposable { private readonly ITestOutputHelper _output; private readonly Patient _patient; private readonly LongTimeTask _task; public PatientShould(ITestOutputHelper output,LongTimeFixture fixture) { this._output = output; _patient = new Patient(); //_task = new LongTimeTask(); _task = fixture.Task;//获取方法 } }


Intercambio de datos

1. [Teoría], el método de ensayo puede tener que los parámetros de configuración de escritura que se utilizan para pasar datos InlineData #

 

Copiar

[Theory] [InlineData(1,2,3)] [InlineData(2,2,4)] [InlineData(3,3,6)] public void ShouldAddEquals(int operand1,int operand2,int expected) { //Arrange var sut = new Calculator(); //sut-system under test //Act var result = sut.Add(operand1, operand2); //Assert Assert.Equal(expected, result); }

2. [MemberData] características, pueden ser utilizados en una pluralidad de prueba #

  1. Primero se debe agregar categorías CalculatorTestData:
 

Copiar

using System.Collections.Generic; namespace DemoTest { public class CalculatorTestData { private static readonly List<object[]> Data = new List<object[]> { new object[]{ 1,2,3}, new object[]{ 1,3,4}, new object[]{ 2,4,6}, new object[]{ 0,1,1}, }; public static IEnumerable<object[]> TestData => Data; } }

  1. uso MemberData
 

Copiar

/// <summary> /// 数据共享-MemberData /// </summary> /// <param name="operand1"></param> /// <param name="operand2"></param> /// <param name="expected"></param> [Theory] [MemberData(nameof(CalculatorTestData.TestData),MemberType =typeof(CalculatorTestData))] public void ShouldAddEquals2(int operand1, int operand2, int expected) { //Arrange var sut = new Calculator(); //sut-system under test //Act var result = sut.Add(operand1, operand2); //Assert Assert.Equal(expected, result); }

3. Datos externos #

  1. Crear una clase, preparar los datos, donde los datos son csv lectura
 

Copiar

using System.Collections.Generic; using System.IO; using System.Linq; namespace DemoTest.Data { /// <summary> /// 读取文件并返回数据集合 /// </summary> public class CalculatorCsvData { public static IEnumerable<object[]> TestData { get { //把csv文件中的数据读出来,转换 string[] csvLines = File.ReadAllLines("Data\\TestData.csv"); var testCases = new List<object[]>(); foreach (var csvLine in csvLines) { IEnumerable<int> values = csvLine.Trim().Split(',').Select(int.Parse); object[] testCase = values.Cast<object>().ToArray(); testCases.Add(testCase); } return testCases; } } } }

  1. datos CSV
 

Copiar

1,2,3 1,3,4 2,4,6 0,1,1

  1. uso
 

Copiar

/// <summary> /// 数据共享-MemberData-外部数据 /// </summary> /// <param name="operand1"></param> /// <param name="operand2"></param> /// <param name="expected"></param> [Theory] [MemberData(nameof(CalculatorCsvData.TestData), MemberType = typeof(CalculatorCsvData))] public void ShouldAddEquals3(int operand1, int operand2, int expected) { //Arrange var sut = new Calculator(); //sut-system under test //Act var result = sut.Add(operand1, operand2); //Assert Assert.Equal(expected, result); }

4. Utilizar las propiedades personalizadas, heredadas de DataAttribute deberá #

  1. Propiedades personalizadas
 

Copiar

using System.Collections.Generic; using System.Reflection; using Xunit.Sdk; namespace DemoTest.Data { public class CalculatorDataAttribute : DataAttribute { public override IEnumerable<object[]> GetData(MethodInfo testMethod) { yield return new object[] { 0, 100, 100 }; yield return new object[] { 1, 99, 100 }; yield return new object[] { 2, 98, 100 }; yield return new object[] { 3, 97, 100 }; } } }

  1. uso
 

Copiar

/// <summary> /// 数据共享-自定义特性继承自DataAttribute /// </summary> /// <param name="operand1"></param> /// <param name="operand2"></param> /// <param name="expected"></param> [Theory] [CalculatorDataAttribute] public void ShouldAddEquals4(int operand1, int operand2, int expected) { //Arrange var sut = new Calculator(); //sut-system under test //Act var result = sut.Add(operand1, operand2); //Assert Assert.Equal(expected, result); }

Fuente: https://gitee.com/Alexander360/LearnXUnit

 

 

Publicado 91 artículos originales · ganado elogios 47 · Vistas a 90000 +

Supongo que te gusta

Origin blog.csdn.net/qq_30007885/article/details/105050194
Recomendado
Clasificación