2009-09-17 13 views
6

Escribo código principalmente para uso personal, pero estoy considerando la posibilidad de lanzar una aplicación (simulación/visualización científica) que desarrollé originalmente para uso personal.Hábitos de Java para el método principal

Uno de mis hábitos es utilizar un método principal en las clases para probar el funcionamiento de la clase de forma aislada. Me imagino que es probable que sea malo de alguna manera (como sin duda hay otros hábitos que se originan en la autoaprendizaje y el entorno de desarrollo científico). Sin embargo, nunca ha sido un problema para las cosas de auto-uso que he notado.

¿Sería tan amable de confirmar (o negar) que la proliferación de la red eléctrica es un problema para una aplicación lanzada a la comunidad científica (la fuente también estaría abierta) y, de ser así, por qué?

EDITAR: Para jugar abogado del diablo (está bien, mi abogado) relativo a algunas de las respuestas ofrecidas: se espera que parte del "uso de la aplicación" sea modificación de fuente por no desarrolladores (el científico típico) en una escala pequeña . Sé que en el extremo receptor, que tener las pruebas para una clase integrada directamente en esa clase sería bastante sencillo para mí reconocer y modificar en consecuencia (especialmente si ese fuera el caso de las clases). ¿El uso de algo como JUnit proporcionaría una utilidad similar, teniendo en cuenta la audiencia?

ACEPTO LA DECISIÓN: Creo que la respuesta de KLE es el mejor equilibrio entre minucioso y sucinto, así que lo elegí, pero creo que los comentarios de la discusión en Bill también son muy útiles. Tampoco entiendo por qué la respuesta de Johannes fue rechazada - la perspectiva de "cómo funciona esta pieza" es muy importante para los codificadores de la comunidad científica - y mientras que las otras respuestas señalan varias razones por las cuales las pruebas unitarias separadas son probablemente más útiles que mi hábito actual, en realidad no abordan ese uso, por lo que su respuesta está lejos de ser "inútil". ¡Gracias a todos los respondedores actuales (y futuros), y deseamos que haya una manera de combinar respuestas múltiples como la respuesta correcta!

+1

+1 agradable exponerse ;-) – KLE

+2

Estoy de acuerdo con KLE. Es importante hablar sobre los malos hábitos para poder averiguar * por qué * son malos (y no solo seguir ciegamente a la manada) o justificar por qué podrían estar bien bajo un conjunto específico de circunstancias. –

+2

@Bill Bien puesto.No pude armar las palabras exactas, pero lo hiciste. Probablemente sea un hablante nativo de inglés, tenga buenas habilidades de comunicación, y ciertamente ** pensado ** al respecto. _ _ Gracias, y sigue ... algunos de nosotros estamos mirando y aprendiendo de ti ;-) – KLE

Respuesta

6

JUnit le permite disponer de pruebas, al igual que sus platos principales, pero también:

  • un principal es por lo general sólo un método, que puede llegar muy grande; Si la extracción de pequeñas métodos utilizados únicamente para la prueba, existe el riesgo de usar que los métodos en el código normal
  • no recarga la propia clase con los métodos de prueba, que están en una clase diferente
  • permite herencia en la prueba clases (principal, como método estático, es imposible de heredar o reutilizar); por lo general, la configuración antes de la prueba real puede ser bastante larga, y reutilizarla naturalmente es genial
  • una principal no tiene ningún resultado (éxito o falla), solo una salida; que necesita para comprobar manualmente la salida para determinar el resultado, y posiblemente lo entiende
  • permitir la ejecución de varias pruebas (Clase del paquete, proyecto, todos) a la vez, que es requerido para las pruebas de regresión (o se le pasar la tarde a la ejecución de uno a uno)
  • JUnit proporcionan muchas características adicionales de la caja, como marcando algunas pruebas como ignorado, la comprobación de que una prueba no es demasiado largo, proporcionar varias interfaces de usuario de lanzamiento etc.
  • se puede reutilizar algunas pruebas en cada implementación o subclase (por ej .: comprobación de Sustitución de Liskov), que le permite realizar muchas pruebas sin mantener una gran cantidad de código de prueba.
