Contexto
Expresado de manera simplificada, 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.
La única forma conocida para ejecutar la estrategia, o plan de negocios, es mediante proyectos. El hacer proyectos rápidos 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.
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 de 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.
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.
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.
Desarrollo con eXtreme Programming
La propuesta es guiar el desarrollo con pruebas. Desarrollar una aplicación 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
- Docker (runtime)
- Render
- Uptime Robot
- Desarrollo
- Gitlab (backlog, repo, CI/CD, etc)
- Visual Studio / Co-Pilot
---
Links
I. Visión de proyecto y Kick-off
- En general, el desarrollo de software implica resolver problemas de negocio.
Visión de negocio
- abc
Mínimo Producto Viable
- Registración
- Lista de expertos
II. Planning y Bootstrap
III. Diseño de la solución
IV. Walking Skeleton
El Walking Skeleton es una versión mínima pero funcional del sistema que recorre toda la arquitectura de punta a punta. Su objetivo es establecer las bases técnicas y arquitectónicas del proyecto desde el inicio.
Notas importantes:
-
Se debe comenzar con un walking skeleton que permita validar la estructura general de la aplicación, desde la interfaz hasta la base de datos o servicios externos.
-
Este walking skeleton debe estar cubierto por una prueba de aceptación end-to-end, asegurando que todo el flujo básico funcione correctamente.
-
Además, debe incluir desde el inicio el proceso completo de versionado, build, test y deploy hacia un entorno similar a producción, siguiendo un esquema de integración continua (CI).
VI. Creación de un proyecto .NET paso a paso
Este apartado explica cómo construir una aplicación .NET completa desde cero, siguiendo buenas prácticas de desarrollo profesional, automatización y testing. El enfoque no es solo técnico, sino también arquitectónico y metodológico: busca sentar las bases de un proyecto sólido, automatizable y probado end-to-end.
- Crear solución:
- dotnet new sln --name <nombre solucion>
- Crear proyecto usando plantilla MVC dentro de la solución:
- 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
- Generar .gitignore
- El archivo .gitignore sirve para indicarle a Git qué archivos o carpetas debe ignorar al hacer seguimiento de cambios en un repositorio.
- Generar Build Script
- Un build script en un archivo .gitlab-ci.yml define el conjunto de acciones que GitLab CI/CD debe ejecutar durante la etapa de construcción de tu pipeline. Generalmente, incluye una lista de comandos que se ejecutan para compilar tu código, ejecutar pruebas o preparar tu aplicación para el despliegue.
- No es recomendable poner código en el build script porque no lo podemos testear localmente. Lo recomendable es colocar el código en scripts.
- How to create file execute mode permissions in Git on Windows?
- Instalar Linter
- Cuando se trabaja con distintos SO y diferentes IDE, se debería agregar un EditorConfig en el proyecto. Este sirve para colocar las convenciones a seguir en el desarrollo. Ver ejemplo de archivo EditorConfig.
- Luego, tenemos que configurar nuestro IDE para que "entienda" las convenciones ubicadas en el EditorConfig. En Visual Studio tenemos que habilitar la opción "Code Style".
- Cuando se suba el código al repositorio, se tiene que asegurar de que se sigan dichas convenciones. Linter hace esto. Parsea tu código y asegura que tu código cumple con las convenciones del lenguaje.
- En .NET el comando dotnet format aplica automáticamente las reglas de estilo definidas en .editorconfig y mantener tu código limpio y consistente.
- Dentro del pipeline se debería hacer una verificación (sin modificación) de que el código está correctamente formateado según las reglas del archivo .editorconfig. Para esto usamos el comando dotnet format --verify-no-changes
- Definir el arnés de pruebas
- Un arnés de pruebas (en inglés, test harness) es un conjunto de herramientas, código y configuraciones que se utilizan para automatizar la ejecución de pruebas en una aplicación o componente de software.
- 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 suelen 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.
- ¿Que tipos de pruebas haremos en nuestra arquitectura?:
- Aceptación: Deben ser end-to-end (e2e), expresadas en términos de la aplicación. Estas pruebas testean la aplicación a nivel de historia de usuario (tipo caja negra), son lentas y no dan buen feedback. Son pruebas que las puede escribir el usuario, por tanto están escritas en un lenguaje natural. Herramientas: nunit + Gherkin + Reqnroll + Selenium.WebDriver. Reqnroll ejecutará el Gherkin. Por debajo, usaremos el Selenium.WebDriver para automatizar tareas en el navegador.
- Unitaria: Prueban la lógica de negocio sin dependencia de infraestructura. Herramientas: nunit + moq
- Integración: Probar como se integra código que escribiste tú con código que tú no escribiste. Herramientas: nunit
- Agregar a la solución un proyecto de test NUnit (con pruebas e2e) para probar la Web.
- Sintaxis Gherkin para especificar los tests
- Usar Reqnroll para interpretar Gherkin en C#
- Con el WebApplicationFactory vamos a instanciar un objeto que va a representar a la aplicación web dentro del proceso que corre los tests sin necesidad de levantar la aplicación por fuera.
- Usar la librería FluentAssertions la cual extiende los métodos de aserción tradicionales (Assert.Equal, Assert.True, etc.) y permite escribir pruebas más naturales y fáciles de leer.
- Configurar la medición de cobertura
- Aplicación de BDD
- En un enfoque tradicional, tenemos al analista que habla con el usuario y genera una especificación (un documento, con casos de uso por ejemplo), luego el developer codifica y finalmente el tester define y ejecuta casos de prueba.
- En un enfoque de testing ágil / XP, Usuario, Dev y Tester se juntan para armar una especificación basada en ejemplos. Estos ejemplos son casos de prueba. El Dev a construir teniendo a mano los casos de prueba, es decir, ya sabe como se va a testear la funcionalidad que está desarrollando. Luego el Tester ejecuta los mismos casos de prueba que el Dev utilizó para guiarse en el desarrollo (esto ahorra muchas idas y vueltas). 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 (Crear imagen custom docker para usar en el CI)
- BDD implica entender los requerimientos a partir de ejemplos concretos.
- User stories are typically broken down into acceptance criteria or business rules. Focusing on examples makes the intention of these rules clear—each rule should be illustrated by one or more examples.
- Escribir un escenario (test) nos ayude a recorrer los puntos centrales de la arquitectura
- Completar la idea de Walking Squeleton
- En Gherkin @wip sirve para excluir escenarios. Luego configurar tu runner para no ejecutarlas: > dotnet test --filter "TestCategory!=wip"
- Armar arnés de prueba en NET
- Armar una configuración de compose que levanta 2 bases de datos. Una BD para cuando ejecute la aplicación de forma manual y otra BD para usarla en el contexto de las pruebas automatizadas.
- Levantar BDs: > docker compose up
- Puedes acceder a las bases de datos mediante el Management Studio.
- Para las pruebas ¿por qué no usar una BD en memoria? Poque necesitamos usar un entorno lo más parecido a producción, para mitigar riesgos.
- Cuando ejecutemos las pruebas, tenemos que apuntar a la BD de pruebas a través del Connection String. Los archivos appsettings son dinámicos por ambiente.
- Ejecutar los Tests (es importante indicar la variable de ambiente de test para no pegarle a la base de datos de desarrollo)
- > set ASPNETCORE_ENVIRONMENT=test
- > dotnet test
- > dotnet test --filter "TestCategory!=wip"
- La BD se creará a través de Migrations (scripts que crean la estructuras de tablas).
- > Add-Migration InitialCreate
- >
- Crear proyecto Web.Test el cual tendrá tests desde la perspectiva del usuario escritos en lenguaje Gherkin.
- En la clase Hooks de Reqnroll,
- En el método BeforeTestRun() se crea instancia de la aplicación
- En el meétodo BeforeScenario() me conecto a la BD y borro todo para que los escenarios estén limpios. Luego levanto el Chrome Driver para que en cada escenario usar una instancia del navegador distinta.
Introducción
- BDD / TDD
- CI / CD
- Ensemble programming (aka "Pair/Mob programming")
- Otros: Infra as Code, Feature Flags, Monitoring, etc.
- Runtime
- .NET 8
- Postgresql 17
- Docker (runtime)
- Render
- Uptime Robot
- Desarrollo
- Gitlab (backlog, repo, ci/cd, etc)
- Visual Studio / Rider / Co-Pilot
- .NET, Git, Docker, IDE
- 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
De Walking Skeletons y Tracer Bullets
- 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.
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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.
- Escribimos una prueba de aceptación en Gherkin
- Luego pasamos a las pruebas unitarias
Arnés de Prueba para .NET
- Historia de Usuario
- Criterios de aceptación
- 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.
Software Requirements
Software Architecture
Software Design
- Diseño de Software
- SOLID principles
- SOLID Principles In C# With Examples
- El Principio de Substitución de Liskov
- Inversión de dependencias
- Segregación de interfaces
- GoF Patterns
- Dependency Injection
Software Construction
- POO
- Frontend
- HTML / CSS
- JavaScript
- Angular
- React
- Blazor
- Backend
- .NET Full Stack
- Clean Code
- Desarrollo con .NET/C#
- Aplicaciones web con ASP.NET Core y MVC
- Entity Framework
- EF Core - Introbook
- Entity Framework Core Interview Questions and Answers
- Learn Entity Framework Core
- Entity Framework Core Tutorial
- Testing de aplicaciones .NET con xUnit y Moq
- Diseño e implementación de servicios REST
- Seguridad de aplicaciones
- SQL
- SQL Server
Software Testing
Software Configuration Management
Software Engineering Management
- Introducción a la gestión de Proyectos
- Introducción a los métodos ágiles
- Introducción a Extreme Programming
Software Engineering Operations
- JIS.uy , 2018 - DevOps, myths and facts of a new paradigm
- Practicas de Software Delivery
- Entrega continua y automatización de pruebas
- Meetup Infrastructure as Code
- Modern Team Structure - Roles and skills for a Software Delivery Team
- La infraestructura y su evolución: el camino al IDP por Fernando Abramowitz | Meetup BA 2024
- Integración Continua 3.0: Evolución, Patrones y Recomendaciones
- EP. 16 Agilidad Técnica ft Nicolás Paez - La Revolución Ágil
- DevOps con Jenkins
Enlaces
- Software Engineering Education Meets DevOps: an Experience Report
- DotNet-Developer-Roadmap
- Software Engineering Guide
- Dirección De Proyectos: Una Introducción Con Base En El Marco Del Pmi
- .NET Developer Roadmap
Poner foco en las siguientes prácticas de desarrollo de software:
- Code Review
- Unit Test
- Coding Standards
- BDD
- Performance Testing
- Cloud Development
- CI/CD
No comments:
Post a Comment