Apuntes Calidad

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 8

– La serie ISO/IEC 9000.

Son un conjunto de normas cuyo ámbito es la gestión de la calidad,


del conjunto la norma más destacada es la ISO/IEC 9001, que trata los requisitos del sistema de
gestión de la calidad.
– La serie ISO/IEC 15504 (también conocida como SPICE). Son un conjunto de normas cuyo
ámbito es evaluar y mejorar la capacidad y madurez de los procesos.
– La serie ISO/IEC 20000. Son un conjunto de normas cuyo ámbito es la gestión del servicio
que ofrecen las tecnologías de la información.
– La serie ISO/IEC 27000. Son un conjunto de normas cuyo ámbito es la seguridad, buenas
prácticas para mantener los Sistemas de Gestión de la Seguridad de la Información (SGSI).

El modelo TMMi contempla el testing de software en diferentes niveles de madurez,


partiendo de la base de que todas las organizaciones comienzan en el nivel 1 de la escala de
madurez TMMi. Cuanto más maduras sean las prácticas de testing de una organización, más
alto será el nivel de madurez TMMi que alcance.

El modelo tiene una arquitectura por etapas para la mejora del proceso de testing.

Los esfuerzos de mejora del proceso de testing se centran en las necesidades de la


organización en el contexto de su entorno empresarial. El paso por los distintos niveles de
madurez aumenta la capacidad de la gestión de la calidad del testing y el software para
ajustarse a las necesidades de la empresa. Los beneficios son, entre otros, la mejora de la
calidad del producto de software con menos defectos, pero también la mejora de la eficacia de
las pruebas.
Las leyes de la evolución del software

A principios de los 80 Lehman formuló las que se conocen como leyes de la evolución del
software, que escribió desde su observación de la evolución del OS/360 (desde el que
curiosamente Brooks también desarrollo sus trabajos sobre gestión de proyectos).

Tres tipos:

- los S (que pueden especificarse formalmente, son estáticos)


- los P (que no pueden ser especificados y es necesario un proceso iterativo para ello)
- los E (sistemas que ya funcionan en el mundo real). Y sobre estos últimos observo que
están siempre en continuo cambio y que los cambios introducen complejidad de
manera creciente. Sus 8 leyes:

Cambio Continuo. Un programa tipo E que se usa debe ser continuamente adaptado, si no,
progresivamente, será menos satisfactorio.

Complejidad incremental. Cuando un programa evoluciona su complejidad se incrementa, a


menos que se trabaje en mantenerla o en reducirla.

Autorregulación. El proceso de evolución del programa se autorregula según una distribución


normal de atributos de proceso y producto.

Conservación de la estabilidad organizacional. A lo largo del ciclo de vida del producto, la


velocidad media de actividad global efectiva del sistema en evolución es invariante. El esfuerzo
en la evolución lo determinan decisiones de dirección… pero su influencia queda restringida
por factores externos, como los recursos disponibles, el personal competente, etc. Por ello, la
actividad dedicada a la estabilización del software es aproximadamente constante.

Conservación de la familiaridad. Durante la vida de un programa en evolución, el tamaño de


las sucesivas versiones es estadísticamente invariante. Uno de los factores que determina la
evolución software es la familiaridad de los implicados con la versión, cuantos más cambios se
hacen a una versión más difícil es que todos los implicados los conozcan, una evolución
“grande” dificultaría esa familiaridad, por lo que los cambios tienden a ser de un tamaño
parecido.

Crecimiento continuo. La funcionalidad del programa debe incrementarse continuamente para


mantener la satisfacción del usuario. Los sistemas nacen con limitaciones de funcionalidad, por
motivos de tiempo o recursos, lo que produce que con el tiempo requisitos que se descartaron
al principio vuelvan a aparecer.

Calidad decreciente. Se percibirá que un programa de tipo E pierde calidad a menos que se
mantenga de manera rigurosa y se adapte al entorno operacional.
Sistema de realimentación. El proceso de programación de un programa tipo E constituye un
sistema de realimentación multinivel (no es estático) y debe ser tratado como tal para tener
éxito en su modificación o mejora.

¿Qué estrategia de control de versiones seguir en un equipo Scrum?


Desarrollo lineal en el control de versiones

Esto sería un desarrollo lineal, en una única línea del control de versiones. Todos los
desarrolladores van subiendo las tareas que han terminado a la misma línea del control de
versiones.

Uno de los principales problemas que tiene este enfoque, es que los errores se propagan más
fácilmente. Además, por este motivo, puede que los desarrolladores no suban su código al
control de versiones muy a menudo, hasta que no sea estable, por temor a introducir errores y
que se propaguen a los otros desarrolladores. Con ello, incumplimos la recomendación de que
todo el código esté en el control de versiones e integrar frecuentemente.

Integración continua y desarrollo lineal en el control de versiones

