- Pruebas unitarias: para verificar la lógica dentro de la capa empresarial y la capa del controlador de interfaz de usuario (o ‘ViewModel’)
- Pruebas de integración: para verificar la capa de acceso a datos y el repositorio y la funcionalidad de extremo a extremo.
- Pruebas de IU: para verificar su lógica de interacción con el usuario. Esto es probablemente lo más difícil ya que las tecnologías no son lo suficientemente maduras; Selenium para aplicaciones web y Ranorex para aplicaciones de escritorio, por ejemplo, son imposibles de mantener a largo plazo. Pero es fundamental asegurarse de que, por ejemplo, las pestañas sobre celdas deshabilitadas funcionen (he tenido que codificar a mano un arnés para esta parte antes de que fuera en una forma que pudiera mantenerse en el futuro).
- Principios de codificación sólidos (¡no @SOLID (diseño orientado a objetos)!), Contratos entre subsistemas y soporte de metadatos. Por ejemplo, el equipo debe tener principios sobre cuándo se devuelve un valor nulo o una colección vacía, si un parámetro es opcional, un buen toque es tener una convención mediante la cual el sufijo si el parámetro tiene ‘Opt’ (cf. Roslyn), identifique dónde ¡Debe haber garantías de que los métodos nunca arrojan y afirman lo mismo en el contrato / documentación !, acuerde en su equipo dónde copiar y pegar es y no es aceptable y esté absolutamente seguro de que se elimina la duplicidad en la lógica o los datos y donde no es posible, emplee code-gen o (por duplicidad en sproc-logic y serveride-logic) use construcciones integradas en el lenguaje / plataforma o, como mínimo, tenga pruebas de integración que garanticen que la lógica permanezca sincronizada.
- Code Gen. Familiarízate con él y úsalo si las herramientas están ahí.
- Uso juicioso de patrones de diseño. Por ejemplo, Memento es excelente para preservar el estado cuando se requiere una manipulación y recuperación de objetos complejos cuando se produce una falla en el proceso y se requiere una limpieza. IoC es bastante común ahora, pero podría arruinar su proyecto: tenga cuidado de que cuando esté a punto de ejecutar alguna acción, ¿sabe cuáles son las dependencias y de dónde se extraerán en ese punto del código?
- Piense en las características de su idioma, su aplicación y su proceso general. Si está escribiendo un motor de procesamiento / FIX de alto volumen que no puede permitirse retrasarse y su (des) asignación de memoria es lenta, preasigne la mayor parte de su memoria por adelantado y limpie manualmente a intervalos predefinidos o cargue equilibrio entre procesos, etc. Si se trata de un gran proyecto (buena suerte en primer lugar), la pieza crítica es la interacción de los componentes y el proceso se vuelve crítico. CI está bien, pero cuando estas piezas pasan a producción juntas, ¿tiene el 100% de confianza de que interactuarán de la misma manera que lo hicieron en el desarrollo, tiene un servicio de HA que garantiza que todos los componentes se ejecutan en el mismo entorno y usted tener una manera de VERIFICAR esto como un paso posterior a la compilación. Si tiene que interactuar con una aplicación heredada, realice algunas pruebas y escriba su código ‘nuevo’ en las mismas condiciones que esas pruebas.
- Contrata programadores orientados al detalle que conozcan bien su plataforma / idioma y sus limitaciones. Las revisiones por pares pueden ayudar, si son del tipo correcto @http: //smartbear.com/SmartBear/m….
- Toma medidas preventivas. El ejemplo de preasignación se da arriba. Otro También al implementar el manejo de excepciones, tome medidas preventivas para que su manejo de excepciones falle e idealmente asegúrese completamente de que el manejo de excepciones en sí mismo no se produzca. Si es una restricción de memoria, no tome una captura de pantalla, si se trata de un error de red, no envíe un correo electrónico en su lugar escriba en el archivo de registro elegido, si eso falla, escriba en el registro de eventos del sistema y si eso falla, escriba en un archivo temporal. Las condiciones previas, las condiciones posteriores y las invariantes son críticas aquí: afirmar, afirmar, afirmar para asegurarse de que sus suposiciones sean correctas. Al principio puede lastimarte la cabeza tener que pensar en esto, pero se convertirá en una segunda naturaleza.
- Manejo de excepciones bien definido. En CUALQUIER etapa de su aplicación, desde hacer clic en el botón hasta insertar datos, debe saber dónde se encuentra el manejo de excepciones para esa etapa. Cómo se maneja un tiempo de espera de php, qué sucede si su servicio de Windows se queda sin memoria, qué pasa con el controlador infame para un clic de botón WinForms, qué pasa con la falla en subprocesos o temporizadores de fondo. No es suficiente conectarse a un controlador global como App.UnhandledException o al archivo asax global solo y luego tomar medidas. Si desea que sea confiable, piense en el contexto y si su componente cargado necesita ser derribado, si la integridad de los datos está comprometida, si el usuario necesita saber al respecto, qué alerta debe enviarse. También debajo de este banner, ¿qué mensaje debe devolver al usuario? El usuario (o la aplicación que consume) debe recibir suficiente información si está disponible para ayudarlo; si la línea 10 de un CSV estaba en el formato incorrecto, dígales que una manta 500 simplemente no es genial. Pero tenga cuidado, no demasiado para regalar la estructura del sistema de archivos / db / etc. Una forma económica de hacerlo es tener una excepción personalizada que se puede lanzar en varios puntos conocidos de su aplicación y que el controlador global podría utilizar para devolver un mensaje específico.
Si puede obtener un código que simplemente funcione año tras año con ~ 0 llamadas de soporte, pero los únicos ‘errores’ realmente son requisitos que no se definieron por adelantado, bueno, eso es genial.