-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2fb851d
commit 059f8cd
Showing
3 changed files
with
190 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
data/blog/en/katas-sustainable-testing-ts/kata-07-csv-filter.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
--- | ||
title: "Kata 07 in TypeScript: CSV Filter" | ||
series: | ||
order: 8 | ||
title: "Sustainable Testing Katas in TypeScript" | ||
date: '2024/10/18' | ||
lastmod: '2024/10/18' | ||
language: en | ||
tags: ['testing', 'tdd', 'javascript', 'typescript'] | ||
authors: ['default'] | ||
draft: false | ||
featured: false | ||
summary: In this article of the series "Sustainable Testing Katas in TypeScript", we'll analyze the creation of a CSV filter using TDD and Jest. | ||
--- | ||
|
||
> The katas of this series are proposed exercises in the excellent course [Testing Sostenible con TypeScript](https://academy.softwarecrafters.io/p/curso) by Miguel A. Gómez and Carlos Blé | ||
## Introduction | ||
|
||
Test-Driven Development (TDD) is an essential methodology in the arsenal of any developer who seeks to create robust and maintainable software. Through a practical exercise involving filtering data from a CSV file with invoices information, we can appreciate how TDD does not only facilitates development, but also improves the understanding of business requirements. | ||
|
||
In previous articles of this series, we have seen how to use this approach to solve problems step-by-step. However, for reasons of practicality and because I consider that the `Red-Green-Refactor` cycle is already well understood, from this article on what we will do is to delve into the key points, the challenges encountered and the lessons learned. Of course, all this without leaving aside the value that I hope these articles will bring you. | ||
|
||
<TOCInline toc={props.toc} exclude="Introduction" locale={props.locale} asDisclosure /> | ||
|
||
## Breakdown of the Exercise | ||
|
||
The objective of this exercise is to process a CSV file containing multiple invoice lines, by applying a set of business rules to determine which lines are valid. Each invoice line, except the header, must meet certain criteria to be considered correct: | ||
|
||
- **Empty Fields**. It is valid that some fields are empty, represented by commas in a row or a final comma. This adds flexibility to the data input but it also adds complexity to the validation. | ||
|
||
- **Invoice Number Uniqueness**. Invoice number must be unique. If duplicates are detected, all lines with this number will be deleted. This requires careful analysis of the data to avoid inconsistencies. | ||
|
||
- **Exclusivity of VAT (IVA) and IGIC Taxes**. Only one of these taxes can be applied per line. IVA is a general value-added tax used in many countries, while IGIC is specific to the Canary Islands. If both fields are filled, the line must be discarded, which implies a clear and precise validation logic. | ||
|
||
- **Exclusivity of CIF and NIF Fields**. Similar to the taxes, only one of these identifiers can be present in a valid line. CIF (Código de Identificación Fiscal) and NIF (Número de Identificación Fiscal) are identifiers for legal entities and individuals, respectively, in Spain. | ||
|
||
- **Correct Calculation of Net Amount**. The net field value must correctly result from applying the corresponding tax to the gross amount. This mathematical verification is crucial for ensuring data integrity. | ||
|
||
## Challenges and Considerations | ||
|
||
### Defining Test Cases | ||
|
||
One of the main challenges in (TDD) is defining exhaustive test cases that cover all possible data variations. This exercise focuses on ensuring that the system behaves correctly under various scenarios by including the following test cases: | ||
|
||
- **Validation of Correct Invoices**. Verify that lines complying with all specified rules, such as uniqueness and proper tax application, are accepted. | ||
|
||
- **Exclusivity Validations**. Ensure that lines containing both taxes (IVA and IGIC) or both identifiers (CIF and NIF) are correctly rejected. | ||
|
||
- **Net Amount Calculation**. Confirm that lines with incorrect net amount calculations are identified and removed. | ||
|
||
- **Handling Borderline Cases**. Test the system's robustness with edge cases, such as empty files or files containing only a single line. | ||
|
||
### Handling Special Cases | ||
|
||
It is crucial to anticipate and handle anomalous cases that may arise in the use of the system. Some questions that arise are: | ||
|
||
- What happens if a header is missing? | ||
- What happens if the fields are unordered or there are unknown fields? | ||
|
||
These questions not only require a solid technical design, but also a constant communication with the business experts to define clear expectations. This is very important, because when we get stuck with special cases because it is not clear how to face them, what we have to do is to consult the business experts. We shall never assume what seems "reasonable" to us, because every business operates differently. | ||
|
||
### Simplicity and Refactoring | ||
|
||
As more tests are developed and more rules are implemented, the code can become complex. Continuous refactoring is essential to keep the code clean, readable and easy to maintain. This involves: | ||
|
||
- **Use of Explanatory Variables**. Introducing variables that explain the purpose of complex code blocks. | ||
- **Method Extraction**. Decomposing long functions into smaller and more specific methods. | ||
- **Methods and Variables Renaming**. Ensuring that names clearly reflect their purpose and content. | ||
|
||
## TDD Best Practices | ||
|
||
- **Start with Simple Tests**. Start writing tests for the simplest cases and gradually progress to more complex situations. This not only reduces cognitive load, but also allows for incremental and controlled development. | ||
|
||
- **Frequent Commits**. Make commits after each passing test or each refactoring is crucial. This allows reverting changes easily if something goes wrong, maintaining a stable workflow. For example, making a commit after creating a test and see it in `Red`, then another commit for `Green` and if applicable, other(s) for `Refactor`, since every small change must be registered. In order to not have a huge commit history, at the end they can me merged into one by using `git squash`. Seen in another way, they would be `microcommits`. | ||
|
||
- **Continuous Refactoring**. Don't wait for the code to become unmanageable before refactoring. Making small adjustments continuously keeps the code clean and consistent. | ||
|
||
- **Single-Purpose Tests**. Ensure each test has only one reason to fail. This facilitates the identification of errors and ensures that each test covers a specific case without unnecessary overlaps. | ||
|
||
- **Collaboration with Business Experts**. To make it even clearer. Business rules can be complex and not always obvious. Collaborate with business experts to clarify any doubts and make sure that the tests faithfully reflect business requirements. | ||
|
||
## Link to GitHub repository | ||
|
||
You can find this kata, and the rest of them, [here](https://github.com/carlos-talavera/katas-sustainable-testing-ts). | ||
|
||
## Conclusion | ||
|
||
This exercise of filtering invoices in a CSV file through TDD reminds us of the importance of a disciplined and methodical approach in software development. Through a precise definition of business rules and test cases, and with a continuous refactoring, we can create solutions that not only meet the current criteria, but are also easy to maintain and scale in the future. TDD is more than a testing technique; it is a development philosophy that leads to a high-quality code and a deep understanding of the problem that is being solved. | ||
|
||
Implementing TDD in practical exercises like this not only improves our technical skills, but also helps us to develop a more systematic approach to address complex problems. At the end of the day, the true value of TDD lies in its ability to transform the way we think about and build software. If you have any question or want to share something, leave it in the comments :) |
91 changes: 91 additions & 0 deletions
91
data/blog/es/katas-sustainable-testing-ts/kata-07-csv-filter.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
--- | ||
title: "Kata 07 con TypeScript: Filtro CSV" | ||
series: | ||
order: 8 | ||
title: "Katas Testing Sostenible con TypeScript" | ||
date: '2024/10/18' | ||
lastmod: '2024/10/18' | ||
language: es | ||
tags: ['testing', 'tdd', 'javascript', 'typescript'] | ||
authors: ['default'] | ||
draft: false | ||
featured: false | ||
summary: En este artículo de la serie "Katas Testing Sostenible con TypeScript", analizaremos la creación de un filtro de CSV usando TDD y Jest. | ||
--- | ||
|
||
> Las katas de esta serie son ejercicios propuestos en el excelente curso [Testing Sostenible con TypeScript](https://academy.softwarecrafters.io/p/curso) de Miguel A. Gómez y Carlos Blé | ||
## Introducción | ||
|
||
El desarrollo guiado por pruebas (TDD) es una metodología esencial en el arsenal de cualquier desarrollador que busca crear software robusto y mantenible. A través de un ejercicio práctico que involucra la filtración de datos de un archivo CSV con información de facturas, podemos apreciar cómo TDD no solo facilita el desarrollo, sino que también mejora la comprensión de los requisitos de negocio. | ||
|
||
En artículos anteriores de esta serie, hemos visto cómo utilizar este enfoque para resolver problemas paso a paso. Sin embargo, por temas de practicidad y porque considero que el ciclo `Red-Green-Refactor` ya está bien entendido, a partir de este artículo lo que haremos es profundizar en los puntos clave, los desafíos encontrados y las lecciones aprendidas. Claro, todo esto sin dejar de lado el valor que espero que estos artículos te aporten. | ||
|
||
<TOCInline toc={props.toc} exclude="Introducción" locale={props.locale} asDisclosure /> | ||
|
||
## Desglose del Ejercicio | ||
|
||
El objetivo del ejercicio es procesar un archivo CSV que contiene múltiples líneas de facturas, aplicando un conjunto de reglas de negocio para determinar qué líneas son válidas. Cada línea de factura, excepto la cabecera, debe cumplir con ciertas condiciones para ser considerada correcta: | ||
|
||
- **Campos Vacíos**. Es válido que algunos campos estén vacíos, representados por comas seguidas o una coma final. Esto añade flexibilidad a la entrada de datos pero también complejidad a la validación. | ||
|
||
- **Unicidad del Número de Factura**. El número de factura debe ser único. Si se detectan duplicados, todas las líneas con dicho número deben ser eliminadas. Esto requiere un análisis cuidadoso de los datos para evitar inconsistencias. | ||
|
||
- **Exclusividad de Impuestos IVA e IGIC**. Solo uno de estos impuestos puede aplicarse por línea. El IVA es un impuesto general de valor agregado usado en muchos países, mientras que el IGIC es específico de las Islas Canarias. Si ambos campos están rellenos, la línea debe ser descartada, lo que implica una lógica de validación clara y precisa. | ||
|
||
- **Exclusividad de Campos CIF y NIF**. Similar a los impuestos, solo uno de estos identificadores puede estar presente en una línea válida. CIF (Código de Identificación Fiscal) y NIF (Número de Identificación Fiscal) son identificadores usados para entidades legales e individuos, respectivamente, en España. | ||
|
||
- **Cálculo Correcto del Neto**. El valor del campo neto debe ser el resultado correcto de aplicar el impuesto correspondiente al bruto. Esta verificación matemática es crucial para asegurar la integridad de los datos. | ||
|
||
## Retos y Consideraciones | ||
|
||
### Definición de Casos de Prueba | ||
|
||
Uno de los principales desafíos en TDD es definir casos de prueba exhaustivos que cubran todas las variaciones de datos posibles. Este ejercicio se centra en asegurar que el sistema se comporte correctamente bajo varios escenarios, incluyendo los siguientes casos de prueba: | ||
|
||
- **Validación de Facturas Correctas**. Verificar que las líneas que cumplen con todas las reglas especificadas, como la unicidad y la aplicación correcta de impuestos, sean aceptadas. | ||
|
||
- **Validaciones de Exclusividad**. Asegurar que las líneas que contienen ambos impuestos (IVA e IGIC) o ambos identificadores (CIF y NIF) sean rechazadas correctamente. | ||
|
||
- **Cálculo del Importe Neto**. Confirmar que las líneas con cálculos incorrectos del importe neto sean identificadas y eliminadas. | ||
|
||
- **Manejo de Casos Limítrofes**. Probar la robustez del sistema con casos extremos, como archivos vacíos o archivos que contienen solo una línea. | ||
|
||
### Manejo de Casos Especiales | ||
|
||
Es crucial anticipar y manejar casos anómalos que podrían surgir en el uso del sistema. Algunas preguntas que surgen son: | ||
|
||
- ¿Qué sucede si la cabecera está ausente? | ||
- ¿Qué pasa si los campos están desordenados o hay campos desconocidos? | ||
|
||
Estas preguntas no solo requieren un diseño técnico sólido, sino también una comunicación constante con los expertos de negocio para definir expectativas claras. Esto es muy importante, ya que cuando nos atoramos con casos especiales porque no es claro cómo afrontarlos, lo que hay que hacer es consultar a los expertos de negocio. Jamás hay que asumir lo que nos parezca "razonable", pues cada negocio opera de manera distinta. | ||
|
||
### Simplicidad y Refactorización | ||
|
||
A medida que se desarrollan más pruebas y se implementan más reglas, el código puede volverse complejo. La refactorización continua es esencial para mantener el código limpio, legible y fácil de mantener. Esto implica: | ||
|
||
- **Uso de Variables Explicativas**. Introducir variables que expliquen el propósito de bloques de código complejos. | ||
- **Extracción de Métodos**. Descomponer funciones largas en métodos más pequeños y específicos. | ||
- **Renombrado de Métodos y Variables**. Asegurarse de que los nombres reflejen claramente su propósito y contenido. | ||
|
||
## Buenas Prácticas en TDD | ||
|
||
- **Inicio con Pruebas Simples**. Comienza escribiendo pruebas para los casos más simples y avanza gradualmente hacia situaciones más complejas. Esto no solo reduce la carga cognitiva, sino que también permite un desarrollo incremental y controlado. | ||
|
||
- **Commits Frecuentes**. Realizar commits después de cada prueba que pasa o cada refactorización es crucial. Esto permite revertir cambios fácilmente si algo sale mal, manteniendo el flujo de trabajo estable. Por ejemplo, hacer un commit después de crear una prueba y verla en `Red`, luego otro commit para `Green` y si aplica, otro(s) para `Refactor`, ya que cada pequeño cambio debe ser registrado. Para no tener un historial gigante de commits, al final pueden combinarse en uno usando `git squash`. Visto de otra forma, serían `microcommits`. | ||
|
||
- **Refactorización Continua**. No esperes a que el código se vuelva inmanejable para refactorizar. Hacer pequeños ajustes continuamente mantiene el código limpio y coherente. | ||
|
||
- **Pruebas con Propósito Único**. Asegúrate de que cada prueba tenga un único motivo para fallar. Esto facilita la identificación de errores y asegura que cada prueba cubre un caso específico sin superposiciones innecesarias. | ||
|
||
- **Colaboración con Expertos de Negocio**. Para dejarlo todavía más claro. Las reglas de negocio pueden ser complejas y no siempre obvias. Colabora con los expertos para aclarar cualquier duda y asegurarte de que las pruebas reflejan fielmente los requisitos del negocio. | ||
|
||
## Enlace al repositorio de GitHub | ||
|
||
Puedes encontrar esta kata, y el resto de ellas, [aquí](https://github.com/carlos-talavera/katas-sustainable-testing-ts). | ||
|
||
## Conclusión | ||
|
||
Este ejercicio de filtrar facturas en un archivo CSV mediante TDD nos recuerda la importancia de un enfoque disciplinado y metódico en el desarrollo de software. Mediante la definición precisa de reglas de negocio y casos de prueba, y con una refactorización continua, podemos crear soluciones que no solo cumplen con los requisitos actuales, sino que también son fáciles de mantener y escalar en el futuro. TDD es más que una técnica de prueba; es una filosofía de desarrollo que guía hacia un código de alta calidad y un entendimiento profundo del problema que se está resolviendo. | ||
|
||
Implementar TDD en ejercicios prácticos como este no solo mejora nuestras habilidades técnicas, sino que también nos ayuda a desarrollar un enfoque más sistemático para abordar problemas complejos. Al final del día, el verdadero valor de TDD radica en su capacidad para transformar la manera en que pensamos y construimos software. Si tienes alguna duda o quieres compartir algo, déjalo en los comentarios :) |