Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

22 Commits

Repository files navigation

Library

INTEGRANTES

ANDERSSON DAVID SÁNCHEZ MÉNDEZ

CRISTIAN SANTIAGO PEDRAZA RODRÍGUEZ

PRE-RREQUISITOS

  • Java OpenJDK Runtime Environment 17.x.x

  • Apache Maven: 3.9.x

  • JUnit: 5.x.x

  • Docker

OBJETIVOS

  • ¿Cómo hacer pruebas unitarias?
  • Utilizar anotaciones @Test del framework JUnit.
  • Aplicar TDD.

DESCRIPCIÓN PROYECTO

El proyecto consiste en un sistema de gestión de bibliotecas, donde hay clases que representan Libro, Usuario, Prestamo, y Biblioteca. Los usuarios pueden tomar prestados libros de la biblioteca, y la Biblioteca se encarga de gestionar los préstamos, asegurarse de que los libros estén disponibles, y mantener un registro de los libros prestados.

CREAR PROYECTO CON MAVEN

  1. Verificamos la versión

alt text

  1. Ahora creamos el directorio con el comando proporcionado.

Busque cómo ejecutar desde línea de comandos el objetivo "generate" del plugin "archetype", con los siguientes parámetros:

Grupo: edu.eci.cvds Artefacto: Library Paquete: edu.eci.cvds.tdd archetypeArtifactId: maven-archetype-quickstart 

Según documentación, hay que seguir este ejemplo

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false

Haciendo que nuestro comando quede como:

mvn archetype:generate -DgroupId=edu.eci.cvds -DartifactId=Library -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false -Dpackage=edu.eci.cvds.tdd

alt textalt text

Exitosa creación de proyecto alt text


AGREGAR DEPENDENCIA JUNIT5

  • Buscar en maven central la dependencia de JUnit5 en su versión más reciente.
  • Edite el archivo pom.xml del proyecto para agregar la dependencia.
  • Verifique que la versión de java sea la 17
<properties>
<maven.compiler.target>1.17</maven.compiler.target>
<maven.compiler.source>1.17</maven.compiler.source>
</properties>

alt text

  • Compile el proyecto para validar que todo este bien.

alt text

AGREGAR ESQUELETO DEL PROYECTO

Cree los siguientes paquetes dentro de edu.eci.cvds.tdd

  • library : book, loan, user

Estos paquetes también se deben crear en la carpeta de test.

alt text

AGREGAR CLASES

En el paquete edu.eci.cvds.tdd.library.book cree la siguiente clase:

packageedu.eci.cvds.tdd.library.book;
publicclassBook {
privatefinalStringtittle;
privatefinalStringauthor;
privatefinalStringisbn;
publicBook(Stringtittle, Stringauthor, Stringisbn) {
this.tittle = tittle;
this.author = author;
this.isbn = isbn;
}
publicStringgetTittle() {
returntittle;
}
publicStringgetAuthor() {
returnauthor;
}
publicStringgetIsbn() {
returnisbn;
}
@Overridepublicbooleanequals(Objectobj) {
returnisbn.equals(((Book)obj).isbn);
}
}

A continuación en el paquete edu.eci.cvds.tdd.library.user cree la siguiente clase:

packageedu.eci.cvds.tdd.library.user;
publicclassUser {
privateStringname;
privateStringid;
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name = name;
}
publicStringgetId() {
returnid;
}
publicvoidsetId(Stringid) {
this.id = id;
}
}

En el paquete edu.eci.cvds.tdd.library.loan se deben crear las clases Loan y el enum LoanStatus:

packageedu.eci.cvds.tdd.library.loan;
importedu.eci.cvds.tdd.library.book.Book;
importedu.eci.cvds.tdd.library.user.User;
importjava.time.LocalDateTime;
publicclassLoan {
privateBookbook;
privateUseruser;
privateLocalDateTimeloanDate;
privateLoanStatusstatus;
privateLocalDateTimereturnDate;
publicBookgetBook() {
returnbook;
}
publicvoidsetBook(Bookbook) {
this.book = book;
}
publicUsergetUser() {
returnuser;
}
publicvoidsetUser(Useruser) {
this.user = user;
}
publicLocalDateTimegetLoanDate() {
returnloanDate;
}
publicvoidsetLoanDate(LocalDateTimeloanDate) {
this.loanDate = loanDate;
}
publicLoanStatusgetStatus() {
returnstatus;
}
publicvoidsetStatus(LoanStatusstatus) {
this.status = status;
}
publicLocalDateTimegetReturnDate() {
returnreturnDate;
}
publicvoidsetReturnDate(LocalDateTimereturnDate) {
this.returnDate = returnDate;
}
}
packageedu.eci.cvds.tdd.library.loan;
publicenumLoanStatus {
ACTIVE, RETURNED
}

Por último se debe crear la siguiente clase en el paquete edu.eci.cvds.tdd.library

packageedu.eci.cvds.tdd.library;
importedu.eci.cvds.tdd.library.book.Book;
importedu.eci.cvds.tdd.library.loan.Loan;
importedu.eci.cvds.tdd.library.user.User;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
importjava.util.Map;
/** * Library responsible for manage the loans and the users. */publicclassLibrary {
privatefinalList<User> users;
privatefinalMap<Book, Integer> books;
privatefinalList<Loan> loans;
publicLibrary() {
users = newArrayList<>();
books = newHashMap<>();
loans = newArrayList<>();
}
/** * Adds a new {@link edu.eci.cvds.tdd.library.book.Book} into the system, the book is store in a Map that contains * the {@link edu.eci.cvds.tdd.library.book.Book} and the amount of books available, if the book already exist the * amount should increase by 1 and if the book is new the amount should be 1, this method returns true if the * operation is successful false otherwise. * * @param book The book to store in the map. * * @return true if the book was stored false otherwise. */publicbooleanaddBook(Bookbook) {
//TODO Implement the logic to add a new book into the map.returnfalse;
}
/** * This method creates a new loan with for the User identify by the userId and the book identify by the isbn, * the loan should be store in the list of loans, to successfully create a loan is required to validate that the * book is available, that the user exist and the same user could not have a loan for the same book * {@link edu.eci.cvds.tdd.library.loan.LoanStatus#ACTIVE}, once these requirements are meet the amount of books is * decreased and the loan should be created with {@link edu.eci.cvds.tdd.library.loan.LoanStatus#ACTIVE} status and * the loan date should be the current date. * * @param userId id of the user. * @param isbn book identification. * * @return The new created loan. */publicLoanloanABook(StringuserId, Stringisbn) {
//TODO Implement the login of loan a book to a user based on the UserId and the isbn.returnnull;
}
/** * This method return a loan, meaning that the amount of books should be increased by 1, the status of the Loan * in the loan list should be {@link edu.eci.cvds.tdd.library.loan.LoanStatus#RETURNED} and the loan return * date should be the current date, validate that the loan exist. * * @param loan loan to return. * * @return the loan with the RETURNED status. */publicLoanreturnLoan(Loanloan) {
//TODO Implement the login of loan a book to a user based on the UserId and the isbn.returnnull;
}
publicbooleanaddUser(Useruser) {
returnusers.add(user);
}
}

Para validar que la estructura del proyecto está bien se debe compilar usando el comando package.

alt text

PRUEBAS UNITARIAS Y TDD

Para poder implementar los métodos addBook, loanABook y returnLoan de la clase Library vamos a aplicar la técnica de TDD, por cada caso de prueba se debe hacer un commit, cada commit debe tener la prueba nueva y la implementación para que la prueba del commit funcione. Las pruebas anteriormente implementadas deben continuar funcionando. Como están trabajando en parejas es necesario trabajar en ramas independientes y utilizar Pull Request para mezclar los cambios.

Teniendo en cuenta esa técnica, hicimos las pruebas primero, y nos damos cuenta que las pruebas no pasan porque no se ha hecho la implementación correspondiente:

alt text

CREAR CLASE DE PRUEBA

