Pregunta

Estoy buscando una herramienta que puede tomar una prueba de unidad, como

IPerson p = new Person();
p.Name = "Sklivvz";
Assert.AreEqual("Sklivvz", p.Name);

y generar, de forma automática, el correspondiente talón de clase y de la interfaz de

interface IPerson         // inferred from IPerson p = new Person();
{
    string Name 
    { 
        get;              // inferred from Assert.AreEqual("Sklivvz", p.Name);
        set;              // inferred from p.Name = "Sklivvz";
    }
}

class Person: IPerson     // inferred from IPerson p = new Person();
{
    private string name;  // inferred from p.Name = "Sklivvz";

    public string Name    // inferred from p.Name = "Sklivvz";
    {
        get
        {
            return name;  // inferred from Assert.AreEqual("Sklivvz", p.Name);
        }
        set
        {
            name = value; // inferred from p.Name = "Sklivvz";
        }
    }

    public Person()       // inferred from IPerson p = new Person();
    {
    }
}

Sé que ReSharper y Visual Studio algunos de estos, pero necesito una completa herramienta de -- línea de comandos o lo que sea-que automáticamente se deduce lo que se necesita hacer.Si no hay ninguna herramienta de este tipo, ¿cómo se escribe (p. ej.ampliación de ReSharper, desde cero, con el que las bibliotecas)?

¿Fue útil?

Solución

Lo que parece que necesita es un analizador para el lenguaje de programación (Java), y un nombre y tipo de resolución.("Tabla de símbolos constructor").

Después de analizar la fuente de texto, un compilador, por lo general tiene una resolución de nombre, que intenta registrar la definición de los nombres y sus correspondientes tipos, y un comprobador de tipos, que verifica que cada expresión tiene un tipo válido.

Normalmente, el nombre y tipo de resolución de queja cuando no puede encontrar una definición.Lo que quiero hacer es encontrar la "undefined" cosa que está causando el problema, y de inferir un tipo para ella.

Para

 IPerson p = new Person();

el nombre de resolución sabe que la "Persona" y "IPerson" no están definidos.Si se tratara de

 Foo  p =  new Bar();

no habría ningún indicio de que usted quería una interfaz, sólo que Foo es una especie de resumen de los padres de la Barra (por ejemplo, una clase o una interfaz).Por lo tanto la decisión como la que se deberá ser conocida la herramienta ("cuando encuentres una tal construcción, asumir Foo es una interfaz ...").Usted podría utilizar una heurística:IFoo y Foo significa IFoo debe ser una interfaz, y en algún lugar alguien tiene que definir Foo como una clase de darse cuenta de que la interfaz.Una vez que el la herramienta ha tomado esta decisión, es necesario actualizar sus tablas de símbolos de manera que se puede pasar a otras declaraciones:

Para

 p.Name = "Sklivvz";

dado que p debe ser una Interfaz (por la anterior inferencia), entonces el Nombre debe ser un miembro del campo, y parece que su tipo es la Cadena de la asignación.

Con eso, la declaración:

 Assert.AreEqual("Sklivvz", p.Name);

los nombres y tipos de resolver sin más problema.

El contenido de la IFoo y Foo entidades es una especie de arriba para usted;usted no tiene que usar get y set, pero eso es gusto personal.

Esto no funciona tan bien cuando se tienen varias entidades en la misma declaración:

 x = p.a + p.b ;