12

La prueba de su clase en su propio método principal es mala porque le da a la clase una responsabilidad adicional (la prueba misma). Las pruebas deben ir en clases separadas, preferentemente utilizando una biblioteca de pruebas como JUnit.

La proliferación de la red eléctrica (me gusta esta frase que ha acuñado) también hace que sea más confuso para un desarrollador encontrar el punto de entrada a su aplicación cuando se acerca a ella por primera vez.

+5

+1: Todos los 'public void main' deben ser aislados en clases que hacen casi nada más. Todo el procesamiento "real" debería estar en otro lugar con mejores API que 'main'. Estos objetos de procesamiento "reales" deben ser instanciados por 'main'. –

+0

digamos que el desarrollador típico no es realmente un desarrollador, y tiene poco o nada de hábitos de codificación del mundo "reales". Agradezco que su respuesta sea probablemente correcta para las personas que trabajan como desarrolladores (aunque, por supuesto, no tengo ni idea), pero ¿cree que es la correcta para esta audiencia atípica? – Carl

+2

@Carl: El desarrollador típico con un poco de experiencia en el mundo real probablemente ya siga este consejo, por lo que la audiencia atípica es exactamente para quién es esto. –

2

Necesita usar una herramienta de prueba como JUNIT para realizar pruebas en sus clases en lugar de insertar el código de prueba en su código de producción.

Esto separa limpiamente las pruebas de su código.

3

No es terrible, pero no es recomendable por dos razones:

  1. Se puede permitir a los usuarios hacer cosas que no quieres que hagan o al menos les dan la idea de que pueden hacer algo que' más bien no lo hicieron; y
  2. Los métodos main() prolíficos son a menudo un sustituto pobre para las pruebas unitarias.

Es (2) realmente deberías concentrarte en.

6

Antes que nada, es genial que estés escribiendo pruebas. Realmente no me gusta el enfoque de tener un método principal en muchas clases en un proyecto. Yo recomendaría mover el código de prueba y usar un marco de prueba. Esto mantiene el código fuente más limpio, y si utiliza una metodología consistente de nomenclatura para sus clases de prueba, también es fácil encontrar las pruebas asociadas.

0

No hay nada de malo en este enfoque per se pero hay un inconveniente importante: debe llamar a cada método main() individualmente para probar todo su código. Es probable que no lo haga. Es demasiado hazzle. Además, al hacer esto, debe saber qué métodos main() son puntos de entrada reales y cuáles son pruebas. Esto no es para nada obvio.

Con JUnit y herramientas similares, puede marcar el código como "esto es una prueba". Esto permite que la herramienta encuentre todas las pruebas en su proyecto automáticamente y las ejecute todas a la vez. De esta forma, es mucho más probable que ejecute todas las pruebas la mayor parte del tiempo y que los errores se detectan temprano.

0

No utilizaría los métodos principales en todas las clases para fines de prueba también. Primero, seguir la regla de separación de preocupaciones (el uso y las pruebas son preocupaciones diferentes) y porque tenemos soluciones elegantes para las pruebas.

En segundo lugar, y eso no se ha mencionado hasta ahora, si cada clase tiene un método principal, es bastante difícil encontrar el punto de entrada "real" en la aplicación. Si veo una clase con un método principal, espero que esto me permita "usar" la clase de la manera prevista. No espero que esto comience un caso de prueba (tal vez con graves efectos secundarios).

Ah, solo un tercer aspecto que me viene a la mente: los métodos principales son siempre públicos, por lo que el usuario de su biblioteca puede usar estos métodos en cualquier momento, incluso durante la ejecución de su propia aplicación. Esto puede tener terribles efectos secundarios, especialmente en entornos con múltiples subprocesos.

Cuestiones relacionadas