Data Driven Testing (DDT)
Clase 21 de 24 • Curso de Introducción a Selenium con Python
Contenido del curso
Royer Guerrero Pinilla
Cristian David Restrepo Marin
Miguel Andres Rendon Reyes
Alberto Perdomo
Jorge Heli Rueda Uribe
Juan Agustin Di Pasquo
polygonus polygonus
fidel angel ochoa
Usuario anónimo
Fredy Mendoza Vargas
softdynamic sac
David Daniel Acerbo
fidel angel ochoa
Fabricio González Guasque
Fernando Lambraño Leon
Juan Manuel Trujillo Tarelo
Miguel Angel Reyes Moreno
Antonio Manilla Maldonado
Sergio Andrés Martínez Ramírez
Miquel Muntaner Barceló
Andrés Mauricio Cárdenas Alvarado
Jeyson David Vargas Crespo
Alex Camacho
Santiago Herrera Velásquez
Wilson Gustavo Chango Sailema
Jesús Velázquez Jiménez
Luis Adolfo Ramírez Inciarte
Enrique Uzcategui
Carlos Alberto Gutierrez Ramirez
Jose Antonio Rojas Ollarves
Jose Antonio Rojas Ollarves
Antonio Demarco Bonino
Miguel Angel Reyes Moreno
fidel angel ochoa
No olviden instalar con pip install ddt amigos
R0Y3R muchas gracias por el aporte!
Gracias bro, enserio que me iluminaste.
Importante para esta clase tener instalada la libreria ddt, para los que usan anaconda es:
Para los que usan PIP es:
Haciendo hoy el ejercicio, encuentro que en la página para los ejercicios (demo-store.seleniumacademy) las cantidades han cambiado, ahora las cantidades del archivo testdata.csv deben ser las siguientes para que no falle la prueba:
CategoryOrProduct,NumberOfProducts earrings,1 music,5 denim,2 skirt,1 book,3
Muchas gracias Jorge 😄
Puede que muchos lo sepan pero otros no, para que esta linea funcione sin ser modificada (@data(*get_data('testdata.csv'))) el archivo .csv debe estar en la misma carpeta donde esta el archivo .py y el archivo .csv debe llamarse "testdata" . Lo aclaro porque cuando se descarga el archivo este tiene otro nombre.
GRACIAS. este tipo de aclaraciones para los novatos nos sirve mucho
import csv, unittest from ddt import ddt, data, unpack from selenium import webdriver def get_data(file_name): rows = [] data_file= open(file_name, 'r') reader= csv.reader(data_file) next(reader, None) for row in reader: rows.append(row) return rows @ddt class SearchDDT(unittest.TestCase): def setUp(self): self.driver= webdriver.Chrome(executable_path= "/home/yanina/Downloads/chromedriver") driver= self.driver driver.implicitly_wait(10) driver.maximize_window() driver.get('http://demo-store.seleniumacademy.com') @data(*get_data('testdata.csv')) @unpack def test_search_ddt(self, search_value, expected_count): driver= self.driver search_field= driver.find_element_by_name('q') search_field.clear() search_field.send_keys(search_value) search_field.submit() products = driver.find_elements_by_xpath('//h2[@class= "product-name"]/a') expected_count= int(expected_count) if expected_count>0: self.assertEqual(expected_count, len(products)) else: message= driver.find_elements_by_class_name('note-msg') self.assertEqual('Your search returns no results.', message) print(f'Found {len(products)} products') if __name__== '__main__': unittest.main(verbosity=2)```
Muchas gracias
Es find_element_by_class_name, no find_elements_by_class_name
Chicos estaba bueno manejar el acceso a los archivos con el keyword “with” ejemplo en la función get_dat()
Es una buena practica para que cuando abrimos el archivo para leerlo al terminar se cierre.
def get_data(file_name): rows = [] with open(file_name, 'r') as data_file: reader = csv.reader(data_file) next(reader, None) for row in reader: rows.append(row) return rows
Reading and Writing Files : https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files
visual estudio code no me detectaba 'ddt' a pesar que lo instale con pip, encontre que la manera de instalarlo 'correctamente', para mi, es asi:
python -m pip install ddt
por supuesto en el ambiente virtual que cree para el curso.
Ojala le ayude algun@.
Encontré la misma forma de hacerlo en google. Funciona 👍
pip install ddt
Hola, Tengo una pregunta en la linea 24 en donde esta el decorator @data usted usa un asterisco antes del function call. me podria explicar para que sirve? puedo asumir que es para hacer multiples llamadas de la funcion, pero no le entiendo bien. O me podria pasar la documentacion sobre como usarlo de esa forma?
He visto que le han dicho muchos halagos a lo largo del curso, profesor. Aquí está el mío. Hace un mes, tal vez un poco más, tomé el curso de Python de Google en Coursera, y ni ahí se aventaron algo tan complejo o tan didáctico como lo hizo usted en esta clase con el manejo de csv. Muy bien, la verdad me agradó bastante.
No se si es por la forma en la que Héctor explica o qué, pero realmente realizar DDT me ha parecido mucho más sencillo con Python.
Yo he tenido la oportunidad de hacer este tipo de ejercucio en una empresa para automatizar pruebas de una aplicación móvil usando Appium/Selenium y Java con TestNG y se me hacía un poco más engorroso por las librerías que había que importar y demás configuraciones.
Realmente pensaré seriamente cuando sea el momento de evaluar un framework de automatización basado en Python.
La cantidad de resultados de la web han cambiado, por tanto, el CSV ahora está mal, aquí les dejo el correcto: (la búsqueda de earrings provocaba un error extraño, por eso lo he quitado, no sé si solo me sucede a mí)
CategoryOrProduct,NumberOfProducts music,5 denim,2 skirt,1 book,3
Así es y para el primer ejercicio son en el decorador @data(('dress',5),('music',5))
Hola, no acabo de entender lo de los decoradores, en este caso que son o para que sirven???
Espero que este post te pueda aclarar tus dudas :)
los decoradores acceden a métodos propios de la metodología que resumidamente acá corren la prueba que esta abajo la cantidad de veces que sea necesario para usar todas las tuplas
import csv, unittest from ddt import ddt, data, unpack from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.common.by import By def get_data(file_name): rows = [] data_file= open(file_name, 'r') reader= csv.reader(data_file) next(reader, None) for row in reader: rows.append(row) return rows @ddt class SearchDDT(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver= self.driver driver.implicitly_wait(10) driver.maximize_window() driver.get('Link URL') @data(*get_data('testdata.csv')) @unpack def test_search_ddt(self, search_value, expected_count): driver= self.driver search_field= driver.find_element(By.NAME,'q') search_field.clear() search_field.send_keys(search_value) search_field.submit() products = driver.find_elements(By.XPATH,'//h2[@class= "product-name"]/a') expected_count= int(expected_count) if expected_count>0: self.assertEqual(expected_count, len(products)) else: message= driver.find_elements(By.CLASS_NAME,'note-msg') self.assertEqual('Your search returns no results.', message) print(f'Found {len(products)} products') if __name__== '__main__': unittest.main(verbosity=2)
Wow! Esta clase fue muy interesante.
import csv, unittest from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from ddt import ddt, data, unpack def get_data(file): rows = [] # list for input data_file = open(file,'r') # variable define file in read mode reader = csv.reader(data_file) # variable select library for read file next(reader, None) for i in reader: rows.append(i) return rows @ddt class DataDrivenTest(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome(service=Service('./chromedriver')) driver = self.driver driver.implicitly_wait(30) driver.maximize_window() driver.get("https://demo-store.seleniumacademy.com/") @data(*get_data("externaldata.csv")) # call our function get_data @unpack def test_search_ddt(self, search_value, expected_count): driver = self.driver search_field = driver.find_element(By.NAME, 'q') search_field.clear() search_field.send_keys(search_value) search_field.submit() products = driver.find_elements(By.XPATH, '//h2[@class="product-name"]/a') expected_count = int(expected_count) if expected_count > 0: self.assertEqual(expected_count, len(products)) else: msg = self.driver.find_element(By.CLASS_NAME,'note-msg') self.assertEqual('Your search returns no results.', msg) print(f'Find {len(products)} products') def tearDown(self): self.driver.implicitly_wait(3) self.driver.close() if __name__ == '__main__': unittest.main(verbosity = 2)
En un entorno de producción y con datos importantes, nunca dejen un archivo abierto. Usen mejor with open(file_name) as f: para evitar olvidar cerrarlo. Por qué? porque ésto se puede aprovechar para que cualquier usuario en el sistema consiga acceso a los datos del archivo hasta que se reinicie el OS
Con 'dress' ahora salen 5 resultados en lugar de 6
Hola,
alguien sabe por que me sale este error: cannot import name 'ddt' from partially initialized module 'ddt' (most likely due to a circular import)
ya instale el ddt, con el comando pip install ddt
Instala ddt:
pip install ddt```
Saludos amigos aqui les comparto la primera parte del codigo utilizando firefox.
import unittest from selenium import webdriver #Importar libreria ddt y extraer submodulos from ddt import ddt, data, unpack #Permitira utilizar los datos y desempaquetarlos #Colocar decorado @ddt class SearchDDT(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox(executable_path= r'./geckodriver.exe') driver = self.driver driver.implicitly_wait(5) driver.maximize_window() driver.get('https://demo-store.seleniumacademy.com/') @data(('dress', 6),('music', 5)) #Decorador que almacena los elementos a buscar @unpack #Decorador para desempaquetar las tuplas y poder ingresar a ellass de forma individual #Agregaremos dos parametros al metodo uno para buscar y otro para validar def test_search_ddt(self, search_value, expected_count): driver = self.driver #Ubicar campo de busqueda search_field = driver.find_element_by_name('q') search_field.clear()#Limpiar en caso de que tengan algun texto #Ingresamos el valor a buscar search_field.send_keys(search_value) #Boton de busqueda search_button = driver.find_element_by_class_name('button') search_button.click() #Identificar donde estan los productos products = driver.find_elements_by_xpath('//h2[@class="product-name"]/a') #Verficiar que todo haya salido bien con un print statement print(f"Found {len(products)} products") #Ciclo for para imprimir los elementos de la pagina actual for i in products: print(i.text) #Assertion de validacion self.assertEqual(expected_count, len(products)) def tearDown(self): self.driver.close() if __name__ == "__main__": unittest.main()```
Esta clase me costó mucho pero salio. Consejo: tengan la biblioteca ddt en la misma carpeta del archivo que de Python que están trabajando.
CategoryOrProduct,NumberOfProducts earrings,1 music,5 denim,2 skirt,1 book,3
justo me di cuenta que habia un cambio en la pagina de prueba, gracias.