Es necesario crear la clase de prueba para edu.eci.cvds.tdd.Library, la clase debe seguir los estándares de nombres estudiados en clase.

alt text

Para pensar en los casos de pruebas lean detenidamente el javadoc de los métodos para reconocer las clases de equivalencia, basados en las clases de equivalencia se debe crear una prueba la cual debe fallar y posteriormente implementar el código necesario para que funcione, este proceso se debe repetir hasta cumplir con la especificación definida en el javadoc.

COBERTURA

  • Agregar la dependencia de jacoco, utilizar la última versión disponible en maven central.
  • Para usar Jacoco es necesario agregar la siguiente sección en el pom.xml
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<excludes>
<exclude>/configurators/</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>jacoco-check</id>
<goals>
<goal>check</goal>
</goals>
<configuration>
<rules>
<rule>
<element>PACKAGE</element>
<limits>
<limit>
<counter>CLASS</counter>
<value>COVEREDRATIO</value>
<minimum>0.85</minimum><!--Porcentaje mínimo de cubrimiento para construir el proyecto-->
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Ahora al compilar el proyecto en la carpeta target se debe crear una carpeta con el nombre site la cual tiene un index.html , al abrir dicho archivo se debe ver la cobertura total y de cada una de las clases, el objetivo es tener la cobertura superior al 80%.

alt text

alt text

Explore los links del reporte en el cual le muestra que partes del código tienen prueba y cuales no.

alt text

SONARQUBE

Ahora es necesario hacer el análisis estático del código usando SonarQube, para lo cual necesitamos tener Docker.

  • Para lo cual se debe descargar la assets/imagen de docker con el siguiente comando docker pull sonarqubealt text

  • Ahora se debe arrancar el servicio de SonarQube con el siguiente comando docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest

alt text

  • Validar funcionamiento docker ps -a

alt text

  • Iniciar sesión en sonar localhost:9000 cambiar la clave por defecto usuario y contraseña es admin.

alt textalt text

  • Entrar a las opciones de la cuenta -> Account -> settings -> generate token; una vez sonar este corriendo deben generar un token.

alt text

alt text

alt text

  • Instale sonarLint en el IDE que este manejando.

alt text

  • Añada el plugin de Sonar en el archivo pom del proyecto.
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>4.0.0.4121</version>
</plugin>
  • Añada las propiedades de SonarQube y Jacoco.
<sonar.projectKey>library</sonar.projectKey>
<sonar.projectName>library</sonar.projectName> <sonar.host.url>http://localhost:9000</sonar.host.url>
<sonar.coverage.jacoco.xmlReportPaths>target/site/jacoco/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
<sonar.coverage.exclusions>src//configurators/*</sonar.coverage.exclusions>
  • Construya el proyecto, genere el reporte de JACOCO y corrija el cubrimiento de las pruebas de unidad para que su proyecto se construya adecuadamente.

alt text

alt text

  • Genere la integración con sonar mvn verify sonar:sonar -D sonar.token=[TOKEN_GENERADO]

En este caso con este comando: mvn verify sonar:sonar -D sonar.token=squ_ac755884f726e68a70bb732ded2f6c5d90c9622c

alt textalt text

  • Se verifica en SonarLint el proyecto Library alt text

PRUEBAS FINALES

Luego de hacer todas las pruebas, y luego si hacer la implementación necesaria para que estas pasaran. Se obtuvo en SonarQube una cobertura de:

alt text

Y también se mira el análisis estático de las pruebas, validando que para clase se hicieron las pruebas correspondientes, y se cumple con las condiciones prestablecidas:

alt text

CONFIGURACIÓN DE GITIGNORE

En este caso, se ignoran los directorios target y .mvn.

alt text

About

Library is a Java-based system for managing library operations, allowing users to borrow and return books. Built with Maven and tested using JUnit 5 under a TDD approach, it ensures reliable management of book inventories, user records, and loan statuses. The project emphasizes clean code, unit testing, code coverage(JaCoCo,) and static analysis.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages