Korpi delfin
EstudianteAndrés Corral
EstudianteGabriel Martin Estrada
EstudianteFacundo Soto
EstudianteMario Alberto Treviño
EstudianteFredy Alexander Izquierdo Dominguez
EstudianteAndrés Xavier Vargas Vera
EstudianteTomas Jesus Escobar Cueltan
EstudianteJesús Enrique Morocoima Marcano
EstudiantePablo Rivera Sepúlveda
EstudianteManuel Rodrigo Zamorano Jimenez
EstudianteJulian Crispin
EstudianteCarlos Andres Ocampo Pabon
EstudianteCesar Sosa
EstudianteDavid Rodriguez
EstudianteDavid Diaz
EstudianteJose Leonardo Araya Parajeles
EstudianteEduardo Pérez
EstudianteJulio César Zaravia Paredes
EstudianteSergio Bryan Madrid Nuñez
EstudianteSebastián Franco
EstudianteRicardo Moreno
EstudianteJulian Ramirez Chacon
EstudianteRicardo Moreno
EstudianteJuan Francisco Pons
EstudianteManuel Rodrigo Zamorano Jimenez
EstudianteAgustin Zamar
EstudianteGabriel Ichcanziho Pérez Landa
EstudianteVíctor Mazo
EstudianteBoris Saavedra
EstudianteAlejandro Benjamín Like García
EstudianteFelipe Alexis Moreno Durán
EstudianteJohn Steven González
EstudianteLeslie Paz Ore
EstudianteMiguel Andres Rendon Reyes
EstudianteLeslie Paz Ore
EstudianteJessica Martinez Freire
EstudianteJulian Ramirez Chacon
EstudianteAngela Nipitella
EstudianteMiguel Rodriguez Perez
EstudianteLuis Jhonayquer Zapata Yamo
EstudianteKarla Berenice
EstudianteAgustin Zamar
EstudianteAndrés Xavier Vargas Vera
Estudiantejesus alberto negrin guerrero
EstudianteHéctor Daniel Vega Quiñones
ProfesorLes comparto el código ya con documentación.
Assertions
import unittest from selenium import webdriver #sirve como excepción para los assertions cuando queremos #validar la presencia de un elemento from selenium.common.exceptions import NoSuchElementException #ayuda a llamar a las excepciones que queremos validar from selenium.webdriver.common.by import By class AssertionsTest(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome(executable_path = r'.\chromedriver.exe') driver = self.driver driver.implicitly_wait(30) driver.maximize_window() driver.get("http://demo.onestepcheckout.com/") def test_search_field(self): self.assertTrue(self.is_element_present(By.NAME, 'q')) def test_language_option(self): self.assertTrue(self.is_element_present(By.ID, 'select-language')) def tearDown(self): self.driver.quit() #para saber si está presente el elemento #how: tipo de selector #what: el valor que tiene def is_element_present(self, how, what): try: #busca los elementos según el parámetro self.driver.find_element(by = how, value = what) except NoSuchElementException as variable: return False return True
Search tests
import unittest from pyunitreport import HTMLTestRunner from selenium import webdriver class SearchTests(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome(executable_path = r'.\chromedriver.exe') driver = self.driver driver.implicitly_wait(30) driver.maximize_window() driver.get("http://demo.onestepcheckout.com") def test_search_tee(self): driver = self.driver search_field = driver.find_element_by_name('q') search_field.clear() #limpia el campo de búsqueda en caso de que haya algún texto. search_field.send_keys('tee') #simulamos la escritura del teclado para poner "tee" search_field.submit() #envía los datos ('tee') para que la página muestre los resultados de "tee" def test_search_salt_shaker(self): driver = self.driver search_field = driver.find_element_by_name('q') search_field.send_keys('salt shaker') #escribimos 'salt shaker' en la barra de búsqueda search_field.submit() #envíamos la petición #hago una lista de los resultados buscando los elementos por su Xpath. Es la forma más rápida. products = driver.find_elements_by_xpath('//*[@id="top"]/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul/li/div/h2/a') #vamos a preguntar si la cantidad de resultados es igual a 1 self.assertEqual(1, len(products)) def tearDown(self): self.driver.quit()
Smoke tests
from unittest import TestLoader, TestSuite from pyunitreport import HTMLTestRunner #para generar el reporte from assertions import AssertionsTest from search_tests_assertions import SearchTests assertions_test = TestLoader().loadTestsFromTestCase(AssertionsTest) search_tests = TestLoader().loadTestsFromTestCase(SearchTests) #contruimos la suite de pruebas smoke_test = TestSuite([assertions_test, search_tests]) #para generar los reporters kwargs = { "output": 'smoke-report' } #la variable runner almacena un reporte generado por HTMLTestRuner #usa como argumento "kwarsp" runner = HTMLTestRunner(**kwargs) #corro el rurner con la suite de prueba runner.run(smoke_test)
gracias
Muchas gracias!!!!
No me gusta ser el negativo pero este curso me parece desastroso, está lleno de cosas no explicadas o implícitas o también cosas esenciales explicadas de manera vaga
Justo entre a los comentarios para ver si era impresión mía o si esta muy mal explicado.
Pienso igual.
Al parecer el código que muestra el profesor no guarda los reportes de los test cases, cuando se evalúan en un Suite, porque solo guarda el reporte del último Test Case....
Yo logré solucionarlo, al parecer hay que instalar otra librería, la librería que nos hace instalar el profesor al parecer es un fork de esta otra librería que tiene muchas mas funcionalidades y está actualizada constantemente.
pip install html-testRunner
https://github.com/oldani/HtmlTestRunner
Esta otra librería se importa: ANTES:
from pyunitreport import HTMLTestRunner
AHORA:
from HtmlTestRunner import HTMLTestRunner
y cuando se prueba Test Cases es igual que antes, no mas que ahora guarda los archivos con un mobre raro, si alguien logra descubrir como evitar esto, estaría agradecido:
Un pequeño cambio, en output, para guardar en carpetas destro de reports, se agrega esto:
El add_timestamps es para agregar la fecha y hora al nombre del archivo, no me gustó, por eso le pongo FALSE, pero si desean le pueden dejar TRUE
En cuanto para Suites, resuelve el problema que están teniendo: Lo unico que cambia son los kwargs y los imports dados anteriormente
kwargs = { "output": "reports/smoke-report", "report_name": "smoke-report", "combine_reports": True, "add_timestamp": False } # ? create runner with the parameters and run runner = HTMLTestRunner(**kwargs) runner.run(smoke_test)
En este caso el nombre del archivo si se guarda con el nombre que se le da
Y ahora se crea un solo reporte para todos los test cases en el suite
Muchas gracias amigo por tomarte el tiempo de explicar esta parte, muy importante saberlo.
Super
El tema de automatizacion es increible... lastima la explicacion de este curso, que desastre!!!
Así es ..!
Este curso es de los peores, enredado, dificil de seguir, una pesadilla
Para los que no entendimos el porqué se el doble asterisco cuando se está pasando el **kwargs al HTMLTestRunner, aquí dejo un articulo donde explican:
Explicación **kwargs
Heroe, gracias! ya entendí mejor el código de esta clase.
Excelente Clase Héctor, Esto es súper útil para no hacer múltiples ejecuciones. Interesante que al no agregar el campo report_name se guarda con el dia y hora de la ejecución.
Buenas noches, compañeros! Si en algún momento alguien llegase a tener problema con:
Les traigo la solución a ambos.
Assertions
import unittest from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager class AssertionsTest(unittest.TestCase): @classmethod def setUp(self): self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver = self.driver driver.implicitly_wait(30) driver.maximize_window() driver.get("Platzi decía que el sitio no era seguro.com") def test_search_field(self): print('Searching the search bar') self.assertTrue(self.is_element_present(By.NAME, 'q')) def test_language_option(self): print('Searching the Select language dropdown') self.assertTrue(self.is_element_present(By.ID, 'iselect-language')) @classmethod def tearDown(self): self.driver.quit() def is_element_present(self, how, what): try: self.driver.find_element(by=how, value=what) except NoSuchElementException(): self.driver.close() return False return True
(Ojo, lo deje como "iselect-language" para que vean que ejecuta el código completa aún cuando algún elemento no exista)
Search Test
import unittest from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from webdriver_manager.chrome import ChromeDriverManager class SearchTests(unittest.TestCase): @classmethod def setUp(self): self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver = self.driver driver.implicitly_wait(30) driver.maximize_window() driver.get("Platzi no dejo poner el URL :c") def test_search_tee(self): driver = self.driver search_field = driver.find_element(By.NAME, "q") search_field.clear() search_field.clear() search_field.send_keys('tee') search_field.submit() def test_search_salt_shaker(self): driver = self.driver search_field = driver.find_element(By.NAME, "q") search_field.clear() search_field.send_keys('salt shaker') search_field.submit() #Searching by XPATH -> $x('//div[@class = "product-info"]/h2[@class="product-name"]/a/text()').map(x => x.wholeText) or $x('//div[@class = "product-info"]/h2/a/text()').map(x => x.wholeText) # REMEMBER: "h2" could also be replaced by "text-fill" products = driver.find_elements(By.XPATH, '//div[@class = "product-info"]/h2[@class="product-name"]/a') self.assertEqual(1, len(products)) @classmethod def tearDown(self): self.driver.quit()
Finalmente... Smoke Tests
from unittest import TestLoader, TestSuite from assertions import AssertionsTest from searchtests import SearchTests from HtmlTestRunner import HTMLTestRunner assertions_test = TestLoader().loadTestsFromTestCase(AssertionsTest) search_tests = TestLoader().loadTestsFromTestCase(SearchTests) #contruimos la suite de pruebas smoke_test = TestSuite([assertions_test, search_tests]) # Aquí generamos nuestros reportes kwargs = { "output": "reports/smoke-report", "report_name": "smoke-report", "combine_reports": True, "add_timestamp": True } runner = HTMLTestRunner(**kwargs) runner.run(smoke_test)
Como pueden notar, la sección importante es la sección de "kwargs", aquí usamos "combine_reports": True para que los 4 reportes puedan estar juntos. Espero esto les ayude y así evitan horas de busquedas para solucionar esos problemas.
Gracias por sus atenciones y HAPPY CODING!
como lograste hacer funcionar el: from HtmlTestRunner import HTMLTestRunner he buscado pero no logro instalarlo
Hola Jose, que error te esta saliendo?
¡Hola Comunidad! . En un video anterior dejé una respuesta con una explicación sobre este error 👇👇👇 .
Puedes utilizar el WebDriver de Firefox. https://pythonbasics.org/selenium-firefox/, aquí pueden encontrar un blog que explica como hacerlo. En lugar de instalar el webdriver de chrome, hay que utilizar algo similar llamado geckodriver que pueden descargar aquí: https://github.com/mozilla/geckodriver/releases, sólo dejan el archivo descomprimido en el mismo nivel en el que tengan su código o señalan la ruta del geckodriver como hacemos en el curso. Ahora seria: webdriver.Firefox()
A mi tambien me daba el error de USB, pero era porque en la función test_lenguage_option() el assert de lenguaje tenía escrito "select-lenguage" en vez de "select-language", fue corregirlo y todo fluyó. Puede que a alguien más le sirva.
*Actualización Para el día de hoy ya no aparece el item de Language por lo tanto es test falla en esa parte
Saludos!
A día de hoy select-language si sirve, la prueba pasa sin ningún problema
Gracias por la info, al momento que realicé el curso no pasaba el test y era porque no estaba la opcion del lenguaje... supongo que no lo vi o algo cambio jaja.
Saludos!
Es un quilombo esta clase! Pésimo todo. Salta de la nada a otro archivo con el mismo nombre pero distinto contenido.
Asi es ..
Hola! Cuando se genera el reporte de la suite de tests smoketests solo muestra reportes de los tests del ultimo archivo ejecutado. ¿Hay alguna forma de que el reporte incluya a todos los tests? ¿O que se cree un archivo para cada uno?
tengo exactamente el mismo problema :( y al parecer no soy el único
La única forma que encontré fue ingresar cada test de forma separada en el TestSuite(), sin notación de lista, más creo que se pierde la ventaja de utilizar el test suite.
El profe no lo mencionó, pero si corren el Test Suite y colocan el parámetro report_name los reportes (obviamente) se sobrescriben y solo verán un reporte. Es por eso que conviene no colocar este parámetro.
De nada 🤣
aunque no coloques el report_name se siguen sobrescribiendo. figuran con la misma hora y segundo
Estimados el codigo a continuación:
assertions.py
import unittest from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By class AssertionsTest(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome(executable_path = r'C:\Python Scripts\curso_selenium\chromedriver.exe') driver = self.driver driver.implicitly_wait(30) driver.maximize_window() driver.get("http://demo-store.seleniumacademy.com/") def test_search_field(self): self.assertTrue(self.is_element_present(By.NAME, 'q')) def test_language_option(self): self.assertTrue(self.is_element_present(By.ID, 'select-language')) def tearDown(self): self.driver.quit() def is_element_present(self, how, what): try: self.driver.find_element(by = how, value = what) except NoSuchElementException as variable: return False return True``` searchtests.py
import unittest from pyunitreport import HTMLTestRunner from selenium import webdriver
class SearchTests(unittest.TestCase):
def setUp(self): self.driver = webdriver.Chrome(executable_path = r'C:\Python Scripts\curso_selenium\chromedriver.exe') driver = self.driver driver.implicitly_wait(30) driver.maximize_window() driver.get("http://demo-store.seleniumacademy.com/") def test_search_tee(self): driver = self.driver search_field = driver.find_element_by_name('q') search_field.clear() search_field.send_keys('tee') search_field.submit() def test_search_salt_shaker(self): driver = self.driver search_field = driver.find_element_by_name('q') search_field.send_keys('salt shaker') search_field.submit() products = driver.find_elements_by_xpath('//*[@id="top"]/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul/li/div/h2/a') self.assertEqual(1, len(products)) def tearDown(self): self.driver.quit()```
smoketests.py
from unittest import TestLoader, TestSuite from pyunitreport import HTMLTestRunner from assertions import AssertionsTest from searchtests import SearchTests assertions_test = TestLoader().loadTestsFromTestCase(AssertionsTest) search_tests = TestLoader().loadTestsFromTestCase(SearchTests) #Construccion de suite de pruebas smoke_test = TestSuite([assertions_test, search_tests]) #Respecto a los reportes kwargs = { "output": 'smoke-report' } runner = HTMLTestRunner(**kwargs) runner.run(smoke_test)``` Exito y saludos
Cuando se utiliza el decorador @classmethod la prueba dura muchísimo menos, hablando en tiempo.
Una consulta compañeros, aún no comprendo bien cuál es la funcionalidad de
verbosity=2
Podrían ayudarme, please?
Hola Leslor, te explico brevemente, que la función del parámetro verbosity es para definir, qué tantas explicaciones queremos por parte de unittest. Es decir, qué tanto texto quieres que aparezca en medio de la prueba. Puedes probar poner 1 y verás cómo casi no te va a decir nada en la terminal. Es como si con verbosity, le pides que sea verbal, que explique más detalladamente.
Muchas Gracias Umi! , Realize el cambio de verbosity a 1, pero me salen las mismas lineas que cuando le pongo 3 o 4, Supongo que mientras más complejo sea el Test Case, lograré ver la diferencia. Thanks! :)
No se por que, pero el xpath aparentemente cambió y colocando (1, len (products)) no da, sale AssertionError: 1 != 0.
Mi xpath sale: '//*[@id="top"]/body/div/div[2]/div[2]/div/div[2]/div[1]/div[4]/ul/li/div/h2/a'
Y el xpath del video sale: '//*[@id="top"]/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul/li/div/h2/a'
¿Como me doy cuenta en este caso? porque la logica esta bien, pero copio el xpath de la pagina y no me da (hoy por hoy), pero si uso el xpath del video si me da.
< def test_search_salt_shaker(self): driver = self.driver search_field = driver.find_element_by_name('q') search_field.send_keys('salt shaker') search_field.submit() products = driver.find_elements_by_xpath('//*[@id="top"]/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul/li/div/h2/a') self.assertEqual(1, len(products))>
Tienes mal la ruta XPATH , la ruta es:
products = driver.find_elements_by_xpath('/html/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul/li/div/h2/a')
Me pasaba lo mismo. Resulta que cuando le daba a inspeccionar la pagina cambiaba de tamaño poder desplegar el menú de desarrolladores de chrome. Al copiar el xpath lo estaba haciendo en una vista adaptada para móviles. esto lleva a tu portapapeles un xpath diferente al de una vista para monitor de pc. Lo pude solucionar en el menú de opciones de la consola de desarrolladores de chrome para que al darle al botón de inspeccionar se abra esta consola en una ventana nueva, dejando intacto el tamaño original de la web.
Este curso es maravilloso para el que tiene cierto nivel en python, si eres nuevo tomando el curso y no tienes experiencia resolviendo los problemas mas comunes al programar y buscar documentación probablemente se te complique un poco mas de lo habitual y creas que se tiene que estar explicando todo lo que escribe el profesor.
Al parecer Selenium a la hora de ejecutar los test lo hace en función al orden alfabético según del nombre las funciones de los test.
Hola, saben como se le puede hacer para que se genere un solo archivo de resultados con todos los casos de prueba de todas las clases, es que conmigo me genera uno, pero solo de la última clase ejecutada
Hola! ¿Pudiste encontrar alguna solucion a esto?
Yo logré solucionarlo al parecer hay que instalar otra librería, la librería que nos hace instalar el profesor al parecer es un fork de esta otra librería que tiene muchas mas funcionalidades y está actualizada constantemente.
pip install html-testRunner
https://github.com/oldani/HtmlTestRunner
Esta otra librería se importa: ANTES:
from pyunitreport import HTMLTestRunner
AHORA:
from HtmlTestRunner import HTMLTestRunner
y cuando se prueba Test Cases es igual que antes, no mas que ahora guarda los archivos con un mobre raro, si alguien logra descubrir como evitar esto, estaría agradecido:
Un pequeño cambio, en output, para guardar en carpetas destro de reports, se agrega esto:
El add_timestamps es para agregar la fecha y hora al nombre del archivo, no me gustó, por eso le pongo FALSE, pero si desean le pueden dejar TRUE
En cuanto para Suites, resuelve el problema que están teniendo: Lo unico que cambia son los kwargs y los imports dados anteriormente
kwargs = { "output": "reports/smoke-report", "report_name": "smoke-report", "combine_reports": True, "add_timestamp": False } # ? create runner with the parameters and run runner = HTMLTestRunner(**kwargs) runner.run(smoke_test)
En este caso el nombre del archivo si se guarda con el nombre que se le da
Y ahora se crea un solo reporte para todos los test cases en el suite
Excelente tema y profesor, de hecho justo un error que comento cuando buscamos el xpath que es poner (elements) plural valga la redundancia casi se me explotaba la cabeza porque lo buscaba en singular y me arrojaba un error lo lei como 3 veces hasta que me di cuenta por el siemple hecho de no prestar atencion XD
Muchas gracias por el comentario, Jesús. En efecto hay que estar muy atentos cuando queremos identificar uno o varios elementos :eyes: