No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Data Driven Testing (DDT)

21/24
Recursos

Aportes 32

Preguntas 9

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

No olviden instalar con pip install ddt amigos

Importante para esta clase tener instalada la libreria ddt, para los que usan anaconda es:

  • conda install -c conda-forge ddt

Para los que usan PIP es:

  • pip3 install ddt

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

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.

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)```

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@.

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
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

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

Y que pasa cuando te sale un captcha?

TDD: Creas Software y durante el desarrollo, vas aprobando los Tests que ya están definidos (creados).
DDT: Creas Tests para que el Software que ya esta escrito las apruebe.

no seria mejor usar un try ,except en caso de que la cantidad esperada sea cero pero la realidad sea otra o vice versa ??

no olvides descargar ddt

pip install ddt
import csv,unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from ddt import ddt, data, unpack

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 CompareProducts(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path='./chromedriver')
        driver = self.driver
        driver.implicitly_wait(30)
        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')
        print(f'se encontraron {len(products)} products')

        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')

        print(f'encontramos {len(products)} productos')


 
    def tearDown(self):
        self.driver.close()

if __name__ == '__main__':
    unittest.main(verbosity=2, testRunner= HTMLTestRunner(output= 'reports', report_name= 'hello-world-report'))

En mi caso, me salia un error en 3 de los Items

Era por que en la validacion
asserEqual()
el expected_count != de len(product)

Creo que de esa forma estariamos validado que la cantidad de productos ingresados es diferente a lo experado.
Igual lo corregi colocando la cantidad que aparace en la pagina por cada item.

Los decoradores, también se pueden agregar sobre las clases.

El uso de ddt con el unpack y el data es lo mismo que usar @pytest.mark.parametrize en pytest

Recomiendo cambiar el return de la función por :

return  list(reader)

para así reducir la complejidad algorítmica (en caso de que el csv sea bastante extenso)

DDT: Metodología utilizada para hacer Tensting y se puede implementar en Selenium, esto hace que los Test sean más robustos y versátiles.

se me congelo cuando iba en denim

CategoryOrProduct,NumberOfProducts
earrings,3
music,5
denim,2
skirt,2
book,3

corregí lo de denim igual a 2, antes era denim=3

para los que tienen este error

FileNotFoundError: [Errno 2] No such file or directory: 'testdata.csv'

solo cambien esta parte

    @data(*get_data('testdata.csv'))

por la direccion completa del documento

@data(*get_data('D:\Documents\Cursos\Curso de selenium\ddt\testdata.csv'))

yo si dije pro que no funciona, gracias a mi compañeros que toca instalar ddt uwu