Sabemos que a y b son probablemente los campos, pero usted no puede adivinar qué tipo numérico, si es que realmente lo son numéricos, o si son cadenas (esto es legal para las cadenas en Java, no sé acerca de C#).Para C++ que no sabes ni lo que "+" significa;podría ser un operador en la Barra de clase.Así que lo que tienes que hacer es recoger restricciones, por ejemplo, "una es algún número indefinido o de la cadena", etc.y como la herramienta recopila la evidencia, se reduce el conjunto de las posibles limitaciones.(Esto funciona como los problemas de palabras:"Joe tiene siete hijos.Jeff es más alto que el de Sam.Harry no puede ocultar detrás de Sam....quién es Jeff gemela?" donde usted tiene que recoger las pruebas y quitar las imposibilidades).Usted también tiene que preocuparse acerca de el caso de que usted termina con una contradicción.

Usted podría descartar p.a+p.b caso, pero entonces usted no puede escribir su unidad de pruebas con la impunidad.Hay estándar de la constraint solvers si uno quiere la impunidad.(Lo que es un concepto).

OK, tenemos las ideas, ahora, se puede hacer esto de una manera práctica?

La primera parte de este requiere un analizador y un interior nombre y tipo de resolución.Usted necesita un solver de restricciones, o al menos un "valor definido los flujos de valor indefinido de la operación" (trivial solver de restricciones).

Nuestro Software DMS kit de herramientas de Reingeniería con su Java Front End probablemente podría hacer esto.DMS es una herramienta del constructor de la herramienta, para las personas que quieren construir herramientas que procesan equipo idiomas en formas arbitrarias.(Piense en "informática con fragmentos de programa en lugar de números").

DMS ofrece propósito general de análisis de la maquinaria, y se puede construir un árbol por cualquier extremo delantero es dado (por ejemplo, en Java, y hay un C# front-end).La razón por la que elegí Java es que nuestra Java front end tiene todo lo que el nombre y el tipo de resolución de la maquinaria, y se proporciona en forma de código fuente por lo que puede ser doblada.Si usted se pegó a la trivial solver de restricciones, usted probablemente podría doblar el Java resolución de nombre para averiguar los tipos.DMS te permitirá montar los árboles que corresponden a fragmentos de código, y se unen a ellos en los más grandes;como su herramienta recogieron los datos de la tabla de símbolos, se podría construir la primitiva árboles.

En algún lugar, usted tiene que decidir que está hecho.Cuántos unidad de pruebas de la herramienta tiene que ver antes de que se sepa toda la interfaz?(Supongo que se come a todos los que te proporcionan?).Una vez completa, que reúne a los fragmentos de los distintos miembros y construir un AST para una interfaz;DMS puede usar su prettyprinter convertir el AST de nuevo en código fuente como se muestra.

Sugiero Java aquí porque nuestra Java front end tiene nombre y tipo de resolución.Nuestro C# front end no.Esta es una "mera" cuestión de ambición;alguien tiene que escribir uno, pero eso es mucho trabajo (al menos lo fue para Java y no me puedo imaginar el C# es muy diferente).

Pero la idea funciona bien en principio el uso de DMS.

Usted puede hacer esto con algunas otras obras de infraestructura que le dio acceso a un analizador y un interior nombre y tipo de resolución.Que podría no ser tan fácil de conseguir para C#;Sospecho que MS le puede dar un analizador, y el acceso a nombre y tipo de resolución, pero no de cualquier manera para cambiar eso.Tal vez el Mono es la respuesta?

Usted todavía necesita una era generar fragmentos de código y ensamblar.Usted podría tratar de hacer esto por la cadena de la piratería;mi (larga) experiencia con el encolado programa de bits es que si se puede hacer con las cadenas que finalmente hago un lío.Usted realmente desea piezas que representan fragmentos de código de tipo conocido, que sólo pueden combinarse en formas de la gramática permite;DMS hace que por lo tanto no hay lío.

Otros consejos

Es increíble cómo en realidad nadie le dio nada a lo que estaban pidiendo.

No sé la respuesta, pero voy a dar mi opinión sobre ella.

Si yo fuera a intentar escribir algo como esto a mí mismo, probablemente voy a ver sobre un resharper plugin.La razón por la que digo esto es porque como se dijo, resharper puede hacerlo, pero en pasos individuales.Así que me gustaría escribir algo que salió de línea a línea y aplicar la correspondiente resharper métodos de creación de encadenar.

Ahora no puedo siquiera saben cómo hacerlo, ya que nunca he construido nada para resharper, pero eso es lo que intentaba hacer.Ella tiene un sentido lógico que se podía hacer.

Y si no escribir algo de código, por FAVOR, publicarlo, ya que he podido encontrar que útil, así, ser capaces de generar el esqueleto entero en un solo paso.Muy útil.

Si usted planea escribir su propia aplicación me gustaría definitivamente sugerir que usted tome una mirada en el NVelocity (C#) o Velocidad (Java) de la plantilla de los motores.

He utilizado estas en un generador de código antes y han encontrado que hacen el trabajo mucho más fácil.

Es factible - al menos en teoría.Lo que yo haría es usar algo como csparser para analizar la prueba de la unidad (no se puede compilar, por desgracia) y, a continuación, tomar desde allí.El único problema que puedo ver es que lo que está haciendo está mal en términos de la metodología - que tiene más sentido para generar pruebas unitarias de las clases de entidad (de hecho, Visual Studio hace precisamente esto) que hacerlo de la otra manera alrededor.

Creo que una solución real a este problema sería muy especializado analizador.Ya que no es tan fácil de hacer, tengo una idea más barato.Por desgracia, tendría que cambiar la manera de escribir las pruebas (es decir, sólo la creación del objeto):

dynamic p = someFactory.Create("MyNamespace.Person");
p.Name = "Sklivvz";
Assert.AreEqual("Sklivvz", p.Name);

Un objeto de fábrica se utiliza.Si puede encontrar el nombre de objeto, se puede crear y devolver (esta es la normal ejecución de la prueba).Si no la encuentra, se va a crear un proxy de grabación (un DynamicObject) que registra todas las llamadas y al final (tal vez en derribar) podría emitir archivos de clase (tal vez basado en algunas de las plantillas) que reflejan lo que se "vio" que se llama.

Algunas de las desventajas que veo:

  • Necesario para ejecutar el código en "dos" modos, lo que es molesto.
  • Para que el proxy para "ver" y el registro de llamadas, que debe ser ejecutado;así el código en un catch bloquear, por ejemplo, tiene que correr.
  • Usted tiene que cambiar la forma de crear el objeto bajo prueba.
  • Usted tiene que usar dynamic;vas a perder el tiempo de compilación de seguridad en las siguientes ejecuciones y tiene un impacto en el rendimiento.

La única ventaja que veo es que es mucho más barato para crear más especializados analizador.

Me gusta CodeRush de DevExpress.Ellos tienen un gran motor de plantillas personalizables.Y la mejor para mí no es la de los cuadros de Diálogo.También tienen la funcionalidad para crear métodos y las interfaces y las clases de la interfaz que no existe.

Trate de mirar el Pex , Un proyecto de microsoft en la unidad de pruebas , que todavía está bajo investigación

research.microsoft.com/en-us/projects/Pex/

Creo que lo que usted está buscando es un fuzzing kit de herramienta (https://en.wikipedia.org/wiki/Fuzz_testing).

Al difíciles nunca he usado, que podría dar Randoop.NET una oportunidad para generar "unidad de pruebas' http://randoop.codeplex.com/

Visual Studio incluye algunas características que pueden ser útiles para usted aquí:

Método De Generar Punta De.Cuando se escribe una llamada a un método que no existe, de que obtendrá un poco de etiquetas inteligentes en el nombre del método que se puede utilizar para generar un código auxiliar del método basado en los parámetros que estamos pasando.

Si eres un teclado persona (yo soy), luego a la derecha después de escribir el paréntesis de cierre, que puede hacer:

  • Ctrl-. (para abrir la etiqueta inteligente)
  • ENTRAR (para generar el stub)
  • F12 (ir a la definición, para tomar con el nuevo método)

La etiqueta inteligente sólo aparece si el IDE piensa que no hay un método que coincida con.Si desea generar cuando la etiqueta inteligente no es, usted puede ir a Editar->Intellisense->Método De Generar Punta De.

Fragmentos de.Pequeñas plantillas de código que hace que sea fácil para generar los bits de código común.Algunos son simples (a tratar de "si[TAB][TAB]").Algunos son complejos ('switch' generar casos para un enum).Usted también puede escribir su propio.Para su caso, tratar de "clase" y "proposición".

Véase también "Cómo cambiar el "Método de Generar Stub" para lanzar NotImplementedException en VS?"para que fragmentos de información en el contexto de los GMS.

autoprops.Recuerde que las propiedades pueden ser mucho más simple:

public string Name { get; set; }

crear la clase.En el Explorador de soluciones, RClick en el nombre del proyecto o en una subcarpeta, seleccione Agregar->Clase.Escriba el nombre de la nueva clase.Hit ENTRAR.Usted obtendrá una declaración de clase en el derecho del espacio de nombres, etc.

Implementar la interfaz.Cuando se desea que una clase para implementar una interfaz, escriba el nombre de la interfaz parte, activar la etiqueta inteligente, y seleccione cualquiera de las opciones para generar los stubs para los miembros de la interfaz.

Estos no son el 100% automatizado solución que está buscando, pero creo que es un buen mitigación.

Me parece que cada vez que necesito una herramienta de generación de código como este, yo soy probablemente la escritura de código que podría ser un poco más genérico, así que sólo tengo que escribir una vez.En tu ejemplo, los getters y setters parece que no agrega ningún valor para el código - de hecho, es realmente sólo la afirmación de que el getter/setter mecanismo en C# de las obras.

Me abstendría de la escritura (o incluso el uso de tal herramienta antes de entender lo que las motivaciones para escribir este tipo de pruebas.

Por CIERTO, puede que desee echar un vistazo a NBehave?

Yo uso Rhino Mocks para esto, cuando yo sólo necesita un simple código auxiliar.

http://www.ayende.com/wiki/Rhino+Mocks+-+Stubs.ashx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top