Un enfoque para la integración continua aquí podría ser que cuando un desarrollador intente
subir su código a esta única línea principal, el servidor de integración continua intente
compilar su código con el que ya hay en la línea principal y ejecutar los tests. Si todo es un
éxito, el código se subirá correctamente al control de versiones, y si no, el desarrollador tendrá
que solucionar los errores.
¿Qué pasa con este enfoque? Además de los problemas mencionados antes, ¿dónde se queda
el código mientras que el servidor de integración continua está compilándolo y pasando los
tests? Hasta que el servidor no termina, no se sube al control de versiones, por lo que puede
que pasemos un tiempo sin hacer nada hasta recibir si todo ha sido un éxito o no.
Por ello, un enfoque que podría funcionar mejor es…

Desarrollo paralelo, o a través de ramas

Podemos cambiar el desarrollo lineal por un enfoque de una historia de usuario o tarea por
rama, es decir, creamos una rama cada vez que vamos a desarrollar una tarea, una historia de
usuario o solucionar un error.
Cuando terminemos de implementar dicha tarea, el código esté probado y sea estable,
procederemos a integrarlo en la rama principal o línea de desarrollo principal.

Estas ramas tienen que tener nombres descriptivos, como por ejemplo el nombre de la tarea,
historia de usuario o el id del bug. Así mejoramos la trazabilidad del código, y se establece
claramente qué propósito tiene cada rama.
Pero también tiene más ventajas:

- Cada desarrollador puede subir su código al control de versiones sin temor a


estropear el código de la línea principal de desarrollo.
- Además, reducimos la propagación de los errores.
- Garantizamos que el código que está en la línea principal de desarrollo sea estable.
Todas las ramas/tareas que se desarrollen a partir de la rama principal, partirán de un
punto estable, sin errores.
- Aseguramos que las tareas son independientes unas de otras.
Integración continua y desarrollo paralelo en el control de versiones

En este enfoque, una alternativa es que el servidor de integración continua sea el que cuando
terminemos una tarea o historia de usuario, combine la rama de esa tarea con la rama
principal, y compruebe que pasan los tests.

Complejidad ciclomática

Fue en 1976 cuando Thomas McCabe publicó un artículo en el que argumentaba como la
complejidad del código puede obtenerse desde su flujo de control.

Se basa en calcular el número de rutas linealmente independientes del código (se mide en los
algoritmos, por ello es aplicable a orientación a objetos, Php, PLs, etc., cualquier cosa con
algoritmo).

La métrica estrella a la hora de rápidamente ver la calidad software de un montón de fuentes.


Fácil de automatizar y proporciona mucha mucha información.

Muestra el grado de código “espagueti”, profundos problemas de diseño, problemas de


comprensibilidad, las pruebas necesarias para lograr una cobertura 100% del código, etc.

Principios SOLID

Te contamos brevemente sobre S.O.L.I.D, es un acrónimo creado por Tío Bob (Robert C. Martin)
bajo el que se engloban cuatro principios que todo Diseño Orientado a Objetos debería seguir.

– SRP (“Single Responsibility Principle” – Principio de Responsabilidad Única). “Una clase


debe tener solamente un único motivo para cambiar.”

– OCP (“The Open Closed Principle ”- Principio de Abierto-Cerrado). “Deberías ser capaz de
extender el comportamiento de una clase, sin modificarla.”

– LSP (“The Liskov Substitution Principle” – Principio de sustitución de Liskov). “Las clases
derivadas deben poder sustituirse por sus clases base”

– ISP (“The Interface Segregation Principle ” – Principio de segregación de interfaces). “Haz


interfaces que sean específicas para un tipo de cliente”.

– DIP (“The Dependency Inversion Principle” – Principio de Inversión de


Dependencias). “Depende de abstracciones, no de clases concretas.”

CODE SMELLS
1. Comentarios

Exceso de comentarios

Comentarios excesivos que explican cosas obvias o que no son útiles, lo que puede dificultar la

lectura del código.


Información inapropiada

Poner en comentarios información sobre el sistema o sobre usuarios. Los comentarios deben

reservarse para notas técnicas sobre el código y el diseño.

Código comentado

El código comentado se vuelve obsoleto, en un punto puede llamar a funciones o usar


variables que ya no existen o han cambiado. Contamina los módulos en los que aparece.

2. Nombres misteriosos

Una de las partes más importantes de un código claro son los buenos nombres, así que
pensamos mucho en nombrar funciones, módulos, variables, clases, para que comuniquen
claramente lo que hacen y cómo usarlos.

3. Código duplicado

Tener la misma estructura de código en más de un sitio. Duplicación significa que cada vez que
leas estas copias, tienes que leerlas cuidadosamente para ver si hay alguna diferencia. Si
necesitas cambiar el código duplicado, tienes que encontrar y cambiar cada duplicación.

4. Funciones largas

Los programas que tienen una vida mejor y durante más tiempo son los que tienen funciones
cortas. Este tipo de código a menudo da la sensación de que no se realiza ningún cálculo, de
que el programa es una secuencia interminable de delegaciones.

5. Larga lista de parámetros

Las largas listas de parámetros suelen ser confusas por sí mismas. Las clases son una buena
forma de reducir el tamaño de las listas de parámetros. Son especialmente útiles cuando
varias funciones comparten varios valores de parámetros.

6. Datos globales

La forma más obvia de datos globales son las variables globales, pero también vemos este
problema con variables de clase y de patrones singletons.

7. Clases demasiado grandes

Clases que tienen demasiadas responsabilidades y hacen demasiadas cosas diferentes.

8. Lógica condicional excesiva

Uso excesivo de condicionales, como if-else, que pueden hacer que el código sea difícil de leer
y entender.

9. Dependencias circulares

Se pueden dar situaciones en las que dos o más clases dependen mutuamente, lo que puede
hacer que el código sea difícil de mantener.

10. Código muerto

Código que ya no se utiliza pero sigue presente en el programa.


11. Clases o métodos con nombres poco descriptivos

Nombres de clases o métodos que no describen claramente lo que hacen o que son confusos.

12. Mal uso de excepciones

El uso inadecuado de excepciones, como lanzar excepciones demasiado amplias o no manejar


excepciones de manera adecuada, lo que puede dificultar la depuración del código.

13. Acoplamiento excesivo

Cuando dos o más partes del código están estrechamente relacionadas, lo que hace que sea
difícil modificar una sin afectar la otras.

CODE SMELLS 2
1. Cohesión débil

La Cohesión débil se refiere a una clase o módulo que tiene muchas responsabilidades o
funcionalidades que no están relacionadas entre sí.

2. Efecto secundario

El Efecto secundario se refiere a una función o método que modifica variables o estados fuera
de su alcance local, es decir, variables que están fuera del ámbito de la función o método.

3. Speculative generality

Speculative generality ocurre cuando se incluyen características o funcionalidades en el


código que no se necesitan actualmente, pero se agregan en caso de que sean necesarias en
el futuro.

4. Clases o métodos que hacen demasiadas cosas

Cuando una clase o método tiene varias responsabilidades diferentes, lo que hace que sea
difícil de entender y mantener.

5. Lazy class

Lazy class ocurre cuando una clase no hace lo suficiente y tiene poco valor en el sistema. En
otras palabras, la clase no tiene una responsabilidad clara y no realiza tareas significativas.

6. Shotgun surgery

El shotgun surgery es un code smell que ocurre cuando un cambio en un requisito o una
funcionalidad afecta a múltiples partes del código.

7. Feature envy

El Feature envy es un code smell que ocurre cuando un método o función accede
repetidamente a los datos o métodos de otra clase en lugar de usar los de su propia clase.

8. Data clumps

Data Clumps es un code smell que se produce cuando se encuentran grupos de datos
relacionados que aparecen repetidamente en todo el código.
9. Middle Man

El Middle man es un code smell que se produce cuando una clase o método actúa como un
intermediario entre otras clases o métodos sin agregar ningún valor adicional.

10. Divergent change

Divergent change ocurre cuando un cambio en una clase o módulo requiere muchos cambios

en otras partes del sistema.

Clean Architecture
- Independencia de frameworks: la arquitectura debe ser independiente de cualquier
framework o tecnología específica. De esta manera, se evita que el código dependa de
tecnologías que puedan cambiar en el futuro.

- Testeabilidad: la arquitectura debe ser diseñada para permitir pruebas automatizadas,


lo que facilita la detección temprana de errores y la validación del correcto
funcionamiento del sistema.

- Independencia de la UI: la arquitectura debe ser independiente de la interfaz de


usuario. De esta manera, se puede cambiar la interfaz de usuario sin tener que cambiar
la arquitectura subyacente.

- Independencia de la base de datos: la arquitectura debe ser independiente de la base


de datos. De esta manera, se puede cambiar la base de datos sin tener que cambiar la
arquitectura subyacente.

- Principio de abstracción: los detalles de implementación deben estar ocultos detrás de


interfaces bien definidas. De esta manera, se pueden cambiar las implementaciones sin
afectar a los componentes que dependen de ellas.

- Separación de capas: la arquitectura debe estar dividida en capas lógicas, donde cada
capa tiene una responsabilidad específica y comunica con capas adyacentes a través de
interfaces bien definidas.

- Coherencia conceptual: la arquitectura debe reflejar el modelo de negocio del sistema.


De esta manera, el código es más fácil de entender y los cambios en el negocio se
pueden reflejar fácilmente en el código.

- Modularidad: la arquitectura debe ser modular, lo que significa que los componentes
del sistema deben ser independientes y reutilizables en diferentes partes del sistema.
- Mantenibilidad: la arquitectura debe estar diseñada para facilitar el mantenimiento
del código a largo plazo.

- Principio de límites contextuales: los componentes deben estar organizados en límites


contextuales (también conocidos como módulos), donde cada límite tiene una
responsabilidad específica y se comunica con otros límites a través de interfaces bien
definidas.

- Principio de composición: La composición debe ser flexible y permitir la reutilización


de componentes.

- Principio de simplicidad: el diseño de la arquitectura debe ser lo más simple posible.

- Principio de consistencia: los componentes y las interfaces deben ser coherentes en


todo el sistema.

También podría gustarte