Pregunta Pruebas unitarias: ¿por qué el argumento esperado siempre es primero en las pruebas de igualdad?


¿Por qué es que cada marco de pruebas de unidades (lo sé de :) requiere que el valor esperado en las pruebas de igualdad siempre sea el primer argumento?

Assert.AreEqual(42, Util.GetAnswerToLifeTheUniverseAndEverything());

assertEquals(42, Util.GetAnswerToLifeTheUniverseAndEverything());

etc.

Ahora estoy bastante acostumbrado, pero cada codificador que trato de enseñar prueba unitaria comete el error de invertir los argumentos, lo cual entiendo perfectamente. Google no ayudó, ¿tal vez uno de los evaluadores de unidades de núcleo duro aquí sabe la respuesta?


32
2018-02-17 15:45


origen


Respuestas:


Creo que es solo una convención ahora y, como dijiste, es adoptada por "cada marco de pruebas de unidades (lo sé)". Si está utilizando un marco, sería molesto cambiar a otro marco que use la convención opuesta. Entonces (si está escribiendo un nuevo marco de prueba de unidades, por ejemplo) sería preferible que usted también siga la convención existente. Creo que esto proviene de la forma en que algunos desarrolladores prefieren escribir sus pruebas de igualdad:

if (4 == myVar)

Para evitar cualquier asignación no deseada, por error, escriba uno "=" en lugar de "==". En este caso, el compilador detectará este error y evitará muchos problemas al intentar solucionar un extraño error de tiempo de ejecución.


9
2018-02-17 15:54



Parece que la mayoría de los marcos iniciales utilizados esperado antes de real (Por alguna razón desconocida, ¿quizás tirar los dados?). Sin embargo, con el desarrollo de lenguajes de programación, y aumentado fluidez del código, esa orden se revirtió. La mayoría de las interfaces fluidas generalmente intentan imitar lenguaje natural y los marcos de prueba de la unidad no son diferentes.

En la afirmación, queremos asegurar que algún objeto coincide con algunas condiciones. Esta es la forma de lenguaje natural, como si fuera a explicar su código de prueba, probablemente dijera

"En esta prueba, me aseguro de que el valor calculado sea igual a 5"

en lugar de

"En esta prueba, me aseguro de que 5 sea igual al valor calculado".

La diferencia puede no ser enorme, pero vamos más allá. Considera esto:

Assert.That(Roses, Are(Red));

Suena bien. Ahora:

Assert.That(Red, Are(Roses));

Hm ...? Probablemente no te sorprendas si alguien te dijera eso las rosas son rojas. Otro camino alrededor, rojo son rosas, plantea preguntas sospechosas. Yoda¿Alguien?

That doesn't sound natural at all

Yoda está haciendo un punto importante: el orden inverso te obliga a pensar.

Se pone aún más antinatural cuando tus afirmaciones son más complejas:

Assert.That(Forest, Has.MoreThan(15, Trees));

¿Cómo revertirías ese? El bosque tiene más de 15 árboles?

Esta afirmación (la fluidez como factor de impulso para la modificación) se refleja de alguna manera en el cambio que ha experimentado NUnit: originalmente (Assert.AreEqual) solía esperado antes de real (viejo estilo). Extensiones fluidas (o para usar la terminología de NUnit, basado en restricciones - Assert.That) revirtió ese orden.


26
2018-02-17 15:58



Nadie sabe y es la fuente de confusiones sin fin. Sin embargo, no todos los marcos siguen este patrón (para una mayor confusión):

  1. FEST-Assertusos normal orden:

    assertThat(Util.GetAnswerToLifeTheUniverseAndEverything()).isEqualTo(42);
    
  2. Hamcrest:

    assertThat(Util.GetAnswerToLifeTheUniverseAndEverything(), equalTo(42))
    
  3. ScalaTest realmente no hace una distinción:

    Util.GetAnswerToLifeTheUniverseAndEverything() should equal (42)
    

5
2018-02-17 15:47



No sé, pero he sido parte de varias discusiones animadas sobre el orden de los argumentos para las pruebas de igualdad en general.

Hay mucha gente que piensa

if (42 == answer) {
  doSomething();
}

es preferible

if (answer == 42) {
  doSomething();
}

en lenguajes basados ​​en C. La razón de esto es que si colocas accidentalmente un solo signo igual:

if (42 = answer) {
  doSomething();
}

le dará un error de compilación, pero

if (answer = 42) {
  doSomething();
}

podría no, y definitivamente introduciría un error que podría ser difícil de rastrear. Entonces, quién sabe, tal vez la persona / personas que establecieron el marco de pruebas unitarias estaban acostumbradas a pensar en pruebas de igualdad de esta manera, o copiaban otros marcos de pruebas unitarias que ya estaban configurados de esta manera.


3
2018-02-17 15:55



Creo que es porque JUnit fue el precursor de la mayoría de los marcos de prueba de unidades (no porque fuera el primer marco de pruebas de unidades, sino que dio inicio a una explosión en las pruebas unitarias). Como JUnit lo hizo de esa manera, todos los marcos posteriores copiaron esta forma y se convirtió en una convención.

¿Por qué JUnit lo hizo de esa manera? No lo sé, pregúntale a Kent Beck.


1
2018-02-17 15:56



Bueno, tenían que elegir una convención. Si quieres revertirlo, prueba los adaptadores Hamcrest. Están destinados a ayudar a aumentar la legibilidad. Aquí hay una muestra básica:

import org.junit.Test;
import static org.junit.Assert.assertThat;
import static org.hamcrest.core.Is.is;

public HamcrestTest{
   @Test
   public void matcherShouldWork(){
       assertThat(   Math.pow( 2, 3 ),  is( 8 )  );
   }
}

0
2018-02-17 17:41



Porque, desafortunadamente, no muchos programadores han leído Autosuficiencia por Ralph Waldo Emerson.


0
2017-08-06 18:54



Seguramente tiene sentido lógico poner primero el valor esperado, ya que es el primer valor conocido.

Piénselo en el contexto de las pruebas manuales. Una prueba manual tendrá el valor esperado escrito, con el valor real registrado posteriormente.


-1
2018-04-20 10:13