2011-12-27 9 views
6

que siguen la convención de nombres de¿Hay alguna forma de proteger los nombres de prueba de unidades que siguen el patrón MethodName_Condition_ExpectedBehaviour contra la refactorización?

MethodName_Condition_ExpectedBehaviour

cuando se trata de nombrar mi unidad de pruebas que ponen a prueba los métodos específicos.

por ejemplo:

[TestMethod] 
public void GetCity_TakesParidId_ReturnsParis(){...} 

Pero cuando tengo que cambiar el nombre del método que se está probando, herramientas como ReSharper no me ofrecen cambiar el nombre de dichas pruebas.

¿Hay alguna manera de evitar que estos casos aparezcan después de cambiar el nombre? Como cambiar la configuración de ReSharper o seguir una convención de nomenclatura de prueba de unidad mejor, etc.

+0

¿Cómo se relaciona esto con Java? La etiqueta 'java' debe eliminarse de entre las etiquetas. De todos modos, en Java (con JUnit por ejemplo) si escribe una prueba para un método específico, entonces no habrá conexión entre la prueba y el método bajo prueba y Eclipse, NetBeans, etc.no le ofrecerá refactorizar el nombre del método de prueba. No puedo comentar sobre el comportamiento de ReSharper. –

+0

¿Es 'cambiar el nombre del método' un gran caso de uso para usted? Si es así ... tal vez puedas omitir este imán de cambio de tus nombres de prueba. P.ej. [clase] TestCityRepository tiene el método de prueba ShouldRetrieveCityById. De esta forma estará aislado del nombre del método de implementación ... – Gishu

Respuesta

7

Un modelo reciente es a las pruebas de grupos en las clases internas por el método que ponen a prueba!.

Por ejemplo (omitiendo los atributos de prueba):

public CityGetterTests 
{ 
    public class GetCity 
    { 
     public void TakesParidId_ReturnsParis() 
     { 
      //... 
     } 

     // More GetCity tests 
    } 
} 

Ver Structuring Unit Tests from Phil Haack's blog para más detalles.

Lo bueno de este diseño es que, cuando el nombre del método cambie, , solo tendrá que cambiar el nombre de la clase interna en lugar de todas las pruebas individuales .

+0

¡Realmente me gusta la idea! ¿Dónde has aprendido sobre este patrón por cierto? ¿Algún recurso o artículo o ...? (¡Gracias!) – pencilCake

1

También comencé con esta conversión, sin embargo, terminé con una sensación que no es muy buena. Ahora uso nombres de estilo BDD como should_return_Paris_for_ParisID.

Eso hace que mis pruebas más legible y alsow me permite refactorizar nombres de los métodos sin la preocupación de mis pruebas :)

+0

¿No menciona el nombre del método en el nombre de la prueba de la unidad? – pencilCake

+0

no, eso me permite cambiarle el nombre más adelante sin ningún efecto secundario :) Creo que probé escenarios, no métodos particulares –

+0

Tal vez su manera se puede conectar con un comentario como: Método en prueba: GetCity. De modo que ReSharper ofrecerá volver a vincular este TEXTO cuando cambie el nombre de su método. – pencilCake

0

Creo que la clave aquí es lo que debe ser la prueba.

Has mencionado a TDD en las etiquetas, por lo que espero que estemos tratando de cumplirlo aquí. Por ese paradigma, las pruebas que escribe el usuario tienen dos propósitos:

  1. Para apoyo su código una vez que se escribe, por lo que puede refactorizar sin temor a que se ha roto algo

  2. Para guíanos a una mejor forma de diseñar componentes - escribir primero la prueba realmente te obliga a pensar en lo que es necesario para resolver el problema en cuestión.

Sé que al principio parece que esta pregunta es sobre el primer punto, pero realmente creo que se trata de la segunda. El problema que tiene es que tiene componentes concretos que está probando en lugar de un contrato.

En términos de código, lo que significa que creo que deberíamos estar probando las interfaces en lugar de los métodos de clase, porque de lo contrario nos exponemos nuestra prueba a una variedad de problemas asociados con las pruebas componentes en lugar de contratos - estrategias de herencia, objeto construcción, y aquí, cambiar el nombre.

Es cierto que los nombres de interfaces también cambiarán, pero serán mucho más rígidos que los nombres de métodos. Lo que TDD nos brinda aquí no es solo una forma de apoyar el cambio a través de un arnés de prueba: ¡proporciona la idea para darse cuenta de que podríamos hacerlo de la manera equivocada!

Tomemos por ejemplo el bloque de código que dio:

[TestMethod] 
public void GetCity_TakesParidId_ReturnsParis(){...} 
{ 
    // some test logic here 
} 

Y digamos que estamos probando el método GetCity() en nuestro objeto, CityObtainer - cuando me puse este objeto hacia arriba? ¿Por qué lo hice? Si me doy cuenta de GetMatchingCity() es un nombre mejor, entonces usted tiene el problema descrito anteriormente!

La solución que propongo es que pensamos acerca de lo que realmente significa este método anterior en el proceso, mediante el uso de interfaces:

public interface ICityObtainer 
{ 
    public City GetMatchingCity(); 
} 

Al escribir en este "afuera hacia adentro" forma de estilo , estamos obligados a pensar sobre lo que queremos del objeto mucho antes en el proceso, y convertirse en el foco debería reducir su volatilidad. Esto no elimina su problema, pero puede mitigarlo de alguna manera (y, creo, es un mejor enfoque de todos modos).

Lo ideal es ir un paso más allá, y nosotros ni siquiera escribir ningún código antes de comenzar la prueba:

[TestMethod] 
public void GetCity_TakesParId_ReturnsParis 
{ 
    ICityObtainer cityObtainer = new CityObtainer(); 
    var result = cityObtainer.GetCity("paris"); 

    Assert.That(result.Name, Is.EqualTo("paris"); 
} 

De esta manera, puedo ver lo que realmente quiero del componente incluso antes de comenzar a escribirlo - si GetCity() no es realmente lo que quiero, sino más bien GetCityByID(), se haría evidente mucho antes en el proceso. Como dije antes, no es infalible, pero podría reducir un poco el dolor en este caso en particular.

Una vez que haya pasado por eso, siento que si cambia el nombre del método, es porque estás cambiar los términos del contrato, y que significa debería tener que ir vuelva y reconsidere la prueba (ya que es posible que no desee cambiarla).

(Como adición rápida, si estamos escribiendo una prueba con TDD en mente, entonces algo está pasando en el interior GetCity() que tiene una cantidad significativa de la lógica pasando. Pensando en la prueba como a una contrato nos ayuda a separar la intención de la aplicación - la prueba permanecerá válida no importa lo cambiamos detrás de la interfaz)

Cuestiones relacionadas