Crea una cuenta o inicia sesi贸n

隆Contin煤a aprendiendo sin ning煤n costo! 脷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:

3D
11H
19M
42S

Testing de Views

5/17
Recursos

Aportes 41

Preguntas 6

Ordenar por:

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

o inicia sesi贸n.

Mi aporte al reto:

Mi soluci贸n

    def test_questions_with_future_pub_date(self):
        """
            Questions with a pub_date greater than the current date should not appear in the Index View.
        """
        Question(question_text='Present Question', pub_date=timezone.now()).save()
        Question(question_text='Future Question', pub_date=timezone.now() + datetime.timedelta(days=30)).save()

        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Present Question")
        self.assertNotContains(response, "Future Question")

Soluci贸n al Challenge (atento a la retroalimentaci贸n)

def test_questions_with_future_pub_date(self):
        """Questions with date greater to timezone.now shouldn't be displayed"""
        time = timezone.now() + datetime.timedelta(days = 30)
        future_question = Question(question_text = "This is a Question for the test", pub_date = time)
        future_question.save()
        response = self.client.get(reverse('polls:index'))
        self.assertNotIn(future_question, response.context['latest_question_list'])
(venv) [email protected]:~/work/premiosplatziapp # python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.....
----------------------------------------------------------------------
Ran 5 tests in 0.018s

OK
Destroying test database for alias 'default'...

Para evitar el error de los par茅ntesis que tuvo Facundo, les recomiendo instalar la extensi贸n de VSCode llamado 鈥淩ainbow Brackets鈥. Es muy 煤til ya que identifica cada par de par茅ntesis con un color diferente y resalta que par茅ntesis le corresponde a su par.

Mi soluci贸n al reto luce de la siguiente manera (estar茅 atento a sus criticas constructivas xd):

Testing de views

Una ejercicio para hacer testing de una view es por ejemplo revisar si hay o no preguntas. Para esto, se crea una clase que testea a las vistas y al modelo y luego se crea un m茅todo para el caso espec铆fico:
En el archivo tests.py

class QuestionIndexViewTest(TestCase):
    def test_no_questions(self):
        """If no question exist, an appropiate message is displayed"""
        # estoy haciendo una peticion get http y se guarda en response
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context["latest_question_list"], [])

Si te aparece el siguiente error al ejecutar el test :

name 鈥榬everse鈥 is not defined

debes de importar el modulo reverse de Django

from django.urls import reverse
    def test_IndexView_show_future_questions(self):
        '''
        IndexView shouldn't show questions that were posted in the future
        '''
        Question.objects.create(question_text='Question_now', pub_date=timezone.now())
        Question.objects.create(question_text='Question_future', pub_date=timezone.now() + datetime.timedelta(days=30))
        Question.objects.create(question_text='Question_past', pub_date=timezone.now() - datetime.timedelta(days=30))
        
        path = reverse('polls:index')
        response = self.client.get(path)

        question_list = response.context['latest_question_list']
        time_now = timezone.now()
        
        for question in question_list:
            print(question.question_text)
            self.assertIs(question.pub_date>time_now, False)

Les comparto el c贸digo que realice para validar que no se esten mostrando preguntas futuras.

Si alguien tiene el mismo problema que yo con la view index y estan utilizando funciones view pueden aplicar el filtro de esta manera

def index(request):
    latest_question_list = Question.objects.all().filter(pub_date__lte=timezone.now()).order_by("-pub_date")[:5]
    return render(request,"polls/index.html",{
        "latest_question_list":latest_question_list
    })

El 鈥渁ssertContains鈥 le podemos tirar alta magia.

Suponiendo que tenemos un texto adentro del index que dice :
鈥淣o polls here in this page. If you are here there is a problem .鈥

Le metemos en el assertContain solo un pedacito del texto FUNIONA.
y ademas
Se puede hacer comparativas in situ. Vean el codigo.

Por lo tanto ojo que si le metemos un mini string por ejemplo 鈥渢al鈥 va a dar True si hay escrito 鈥渆l tarro de talco鈥 , " el SR. dijo tal cosa" , 鈥渆l talisman del heroe鈥 etc etc

Saludos

