No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Aprende todo un fin de semana sin pagar una suscripci贸n 馃敟

Reg铆strate

Comienza en:

1D
16H
41M
54S
Curso B谩sico de Testing en Java

Curso B谩sico de Testing en Java

Ferran Maylinch Carrasco

Ferran Maylinch Carrasco

Ejemplos de TDD: calcular el a帽o bisiesto

13/24
Recursos

Descripci贸n:
Los a帽os bisiestos son a帽os con 366 d铆as en vez de 365 y suceden cada 4 a帽os.

Para determinar si un a帽o es bisiesto o no, debemos seguir las siguientes reglas:

  • Todos los a帽os divisibles por 400 son bisiestos (1600, 2000, 2400)
  • Todos los a帽os divisibles por 100 pero NO por 400 NO son bisiestos (1700, 1800, 1900)
  • Todos los a帽os divisibles por 4 son bisiestos (1996, 2004, 2012)
  • Todos los a帽os que NO son divisibles por 4 NO son bisiestos (2017, 2018, 2019)

Algunas clases de pruebas terminan con la palabra Should en lugar de Test porque podemos entenderlas como frases cuando se leen en conjunto con los nombres de los m茅todos.

Por ejemplo, la clase DateUtilLeapYearShould con su m茅todo return_true_when_year_is_divisible_by_400 pueden leerse como 鈥淒ate utils leap year should return true when year is divisible by 400鈥 o 鈥淟os utils para calcular el a帽o bisiesto deben devuelven true cuando el a帽o es divisible por 400鈥.

Aportes 34

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Dejo aqui las notas:

All years divisible by 400 ARE Leap years (1600, 2000, 2400)
All years divisible by 100 but not by 400 are NOT leap years (1700, 1880, 1900),
All years divisible by 4 but not by 100 ARE 1eap years (1996, 2004, 2008),
All years not divisible by 4 are NOT Leap years (2017, 2018, 2019)

Tener en cuenta que al dia de hoy la funccion assertThat esta marcado como deprecated en junit4

REFACTORING:

public static boolean isLeapYear(int year) {
        return (year % 4 == 0 && year % 100 != 0) || (year % 400) == 0;
    }

En TDD NUNCA se pasan los test a verde "por casualidad". Lo que pasa es que el profesor no ha seguido correctamente el proceso del TDD. 1. Escribimos los Test. 2. Desarrollamos el codigo. 3. Refactorizamo si es necesario .

para los que usan la versi贸n 5 de junit
para usar el assertThat y el is

<dependency>
     <groupId>org.hamcrest</groupId>
     <artifactId>hamcrest-all</artifactId>
     <version>1.3</version>
     <scope>test</scope>
</dependency>

Me surgi贸 una duda al ver este nuevo AssertThat. Ya que sent铆a que podr铆a hacer lo mismo con un assertTrue o assertFalse. Busqu茅 en internet, y encontr茅 que el MOTIVO por el que se usa assertThat sobre estos otros es por: FACILIDAD DE LECTURA (Redability). Siento que lo explican MUY bien en esta p谩gina, asi que aqu铆 os la dejo 馃槃. Espero os sirva

Para quien est茅 viendo el video en 2022 o posterior y utiliza junit5

        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest</artifactId>
            <version>2.2</version>
            <scope>test</scope>
        </dependency>

Imports

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

Me gusta la idea del TDD, tienes t煤, o quiz谩s otro compa帽ero alguna gu铆a para implementarla en aplicaciones m谩s del mundo real?
No s茅 bien como podr铆a implementar TDD al hacer un microservicio, o al hacer una API,
Hay alguna gu铆a para hacerlo? He intentado buscar por internet, pero no he dado con nada convincente.

DateUtil.java

package com.platzi.javatests.util;

public class DateUtil {

  public static boolean isLeapYear(int year) {
    return (year % 400 == 0) || (year % 4 == 0 && year % 100 != 0);
  }
}

DateUtilLeapYearShould.java

package com.platzi.javatests.util;

