Software Engineering Guide

IMPORTANTE: El propósito de este Roadmap es tratar de plasmar una ruta de aprendizaje de cara a especializarme como .NET Full-Stack Developer con una visión integral de los aspectos de la producción de software (ingeniería de software).

Contexto

Expresado de manera simplicada, el desarrollo de un sistema de software puede verse como una transformación hacia la solución técnica de determinada problemática u oportunidad con el fin de resolverla. Este cambio enfrenta a menudo restricciones en relación con el tiempo, el costo y la calidad. 

Figura 1: Visión simplificada del desarrollo de sistemas

La única forma conocida para ejecutar la estrategia, o plan de negocios, es mediante proyectos. El hacer proyectos rápida y correctamente tiene ventajas obvias. Las tareas y estrategias se ejecutan con agilidad, se utilizan solo los recursos necesarios, tanto de dinero como de personas, y el producto resultante y sus beneficios se ven más rápido. 

Nota: Si tu competidor puede ejecutar proyectos a la mitad del tiempo que tú, te está ganando en el aquí y ahora.

Las actividades en un proyecto se realizan en dos frentes paralelos: El frente gerencial y el frente técnico. 

Figura 2: Frentes gerencial y técnico del proyecto

La Figura 2 correlaciona estos dos frentes y además indica que en el frente gerencial siempre se realizan, fase por fase, los siguientes grandes grupos de actividades: Iniciar, planificar, ejecutar, monitorear/controlar y cerrar, esto en consonancia con lo presentado en el PMBOK.

Es importante resaltar que las actividades que se desarrollan en el frente gerencial no dependen del tipo de industria. Aplican por igual en las industrias de extracción, construcción, manufactura, farmacéutica, desarrollo de software, consultoría, telecomunicaciones, banca, seguros, comercialización, producción, energía, gas, petróleos, etc.

Nota: Este enfoque de que un proyecto no depende de su naturaleza o dominio se realiza con fines puramente académicos para concentrarnos en los aspectos propios de la dirección de proyectos.

En el frente técnico del proyecto actúan los diversos miembros del equipo del proyecto encargados de materializar los entregables -productos, servicios o resultados- con los cuales se ha comprometido el proyecto. Obsérvese que este grupo está desarrollando los constitutivos del alcance con los cuales se ha comprometido el proyecto. Las actividades que se relacionan con este frente sí son muy dependientes de la naturaleza de la empresa y el tipo de proyecto a desarrollar. Por ejemplo, las actividades técnicas que requieren los proyectos de fidelización de clientes, de reingeniería de procesos de producción, de construcción de carreteras, de desarrollo de software, etc. pueden ser muy diferentes entre sí. En el desarrollo de software las actividades técnicas que se realizan desde el dominio del problema hasta el dominio de la solución son: Requerimientos, Diseño, Construcción, Pruebas, Despliegue y Mantenimiento.


Flujo de Valor

Como desarrolladores tenemos la misión entregar software funcional de manera frecuente. En nuestro día a día esto implica recorrer un Flujo de Valor donde realizamos actividades para diseñar, producir y entregar software al cliente. 

Figura 3: Flujo de valor

Dicho flujo de valor sigue las siguientes etapas:

  • (a) Todo comienza con una necesidad del usuario, una oportunidad de negocio.
  • (b) Creamos una visión del proyecto.
  • (c) Identificamos las funcionalidades para crear el backlog del producto.
  • (d) Empezamos a trabajar de manera iterativa e incremental.
  • (e) Al final de cada iteración tenemos un incremento del producto.
  • (f) Lo verificamos: Testing, control de calidad.
  • (g) Si todo está de acuerdo con las expectativas, entonces nuestro producto está potencialmente listo para su lanzamiento. Para ello, nuestro artefacto de software puede tener que pasar por diferentes entornos en su camino hacia producción.
  • (h) Donde finalmente se encuentra con el usuario final.
  • (j) Es en ese momento, en manos del usuario, cuando el software aporta valor (se generan utilidades).
  • (i) Tenemos que operarlo para garantizar su disponibilidad.
  • (k) Y necesitamos obtener métricas en tiempo de ejecución para comprender el comportamiento del usuario y de esta forma buscar formas de incrementar las utilidades.
Finalmente, de vuelta a empezar.

Tradicionalmente, la Ingeniería de Software se ha centrado en los aspectos relacionados con el desarrollo (los requisitos, la arquitectura, el diseño, las pruebas, etc.), es decir, la zona verde de la Figura 3. Por otro lado, iniciativas como ITIL y MOF han tratado las preocupaciones de la zona roja, pero ninguna de ellas ha sido ampliamente difundida y adoptada. En los últimos años, la iniciativa DevOps ha logrado un gran éxito optimizando todo el flujo lo cual lo sitúa en la zona azul de la Figura 3.



Software Requirements


Software Architecture

Software Design


Software Construction


Software Testing

Software Configuration Management


Software Engineering Management


Software Engineering Operations



Desarrollo con eXtreme Programming

La propuesta es guiar el desarrollo con pruebas


https://gitlab.com/untref-ingsoft/trinchera/jobvacancynet

Introducción


Desarrollar una aplicacion siguiendo la metodología de eXtreme Programming (moderno)  considerando las siguientes prácticas:
  • BDD / TDD
  • CI / CD
  • Ensemble programming (aka "Pair/Mob programming")
  • Otros: Infra as Code, Feature Flags, Monitoring, etc.
El stack de tecnología a utilizar es el siguiente:
  • Runtime
    • .NET 8
    • Postgresql 17
    • Docker (runtime)
    • Render
    • Uptime Robot
  • Desarrollo
    • Gitlab (backlog, repo, ci/cd, etc)
    • Visual Studio / Rider / Co-Pilot
---

Preparar ambiente de desarrollo
  • .NET, Git, Docker, IDE
Crear repositorio y backlog (https://gitlab.com/ingsoft2630115/trinchera/jobvacancy-net/-/boards)

Guiamos el desarrollo con pruebas
  • Pruebas de aceptación
    • Relatadas desde la perspectiva del usuario
    • ¿Cliente o usuario? El cliente es el que paga, el usuario es el que usa el software.
    • El usuario tendría que ser el que escribe las pruebas (en el mejor de los casos)
    • Herramienta: reqnroll
  • Pruebas uniarias
    • Pruebas técnicas
    • Herramienta: xUnit

Diseño de alto nivel desacoplado de la tecnología



Investigar/Definir las herramientas a utilizar (ORM, View Engine, etc)

Las decisiones de diseño se tienen que documentar en un log de arquitectura.

Con NET vamos a generar un scafolding básico y sobre eso generamos un walking skeleton con una funcionalidad de healthcheck.


De Walking Skeletons y Tracer Bullets



Walking Skeleton
  • A Walking Skeleton is a tiny implementation of the system that performs a small end-to-end function. It does not need to use the final architecture, but it should link together the main architectural components.
  • Implementar una funcionalid de punta a punta, de tal forma que podomas cablear todas las partes de nuestra arquitectura.

Tracer Bullet
  • A bare-bones skeleton of your system that is complete enough to hang future pieces of functionality on. It's exploratory, but it's not really a prototype because you are not planning to throw it away - it will become the foundation of your real system.

Scaffolding

Scaffolding se refiere a la generación automática de código.
Para generar una solución con un proyecto ASP.NET MVC con Entity Framework usando PostgreSQL:
  • dotnet new sln --name <nombre solucion>
  • dotnet new mvc --auth None --no-https --framework net8.0 -o WebApp
  • dotnet sln add WebApp/WebApp.csproj
  • dotnet add WebApp/WebApp.csproj package Npgsql
  • dotnet build

Para instalar las herramientas de Entity Framework
  • dotnet tool install --global dotnet-ef

Motor de Templates

  • Razor pages
  • Blazor
  • Razor
  • Liquid
  • Scriban
  • Handlebars.NET

Opciones para acceso a base de datos

  • NHibernate
    • Es un ORM completo de la comunidad
    • Muchas funcionalidades
    • https://nhibernate.info/
  • Dapper
    • No es un ORM completo
    • Comunidad
  • Entity Framework
    • ORM de Microsoft

52min: code time

Crear un Log de Decisiones en el repositorio

Si queremos hacer desarrollo guiado en el dominio, entonces tenemos que ajustarnos en el dominio. Si mi cliente habla sobre su negocio en español, entonces quiero que ello esté reflejado en el código. Cuando hacemos traducciones caemos en riesgo de caer en la ambiguedad. 

Agregamos un build script en el proyecto

Agregamos un EditorConfig en el proyecto. Este sirve para colocar las convenciones a seguir en el desarollo.
https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/code-style-rule-options
Cuando se suba el código al respositorio se tiene que asegurar que se siguen dichas convenciones. Linter hace esto. Parsea tu código y asegura que tu código cumple con las convenciones del lenguaje. 
El "dotnet format" lee el editorconfig 
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-format
Cada vez que suba el proyecto al repo se debe verificar: 1) que compile, 2) que siga las convenciones, 3) que pasen los tests, ...

Crear proyecto de test
  • dotnet new nunit --framework=net8.0 --name jobvacancynet.Web.Tests
  • dotnet sln add jobvacancynet.Web.Tests/jobvacancynet.Web.Tests.csproj
  • dotnet add jobvacancynet.Web.Tests/jobvacancynet.Web.Tests.csproj reference jobvacancynet.Web/jobvacancynet.Web.csproj
  • cd jobvacancynet.Web.Tests
  • dotnet add package Microsoft.AspNetCore.Mvc.Testing --version 8.0.14
  • https://learn.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-9.0


MVC, Patrones y Arnés de Pruebas






MVC
  • Problema que intenta resolver: como estructurar una aplicación interactiva (el usuario hace algo, la aplicación contesta). Un proceso batch no es una aplicación interactiva (aqui podrías usar un batch filter). Las aplicaciones interactivas tienen que interpretar el input del usuario, luego hacer algún tipo de cómputo y finalmente entregar una respuesta.
  • 3 componentes: Vista, controlador y modelo
    • controlador: interpreta intención del usuario 
    • modelo: resuelve la lógica de negocio
    • vista: da una respuesta al usuario
  • El modelo no debe conocer la vista ni el controlador
  • El patrón MVC se puede combinar con otros


Arquitectura Hexagonal
  • Puerto = Interfaz
  • Adaptador = Implementación
  • Problema: aislar la lógica de negocio de la infraesctructura.
  • Beneficios: 
    • Independizarme de la infraestructura (cambiable)
    • Testear la lógica de negocio sin depender de la infraestructura

Combinación MVC y Arquitectura Hexagonal



Arnés de Pruebas
  • En un desarrollo guiado por pruebas, el objetivo no es escribir las pruebas. Las pruebas son un medio para escribir la aplicación. Estas pruebas tempranas suele ser distintas a las que uno hace a posteriori del desarrollo con el objetivo de testear.
  • Si no tienes en cuenta las pruebas de manera temprana terminarás solo haciendo pruebas de caja negra. Esto es costoso.
  • La arquitectura propuesta hasta el momento permite realizar distintos tipos de tests. Nota: los tipos de tests no están estandarizados. 
  • Según el libro "Growing Object-Oriented Software, Guided by Tests" existen los siguientes tipos de tests:
    • Unit: 
      • Prueba un componente, una clase
    • Integration
      • Cómo se integra código que escribiste tú con código que tú no escribiste.
    • Acceptance
      • Una prueba que la puede escribir el usuario 
      • Expresada en términos de la aplicación
      • Deben ser end-to-end (e2e)
      • Son lentas, no dan buen feedback
  • La estrategia de pruebas sería la siguiente


Behavior-Driven Development




Enfoque Tradicional




Enfoque Testing Ágil / XP
  • Usuario, Dev y tester se juntan para armar una especificación basada en ejemplos. Estos ejemplos son casos de prueba.
  • Para que el usuario pueda trabajar colaborativamente en la definición de estos casos de prueba se utilizan una herramienta como Gherkin. Luego se utilizan otra serie de herramientas para convertir Gherkin a código. 
  • Reqnroll ejecutará el Gherkin. Por debajo, usaremos el Selenium.WebDriver para automatizar tareas en el navegador.
  • La idea entender los requerimientos a partir de ejemplos concretos los cuales se construyen en conjunto con el usuario.
  • A partir de herramientas como Reqnroll y Cucumber podemos automatizar los requerimientos expresados en Gherkin. Cada escenario representa un test.



Selenium.WebDriver es un paquete que maneja Google Chrome. Esto requiere que esté instalado el Chrome. Si queremos ejecutar esto dentro de Gitlab, vamos a necesitar crear una imagen de Docker que tenga .NET y Google Chrome para que esto pueda correr dentro del Pipeline. 

La idea es que un Test nos ayude a recorrer los puntos centrales de la arquitectura.

BDD / TDD
  • Escribimos una prueba de aceptación en Gherkin
  • Luego pasamos a las pruebas unitarias



Arnés de Prueba para .NET




La herramienta reqnroll permite asociar código a lenguaje gherkin


Definir el Requerimiento:
  • Historia de Usuario
  • Criterios de aceptación

Crear la Feature con Gherkin
  • Dado una funcionalidad, esta tiene una serie de reglas y asociado a las reglas hay distintos escenarios.
  • Un camino feliz y caminos alternativos.
  • ¿Es necesario que todo los escenarios tengan pruebas de aceptación e2e? El escenario feliz seguramente si, los escenarios alternativos tal vez no todos. 










Enlaces







Poner foco en las siguientes prácticas de desarrollo de software:

  • Code Review
  • Unit Test
  • Coding Standards
  • BDD
  • Performance Testing
  • Cloud Development
  • CI/CD

Comments

Popular posts from this blog

Week #1: Definición de objetivos, desglose de trabajo

Week #2: Azure App Service

Registro de Excepciones