class QuestionIndexViewTest(TestCase):
    def test_no_questions(self):
        """If no question existe, a raisonable message is displayed"""
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls here in" and "f you are here there is a probl")
def test_future_question_no_published(self):
        """If question pub date is in the future, don't show it in the index page"""
        response = self.client.get(reverse("polls:index"))
        time = timezone.now() + datetime.timedelta(days=15)
        future_question = Question(question_text="Who is the best Platzi's Course Director ?", pub_date=time)
        self.assertNotContains(response, future_question)
def test_questions_published_in_future_dont_be_displayed_in_present(self):
        """if a question have a pub_date in future, don麓t be displayed now"""
        time = timezone.now() + datetime.timedelta(days=30)
        Question(question_text="驴Test Question?",pub_date=time).save()
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, "驴Test Question?")

Mi soluci贸n para el reto:

def test_no_future_question_are_displayed(self):
        """If there are a question published in the future, this question won't be displayed"""
        response = self.client.get(reverse("polls:index"))
        time = timezone.now() + datetime.timedelta(days = 30)
        self.assertEqual(response.status_code, 200)
        future_question = Question(question_text="驴Mejor p谩gina de Platzi?", pub_date=time)
        self.assertNotContains(response, future_question.question_text)

Las pruebas que requieren una base de datos (conocidas como pruebas de modelo) no utilizar谩n tu base de datos 鈥渞eal鈥 (de producci贸n). Se crear谩n bases de datos separadas y vac铆as para las pruebas. Sin importar si las pruebas pasan o fallan, las bases de datos de prueba se destruir谩n cuando se hayan ejecutado todas las pruebas. Por este mismo motivo es valido esperar en la funci贸n test_no_questions() un response con el texto 鈥淣o polls are available鈥.

Si viste los comentarios y te diste cuenta del comando assertNotIn y dijiste 鈥渄onde has estado toda mi vida鈥 dale like jajaja xD

Se agregan dos preguntas, una con fecha en el futuro y la otra con fecha de 300 minutos antes desde el momento de ejecuci贸n.
Se eval煤a que las preguntas obtenidas en el contexto est茅n en una fecha pub_date inferior o igual al momento de ejecuci贸n.

Si la pregunta futura viene en la respuesta lanza una excepci贸n de error, ya que la validaci贸n es False.

    def test_future_questions(self):
        """If future question is returned the test value is false"""

        time_future = timezone.now() + datetime.timedelta(days=300)

        future_question = Question(question_text="驴pregunta en el futuro?", pub_date=time_future)
        now_question = Question(question_text="驴Pregunta ahora?", pub_date=timezone.now() - datetime.timedelta(minutes=300))

        future_question.save()
        now_question.save()

        response = self.client.get(reverse("polls:index"))

        for question in response.context["lates_question_list"]:
            self.assertTrue(question.pub_date <= timezone.now())

Mi aporte a el reto:

 def test_no_questions_future(self):
        """
        If no question future exists, an appropiate message is displayed
        """
        response = self.client.get(reverse("polls:index"))
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(question_text="驴Cu谩l es el mejor profesor de Platzi?", pub_date=time)
        self.assertNotIn(future_question, response.context["latest_question_list"])

Uso el assertNotIn porque lo que haces es que a no est谩 en b osea que la pregunta a futuro no se encuentre en la lista de las 煤ltimas preguntas

Mi codigo

Yo no tuve esa opci贸n de ponerle un datetime a la pregunta cuando la a帽ad铆 por Admin debido a 鈥渁uto_now_add=True鈥 que hab铆a puesto en el modelo Question para evitar esos errores y no modificar las preguntas. Les recomiendo revisar su c贸digo si de casualidad la consola de admin tiene algo similar.

Comparto mi soluci贸n:

def tets_no_questions_future(self):
	"""test para validar que no existan preguntas del futuro"""
	response = self.client.get(reverse("polls:index"))
	preguntas_publicadas = Question.objects.exclude(pub_date__gte=datetime.date.today())
	self.assertQuerysetEqual(response.context["latest_question_list"], preguntas_publicadas)	

Hola el reto creo quedar铆a as铆 :

    def test_show_question_of_future(self):
        """If a question from future is show returns False"""
        time_in_future = timezone.now() + datetime.timedelta(days=30)
        question_from_future = Question(question_text="Question from the future?", pub_date=time_in_future)
        question_from_future.save()
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertNotContains(response, "Question from the future?")

Espero pueda servir a alguien

Mi soluci贸n es la siguiente.: Se agrega solo un registro con fecha del futuro, en la base de datos solo existir铆a un registro, pero est谩 en el futuro el set de objetos debe venir vaci贸.

``
def test_no_questions_future(self):
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(1,"驴Qui茅n es el mejor Course Director de Platzi?",pub_date=time)
        future_question.save()
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code,200)
        #self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context["latest_question_list"],[]) 
```   
```

Mi propuesta:

import datetime

from django.test import TestCase
from django.utils import timezone
from django.urls import reverse

from .models import Question

# * Lo m谩s com煤n es hacer tests sobre modelos y/o vistas en Django


class QuestionModelTests(TestCase):
    def setUp(self):
        self.question = Question(
            question_text='驴Qui茅n es el mejor Course Director de Platzi?')
        self.future_time = timezone.now() + datetime.timedelta(days=30)
        self.past_time = timezone.now() - datetime.timedelta(days=30)
        self.recent_time = timezone.now()

    def test_was_published_recently_with_future_questions(self):
        """was_published_recently returns False for questions whose pub_date is in the future"""
        self.question.pub_date = self.future_time
        self.assertIs(self.question.was_published_recently(), False)

    def test_was_published_recently_with_past_questions(self):
        """was_published_recently returns True for questions whose pub_date is in the past"""
        self.question.pub_date = self.past_time
        self.assertIs(self.question.was_published_recently(), False)

    def test_was_published_recently_with_recent_questions(self):
        """was_published_recently returns True for questions whose pub_date is today"""
        self.question.pub_date = self.recent_time
        self.assertIs(self.question.was_published_recently(), True)


class QuestionIndexViewTests(QuestionModelTests, TestCase):
    def test_no_questions(self):
        """If no question exist, an appropiate message is displayed"""
        # * Hago una petici贸n GET al index de polls y guardo la respuesta en response
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

    def test_show_only_recent_questions(self):
        """The view should only show recent questions. It cannot show future questions from the date they are consulted."""
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        future_question = [self.question, self.future_time]
        self.assertNotContains(response, future_question)

Este es el test del reto;

 def test_future_question(self):
        """
        If a future question exist, isn't displayed on the index page.
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(question_text="驴Qui茅n es el mejor Course Director de Platzi?", pub_date=time)
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertQuerysetEqual(response.context["latest_question_list"], [])

Hola, yo realic茅 las siguientes pruebas:

class QuestionIndexViewTests(TestCase):
    def test_no_question(self):
        """
        If no questions exist, an appropriate message is displayed.
        """
        response = self.client.get(reverse(('polls:index')))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['lastest_question_list'], [])
        
    def test_no_question_with_future_question(self):
        """
        Even if no questions exist, if a future question exists, an appropriate message is displayed.
        """
        Question.objects.create(question_text="Future question.", pub_date = timezone.now() + datetime.timedelta(days=30))
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['lastest_question_list'], [])
        
    def test_question_with_past_question_and_future(self):
        """
        If even a past question exists, Only display the past question.
        """
        Question.objects.create(question_text="Past question.", pub_date = timezone.now() - datetime.timedelta(days=30))
        Question.objects.create(question_text="Future question.", pub_date = timezone.now() + datetime.timedelta(days=30))
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Past question.")
        self.assertNotContains(response, "Future question.")
        self.assertEqual(response.context['lastest_question_list'].count(), 1)
        
    def test_question_with_past_and_actual_question(self):
        """
        Exist only past and actual question. Show all questions.
        """
        Question.objects.create(question_text="Past question.", pub_date = timezone.now() - datetime.timedelta(days=30))
        Question.objects.create(question_text="Actual question.", pub_date = timezone.now())
        response = self.client.get(reverse('polls:index'))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "Past question.")
        self.assertContains(response, "Actual question.")
        self.assertEqual(response.context['lastest_question_list'].count(), 2)

Espero que mi aporte le sirva a alguno. A estas alturas entre confundido y dandole duro al ejercio y con un poco de ayuda de github copilot les dejo la solucion al reto de la clase
.

Si estan como yo, un poco aturdidos por las nuevas funciones e informacion de django, algo que me ayudo mucho fue entrar al shell de django y desde alli empezar a ejecutar las funciones una a una para ver los inputs y las salidas, asi entendi un poco mejor la funcion reverse() por ejemplo
.
Ahora si la solucion al reto.
Primero toca colocar

from django.urls import reverse

cree en test.py una funcion que devuleve un question.

def create_question(question_text, days):
        """
        Create a question with the given `question_text` and published the
        given number of `days` offset to now (negative for questions published
        in the past, positive for questions that have yet to be published).
        """
        time = timezone.now() + datetime.timedelta(days=days)
        return Question.objects.create(question_text=question_text, pub_date=time)

y luego implemente en class QuestionIndexViewTests(TestCase):
el siguiente metodo o test.

def test_future_question(self):
        """
        Questions with a pub_date in the future aren't displayed on
        the index page.
        """
        create_question(question_text="Future question.", days=30)
        response = self.client.get(reverse('polls:index'))
        self.assertContains(response, "No polls are available.")
        self.assertQuerysetEqual(response.context['latest_question_list'], [])

al correr los tests con:

py manage.py test polls

la salida fue:

Found 5 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.....
----------------------------------------------------------------------
Ran 5 tests in 0.024s

OK
Destroying test database for alias 'default'...

Si quieren correr los test usando Pychar Community, les dejo la configuarion

Mi Test queda as铆

def test_no_questions_in_the_future(self):
        """Question created in the future has not been included in latest_question_list"""
        Question(question_text="Question in the future?", pub_date=timezone.now() + timezone.timedelta(days=1)).save()
        response = self.client.get(reverse("polls:index"))
        self.assertQuerysetEqual(response.context["latest_question_list"], [])

Mi propuesta: al ser una pregunta futura, no deber铆a estar dentro del 鈥渓atest_question_list鈥, que luego se representa en el index view 馃槂

def test_future_question_is_not_displayed(self):
        """"If there is a future question, it is not shown in the index view"""
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(question_text="Qui茅n es el mejor CD de Platzi?", pub_date=time).save()
        response = self.client.get(reverse("polls:index"))
        self.assertQuerysetEqual(response.context["latest_question_list"], [])

En la documentaci贸n no encontr茅 nada que ayudase 馃槮

**Soluciob al reto de la clase anterior. **
Utilize el metodo assertEqual como lo recomendo el profe

    def test_was_pusblished_recentely_with_present_question(self):
        """Was_published_recently returns True for quiestion whose pub_date is at now"""
        time = timezone.now() 
        now_question = Question(question_text='驴Cual es el mejor estudiante de platzi?', pub_date= time)
        self.assertEqual(now_question.was_published_recentely(), True)

    def  test_was_published_recentely_with_past_question(self):
        """Was_published_recently returns False for question Whose pub_date is in Past"""
        time = timezone.now() - datetime.timedelta(days=1)
        past_question = Question(question_text= '驴Cual es la mejor escuela de platzi?', pub_date= time)
        self.assertAlmostEqual(past_question.was_published_recentely(), False)

Aqu铆 va mi reto ;D

Esto de los tests es buenisimo, pero me gustar铆a saber si es posible debbugear los tests en VS Code para ver el flujo de la inofrmaci贸n.

Saludos.

Muy generalista, se pueden dividir los tests para ser mas especificos. Como hacer assertEqual en la longitud, assert de la pregunta esperada, etc.

Supongo que lo veremos en breve 馃槂

    def test_future_question(self):
        """if the new question is in a future, dont let to see sach question"""
        time = timezone.now() + timezone.timedelta(days=30)
        future_question = Question.objects.create(question_text="future question",pub_date=time)
        response = self.client.get(reverse("polls:index"))

        self.assertNotContains(response,future_question)

Dejo las que hice

En Test

def test_get_queryset_with_future_questions(self):
    """If question.pub_date is in the future, it is not displayed"""
    time = timezone.now() + dt.timedelta(days = 30)
    future_question = Question(question_text = "Any Question", pub_date = time)
    future_question.save()
    response = self.client.get(reverse('polls:index'))
    self.assertNotIn(future_question, response.context['latest_question_list'])
    
def test_get_queryset_with_old_questions(self):
    """If question.pub_date is older than 1 day, it is not displayed"""
    time = timezone.now() - dt.timedelta(days = 1, seconds = 1)
    old_question = Question(question_text = "Any Question", pub_date = time)
    old_question.save()
    response = self.client.get(reverse('polls:index'))
    self.assertNotIn(old_question, response.context['latest_question_list'])

En views

def get_queryset(self):
    """Return the last five published questions."""
    # return Question.objects.order_by("-pub_date")[:5]
    # return Question.objects.filter(pub_date__lte = timezone.now()).order_by('-pub_date')[:5]
    questions = Question.objects.filter(pub_date__lte = timezone.now())
    questions = questions.filter(pub_date__gt = timezone.now() - dt.timedelta(days = 1))
    questions = questions.order_by('-pub_date')[:5]
    return questions

Comparto mis testCases

import datetime
from django.test import TestCase
from django.utils import timezone

from .models import Question

class QuestionModelTests(TestCase):

    SAMPLE_QUESTION = "驴Is this a question?"

    def test_was_published_recently_with_future_questions(self):
        """Was published recently should return False for questions whose
        pub_date is in the future."""
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(question_text=self.SAMPLE_QUESTION, pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)


    def test_was_not_published_recently(self):
        """Was published recently should return False for questions whose
        pub_date is older than 1 day."""
        time = timezone.now() - datetime.timedelta(days=1, seconds=1)
        old_question = Question(question_text=self.SAMPLE_QUESTION, pub_date=time)
        self.assertIs(old_question.was_published_recently(), False)
    
    def test_was_published_recently_with_recent_question(self):
        """Was published recently should return True for questions whose
        pub_date is within the last day."""
        time = timezone.now() - datetime.timedelta(hours=23, minutes=59, seconds=59)
        recent_question = Question(question_text=self.SAMPLE_QUESTION, pub_date=time)
        self.assertIs(recent_question.was_published_recently(), True)

Hola profe, tengo un error en la linea:
self.assertContains(response, 鈥淣o Polls are available鈥)
En la consola: AssertionError: False is not true : Couldn鈥檛 find 鈥楴o Polls are available鈥 in response
He revisado el codigo mil veces, es igualito al tuyo. Si comento la linea, el test funciona. Ayuda porfa!!

Yo hice 2 pruebas.
Una con un solo registro en el futuro.
La segunda con 2 registros uno en el futuro y otro en el presente

class QuestionIndexViewTest(TestCase):
    
    def test_no_questions(self):
        """ If no question exits, an appropiate message is displayed"""
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No Polls are avariable.")
        self.assertQuerysetEqual(response.context["latest_question_list"], [])
    
    def test_was_no_publish_questions_in_the_future(self):
        """If there is a publication that has a date in the future, it should not be published. and send the message: No Polls are avariable."""
        time = timezone.now() + datetime.timedelta(days=30)
        Question( question_text="驴Quien es el mejor Course Director de Platzi?", pub_date = time ).save()
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "No Polls are avariable.")
        self.assertQuerysetEqual(response.context["latest_question_list"], [])
    
    def test_was_no_publish_questions_in_the_future_and_publish_question_now(self):
        """If there is a publication that has the future date and today's publications, only those of today should be published. """
        time = timezone.now() + datetime.timedelta(days=30)
        Question( question_text="驴Quien es el mejor Course Director de Platzi?", pub_date = time ).save()
        Question( question_text="驴Cual es el mejor curso de Platzi?", pub_date = timezone.now() ).save()
        response = self.client.get(reverse("polls:index"))
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "驴Cual es el mejor curso de Platzi?")
        self.assertEqual(len(response.context["latest_question_list"]), 1)

Yo hice esta (para los 30 d铆as despu茅s), pero quer铆a hacer (la de un d铆a en concreto).

tests

    def test_was_published_last_time(self):
        """
        was_published_last_time returns True for questions whose pub_date is in the past time
        """
        time = timezone.now() - datetime.timedelta(days=30)
        last_question = Question(question_text="驴Qui茅n es el mejor Course Director de Platzi?", pub_date=time)
        # Verificar que el resultado de aplicar el m茅todo was_published_last_time() sobre last_question es igual a verdad
        self.assertIs(last_question.was_published_last_time(), True)

models

    def was_published_last_time(self):
        return self.pub_date <= timezone.now() -datetime.timedelta(days=30)