import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class DateUtilLeapYearShould {
  /**
   * All years divisible by 400 ARE leap years (1600, 2000, 2400).
   * All years divisible by 100 but not by 400 are NOT leap years (1700, 1800, 1900).
   * All years divisible by 4 but not by 100 ARE leap years (1996, 2004, 2008).
   * All years are not divisible by 4 are NOT leap years (2017, 2018, 2019).
   */

  @Test
  public void returnTrue_whenYearIsDivisibleBy400() {
    assertThat(DateUtil.isLeapYear(1600), is(true));
    assertThat(DateUtil.isLeapYear(2000), is(true));
    assertThat(DateUtil.isLeapYear(2400), is(true));
  }

  @Test
  public void returnFalse_whenYearIsDivisibleBy100ButNotBy400() {
    assertThat(DateUtil.isLeapYear(1700), is(false));
    assertThat(DateUtil.isLeapYear(1800), is(false));
    assertThat(DateUtil.isLeapYear(1900), is(false));
  }

  @Test
  public void returnTrue_whenYearIsDivisibleBy4ButNotBy100() {
    assertThat(DateUtil.isLeapYear(1996), is(true));
    assertThat(DateUtil.isLeapYear(2004), is(true));
    assertThat(DateUtil.isLeapYear(2008), is(true));
  }

  @Test
  public void returnFalse_whenYearIsNotDivisibleBy4() {
    assertThat(DateUtil.isLeapYear(2017), is(false));
    assertThat(DateUtil.isLeapYear(2018), is(false));
    assertThat(DateUtil.isLeapYear(2019), is(false));
  }
}

por favor evitar usa los importes con *, as铆 sea en casos pr谩cticos, es mala pr谩ctica y si lo haces aprendiendo tambi茅n lo haces en el trabajo saludos

Una observaci贸n para los que esten viendo este curso sobre la metodologia de TDD, literal en la anterior clase se explic贸 que los pasos son ROJO(falla), VERDE(pasa) y AZUL(refactor).
En ese orden, debi贸 haberse escrito el Test antes que el c贸digo, probar que fallar谩 y luego si escribir el c贸digo que hiciera que pasar谩 el test.
Pero ac谩 no se sigui贸 ese orden, y comenzamos con VERDE, para luego pasar a ROJO.

Si se hace como dicta TDD, ser铆a algo asi:

  1. Escribir el test
  2. Error (ROJO), la clase no existe (DateUtil)
  3. Se crea la clase, se corre el Test
  4. Error (ROJO), la clase no tiene el metodo (isLeapYear)
  5. Se crea el metodo para que retorne falso siempre.
  6. Se corre el Test, error (ROJO), se espera true, se obtiene falso
  7. Se modifica el codigo para los casos multiplos de 400.
  8. Se corre el Test, pasa (VERDE).
  9. Se crea el nuevo Test, se corre, no pasa (ROJO)
  10. Se modifica el codigo, etc

Parece tedioso, pero asi es el flujo y en aras de la pedagogia hubiera sido bueno hacerlo asi.

Sorprendente el Ide, ayuda mucho a detectar, implementar y refactorizar.

Buena clase gracias 馃槂

Otra posible soluci贸n:

public static boolean esBisiesto(int year) {
        return !(year % 100 == 0 && year % 400 != 0) ;
    }

Mi aporte de c贸digo en one line 馃槂

public static boolean isLeapYear(int year){
        return (year%400 == 0 || (year%4 == 0 && year%100 != 0))? true : false;
    }

Refactor 0.0

package Utils;

public class DateUtil {
    public static boolean isLeapYear(int year) {
        boolean isMultiple4 = year % 4 == 0 && year % 100 != 0;
        boolean isDivisibleFor400 = year % 400 == 0;

        return isMultiple4 || isDivisibleFor400;
    }

}

El c贸digo lo vi c贸mo un poco m谩s entendible de est谩 manera:

public static boolean isLeapYear(int year){
        boolean divisibleBy4ByNotBy100 = (year % 4 == 0 && year % 100 != 0);
        boolean isJustDivisibleBy400 = (year % 400 == 0);
        boolean isDivisibleBy100ByNotBy400 = !(year % 100 == 0 && year % 400 != 0);
        return (isJustDivisibleBy400 || divisibleBy4ByNotBy100) && isDivisibleBy100ByNotBy400;
    }```

Test creados

<package com.prueba.test.utilidad;

import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class DateUtilsTest {

    private DateUtils dateUtils;

    @Before
    public void setUp() {
        dateUtils = new DateUtils();
    }


    @Test
    public void ifYearIsDivisibleBy400_IsLeap() {
        assertThat(dateUtils.isLeapYear(2000), is(true));
    }

    @Test
    public void ifYearIsDivisibleBy4ButItIsNotDivisibleBy400_IsNotLeap() {
        assertThat(dateUtils.isLeapYear(2019), is(false));
    }

    @Test
    public void ifYearIsDivisibleBy4ButItIsNotDivisibleBy100_IsLeap() {
        assertThat(dateUtils.isLeapYear(1996), is(true));
    }

    @Test
    public void ifYearIsNotDivisibleBy4_IsNotLeap() {
        assertThat(dateUtils.isLeapYear(2017), is(false));
    }
}>

DateUtil

    public static  boolean isLeadYear(int year){
        if ((year % 400 == 0) || ((year % 100 != 0)&&(year % 4 == 0))){
            return true;
        }
        return  false;
    }

public class DateUtilTest {

    @Test
    public void year_is_Leap() {
        boolean result = DateUtil.isLeadYear(1600);
        assertTrue(result);
         result = DateUtil.isLeadYear(2000);
        assertTrue(result);
         result = DateUtil.isLeadYear(1996);
        assertTrue(result);
         result = DateUtil.isLeadYear(2008);
        assertTrue(result);
    }
    @Test
    public void year_is_not_Leap() {
        boolean result = DateUtil.isLeadYear(1700);
        assertFalse(result);
        result = DateUtil.isLeadYear(2017);
        assertFalse(result);
        result = DateUtil.isLeadYear(2019);
        assertFalse(result);
        result = DateUtil.isLeadYear(2018);
        assertFalse(result);
    }
}

Muy buena clase, donde se pone en practica el TDD, y se explica como se debe de hacer

dateUtils

Muy buena clase y explicacion. Hay muchas personas que ofrecen codigos diferentes y la verdad es genial, cada quien tiene su tipo o forma de programar. Por lo menos yo ese tipo de simplicaciones como la que hizo en el if no me gustan, prefiero ver todo. Puede que en un codigo grande afecte, pero a futuro por lo menos para mi es mas facil entenderlo.

Por que los a帽os 1700,1800 y 1900 no son bisiestos? el metodo se deberia simplemente con que el a帽o sea divisible entre 4:

return year % 4 == 0;

Tengo una duda no se supone que primero tenia que hacer fallar el test ya que es el paso numero

Es aconsejable realizar muchas simplificaciones o es mejor que el c贸digo sea claro aunque implique ser un poco mas largo pero entendible

package com.platzi.JavaTEST.StringEmpty;

public class DateUtil {

	public static boolean isLeapYear(int year) {

		//forma 1
		return forma1(year);
		//return forma2(year);
		
	}
	
	public static boolean forma1(int year) {
		if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
			return true;
		} else {
			return false;
		}
	}
	
	public static boolean forma2(int year) {
		return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
	}
}

package com.platzi.JavaTEST.StringEmpty;

import static org.hamcrest.CoreMatchers.is;
import org.junit.Test;
import static org.junit.Assert.assertThat;

public class DateUtilShould {

	/**
	 * All years divisible by 400 ARE leap years (1600, 2000, 2400). All years
	 * divisible by 100 but not by 400 are NOT leap years (1700, 1800, 1900). All
	 * years divisible by 4 but not by 100 ARE leap years (1996, 2004, 2008). All
	 * years are not divisible by 4 are NOT leap years (2017, 2018, 2019).
	 */

	@Test
	public void return_true_when_year_is_divisible_by_400() {
		assertThat(DateUtil.isLeapYear(2000), is(true));
		assertThat(DateUtil.isLeapYear(1600), is(true));
		assertThat(DateUtil.isLeapYear(2400), is(true));
	}

	@Test
	public void return_false_when_year_is_divisible_by_100_but_not_by_400() {
		assertThat(DateUtil.isLeapYear(1700), is(false));
		assertThat(DateUtil.isLeapYear(1800), is(false));
		assertThat(DateUtil.isLeapYear(1900), is(false));
	}

	@Test
	public void return_true_when_years_are_divisible_by_4_but_not_by_100() {
		assertThat(DateUtil.isLeapYear(1996), is(true));
		assertThat(DateUtil.isLeapYear(2004), is(true));
		assertThat(DateUtil.isLeapYear(2008), is(true));
	}

	@Test
	public void return_false_when_years_arent_divisible_by_4() {
		assertThat(DateUtil.isLeapYear(2017), is(false));
		assertThat(DateUtil.isLeapYear(2018), is(false));
		assertThat(DateUtil.isLeapYear(2019), is(false));
	}
}

En programaci贸n funcional se me ocurri贸 esto 驴Tal vez, se podr铆a hacer mejor?

public class DateUtil {

    public static boolean isLeadYear(int year) {
        Predicate<Integer> divisibleBy400 = x -> x % 400 == 0;
        Predicate<Integer> divisibleBy4AndNotBy100 = x -> x % 4 == 0 && x % 100 != 0;

        return divisibleBy400.or(divisibleBy4AndNotBy100).test(year);
    }
}

Se crean primero los tests de esta manera vamos escribiendo el c贸digo necesario para que los test fallen.
Una vez que fallan se ajusta el c贸digo para que tengan 茅xito y una vez teniendo 茅xito en todas los test, se optimiza el c贸digo.

En Kotlin.

 fun isLeapYear(year : Int) : Boolean{
        return when {
            year % 400 == 0 && year % 4 == 0  -> {
                true
            }
            else -> {
                false
            }
        }
    }

Excelente clase instructor Ferran, con el uso de este enfoque de programaci贸n podremos verificar que parte est茅 funcionando e iremos notando que partes podremos mejorar.

public static boolean isLeapYear(int year){
        return (year % 400 == 0 || year % 100 == 0 || year % 4 == 0);
    }

Gracias

Hola, a mi me qued贸 as铆

DateUtilLeapYear

public class DateUtilLeapYear {

    public boolean isLeapYear(int year) {
        return year % 100 != 0 || year % 400 == 0;
    }

}

DateUtilLeapYearShould

class DateUtilLeapYearShould {

    @Test
    public void return_true_when_year_is_divisible_by_400() {
        assertTrue(new DateUtilLeapYear().isLeapYear(1600));
        assertTrue(new DateUtilLeapYear().isLeapYear(2000));
        assertTrue(new DateUtilLeapYear().isLeapYear(2400));
    }

    @Test
    public void return_false_when_year_is_divisible_by_100_but_not_by_400() {
        assertFalse(new DateUtilLeapYear().isLeapYear(1700));
        assertFalse(new DateUtilLeapYear().isLeapYear(1800));
        assertFalse(new DateUtilLeapYear().isLeapYear(1900));
    }

    @Test
    public void return_true_when_year_is_divisible_by_4() {
        assertTrue(new DateUtilLeapYear().isLeapYear(1996));
        assertTrue(new DateUtilLeapYear().isLeapYear(2004));
        assertTrue(new DateUtilLeapYear().isLeapYear(2012));
    }

    @Test
    public void return_false_when_year_is_not_divisible_by_4() {
        assertTrue(new DateUtilLeapYear().isLeapYear(2017));
        assertTrue(new DateUtilLeapYear().isLeapYear(2018));
        assertTrue(new DateUtilLeapYear().isLeapYear(2019));
    }

}