Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Preparar assertions y test suites

8/24
Recursos

Aportes 61

Preguntas 16

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

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

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.

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

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

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

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

¡Hola Comunidad!
.
En un video anterior dejé una respuesta con una explicación sobre este error 👇👇👇
.

.
Ya que quizá este error le esté apareciendo a algunos de ustedes (como a mí) aprovecho en dejarlo por aquí como un aporte:
.
Según pude revisar (porque a mi también me pasó 😔) este error se debe a que el Driver intenta generar una nueva sesión del navegador Chrome y para esto hace una serie de validaciones, una de las validaciones tiene que ver con la interfaz webUSB (que permite el acceso a dispositivos USB desde una página web), es en este punto en que se genera el error.
.
¿Por qué se genera el error? ¿Por qué se genera el error? Parece que no tiene nada que ver con tus entradas USB 😅 sino que parece ser que es un error de Chromium, según he podido leer ya fue notificado para su revisión.
.
Y, ¿Qué hacemos? No lo sé 🤠 … Pero he leído que el error no impide la generación de un nuevo contexto de navegación, es decir tu navegador debería abrirse y cargar la web y ejecutar los tests que hayas programado sin ser afectados.
.
En mi caso he notado que la ejecución a pesar de mostrar el error termina en status OK, he podido visualizar que el navegador se abre como de costumbre y me ha generado los reportes de manera satisfactoria, sin embargo estoy haciendo más pruebas mientras avanzo el curso.
.

.
Pero no podría decirles más. Esperemos que puedan solucionar esto y sigamos haciendo pruebas para ver si en realidad afecta nuestro trabajo o no.
.
Trataré de actualizar este comentario si encuentro algo más, por lo pronto les dejo esta discusión en SO que me sirvió de mucho y de la que extraje algunos de los datos que acabo de comentar.
.
Si alguien lee esto y está más enterado que yo del asunto o ha visto que me he equivocado en algo, o en todo 😐, por favor lo comenta y así aprendemos todos.
.
¡Saludos!

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 🤣

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


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

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

Cuando se utiliza el decorador @classmethod la prueba dura muchísimo menos, hablando en tiempo.

Para hacer un Test suit, solo tenemos que crear un archivo en dónde importaremos todos nuestros módulos, incluyendo claro está el módulo de Test suit de unittest.

Buenas he seguido el codigo,para probar que todo este bien ejecute individualmente assertions y seachtests y funcionan, el problema es con smoketests, me da error he verficado muchas veces mi sintaxis,me pueden ayudar porfa.

from unittest import TestLoader,TestSuite
from pyunitreport import HTMLTestRunner
from assertions import AssertionsTest
from searchtests import SearchTests

assertions_test = TestLoader().loadTestsFromTestCase(AssertionsTest)
search_test= TestLoader().loadTestsFromTestCase(SearchTests)

smoke_test = TestSuite([assertions_test,search_test])

kwargs = {
    "output":'smoke-repot'
}

runner = HTMLTestRunner(**kwargs)
runner.run(smoke_test)

Me da este error

Traceback (most recent call last):
  File "smoketests.py", line 4, in <module>
    from searchtests import SearchTests
ModuleNotFoundError: No module named 'searchtests'

hola soy nuevo en esta cosa y pues la neta me encanta xd jajajaj

A alguien más no le sirve la url?

Me tomó varios intentos pero por fin lo pude hacer funcionar 😄

Comparto mis archivos assertions y searchtests

Por si les pasa este error 😃:

  • Python selenium - AttributeError: ‘dict’ object has no attribute 'get_attribute’
    ó
  • Python selenium - AttributeError: ‘dict’ object has no attribute ‘send_keys’

Respuesta: Encontré una respuesta a este problema en stackoverflow.com, donde relata el problema de cuando se hace una petición y este devuelve un diccionario.

• Me encontré con este problema exacto. Parece ser algún tipo de error en Selenium 4.0. He vuelto a 3.141.0 (pip install selenium==3.141.0) y parece haber resuelto este problema.

Selenium es un conjunto de utilidades que facilita la labor de obtener juegos de pruebas para aplicaciones web. Para ello nos permite grabar, editar y depurar casos de prueba, que podrán ser ejecutados de forma automática e iterativa posteriormente.

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.

Todo lo que debes saber sobre el archivo smoketests

# Este archivo contiene el Test Suite #
# submodulos necesarios para crear el Test Suite
from unittest import TestLoader, TestSuite

# modulo para generar el reporte 
from pyunitreport import HTMLTestRunner

# from file import class-test-name
from assertions import AssertionsTest
from searchtests import SearchTests

# variables cargar los TestCase
assertions_test = TestLoader().loadTestsFromTestCase(AssertionsTest)
search_test = TestLoader().loadTestsFromTestCase(SearchTests)

# Construir TestSuite, recibe una lista de tests cases
smoke_test = TestSuite([assertions_test, search_test])

# Diccionario para indicar parametros para generar los reportes.
# output =  'folder for reports'
kwargs = {
        'output': 'smoke_test',
        'report_name': 'new_suite' 
}
# runner es un variable genera el reporte con los parametros del diccionario 'kwargs'.
runner = HTMLTestRunner(**kwargs)
# ejecutar runner con la Suite test 'smoke_test' 
runner.run(smoke_test)

En Python, podemos pasar un número variable de argumentos a una función utilizando símbolos especiales. Hay dos símbolos especiales:

*args (Argumentos sin keyword)
**kwargs (Argumentos de keyword)

Usamos *args y **kwargs cuando no estamos seguros del número de argumentos a pasar en las funciones.

notitas

Assertions

Métodos que permiten validar un valor esperado en la ejecución del test, si el resultado es verdadero el test continua en caso contrario falla y termina

test suites

colección de test unificados en una sola prueba, permitiendo tener resultados grupales e individuales(multiples pruebas secuenciales)

código lo tome de @korppiii por que me parecio increible como lo comento

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("https://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("https://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)```

notas finales

no olvides cambiar el path dependiendo de en que sistema operativo estes programando

Qué clase más chévere.

Ok, dato curioso, he intentado hacer estas pruebas con el buscador de Platzi y hay un captcha que impide las búsquedas jejeje

Siempre se agradece archivos extras para la clase, muy bien ahi.

Podemos crear variables con las que cargaremos los casos de prueba. Es decir, creamos una instancia de TestLoader que como lo dice su nombre trae los test a nuestro archivo actual, luego de ello utilizamos un método para llamar desde nuestro TestCase un caso de testeo, ya que en los módulos anteriores, utilizamos el Testcase para nuestras clases.

Tenemos que tener cuidado con la diferencia entre element y elements, el último genera una lista.

Es mejor poner el xpath entre comillas simples.

Si queremos generar una interacción con la barra de búsqueda entonces podemos utilizar el método submit.

Si le ponemos send_keys a una un input, se escribirán esta serie de patrones.

tee es camisa en inglés.

Ponemos el método clear() al objeto search_field, para que limpie el campo en caso de que haya algún texto.

Los assertions de esta clase nos permiten comprobar no solo la existencia del elemento si no que también los valores de este.

Lo que intentamos hacer al momento de importar el módulo By, es tomar un parámetro de webdriver que podemos declarar como una constante, esta define el selector o la forma de referencia a nuestro elemento

Lo que hacemos con la función is_element_present, es utilizarla como como una función de utilidad, en dónde how nos indica el tipo de selector y what el valor de este último.

Los Test Suits, es una colección de pruebas unificadas en un solo archivo. Es decir, varias pruebas que se enfocan en partes diferentes de la página, podemos tomar todas estas pruebas y hacerlas secuencialmente sin ir archivo por archivo ejecutando el script. De forma tal que podemos hacer Test largos.

Podemos tener pruebas más asertivas. Mediante los assertions, podemos validar con afirmaciones, lo que sabemos que serán los resultados de una o varias operaciones. Esto nos permite checar si el test está funcionando correctamente.

Espectacular cuando rellena “salt shaker” y “tee” en el campo Search automáticamente.

A mi me funciono asi para unificar reportes.

import unittest
from unittest import TestLoader, TestSuite
from HtmlTestRunner import HTMLTestRunner
from containers.Users.UserViewTest import UsersTest
from containers.ChangeType.ChangeTypeViewTest import ChangeTypeTest

user_test = TestLoader().loadTestsFromTestCase(UsersTest)
change_test = TestLoader().loadTestsFromTestCase(ChangeTypeTest)

frontend_test = TestSuite([change_test, user_test])

runner = HTMLTestRunner(combine_reports=True, output='report/frontend-report')
runner.run(frontend_test)

El modulo pytunitreport no me dejaba

Assertions: Se trata en verificar que una parte del test este funcionando correctamente como lo queremos, para que asi el test pueda fallar o continuar su flujo de proceso.
|
Ejemplo: assertEqual(price.text, “300”) - Con esto estamos vericando si el texto de un documento es igual a un string de 300 y no como una cantidad, esto es muy importante ya que vamos a trabajar con ello.
|
Suites: Se trata de una interfaz de test, en un solo lugar permitiendo tener resultados grupales e individuales
|
IMPORTANTE Las pruebas no se corren en paralelo, pero si de forma secuencial y de igual forma tendremos una respuesta del test suite.

# Funcion para identificar cuando un elemento esta presento (self, tipo de selector, valor que tiene)
	def	is_element_present(self, how, what):
		try:   
			self.driver.find_element(by = how, value = what) 
		except NoSuchElementException as variable:
			return False
		return True

Alguien se le ocurre porque solo me genera el reporte de dos casos y no de los cuatro? Corre los cuatro bien, pero solo me da el reporte de dos…

Hola Amigos en mi test me muestra los 4 test con error
Running tests…

test_language_option (assertions.AssertionsTest) … ERROR (0.003989)s
test_search_field (assertions.AssertionsTest) … ERROR (0.000996)s
test_search_salt_shaker (searchtests.SearchTests) … ERROR (0.000000)s
test_search_tee (searchtests.SearchTests) … ERROR (0.001009)s

ERROR [0.003989s]: b’test_language_option (assertions.AssertionsTest)'
ERROR [0.000996s]: b’test_search_field (assertions.AssertionsTest)'
ERROR [0.000000s]: b’test_search_salt_shaker (searchtests.SearchTests)‘
ERROR [0.001009s]: b’test_search_tee (searchtests.SearchTests)’

Tengo un error en el except, unused variable. No entiendo que tengo mal. Me ayudan?

Hola me ayudan porfavor,

estaba tratando de investigar pero no encuentro por que me sale este error:

Traceback (most recent call last):
File …/smoke_test.py", line 6, in <module>
assertions = TestLoader().loadTestFromTestCase(AssertionTest)
AttributeError: ‘TestLoader’ object has no attribute ‘loadTestFromTestCase’

@Héctor Daniel Vega Quiñones

Hola,

parece que tengo problemas al importar assertions y searchtests

Alguien me puede indicar que debo hacer por favor ?

Todo perfecto en Assertions, sin embargo me hizo ruido la parte de que son métodos que permiten validar… Mi cerebro me dice que son funciones ya que arrojan resultado, las funciones de assertion hacen un return True o False.

nuevo error
Traceback (most recent call last):
File “smoketes.py”, line 3, in <module>
from assertions import AssertionsTest
from selenium.common.exeptions import NoSuchElementException
ModuleNotFoundError: No module named ‘selenium.common.exeptions’

import unittest
from selenium import webdriver
from selenium.common.exeptions import NoSuchElementException
from selenium.webdriver.common.by import By

Hola Chicos, necesito ayuda, no sé porqué me sale este error en el self, agradezco la ayuda 😄 !

Instance of ‘Assertions’ has no ‘assertTrue’ memberpylint(no-member)

hola me pueden ayudar por fa
estoy trabajando en windows-ubunto con un ambiente virtual

Running tests…


Ran 0 tests in 0.000s

OK

Hola para los que tienen problemas con el test_search_salt_shaker es por el elemento que seleccionamos, que marca un AssertionError: 1 != 0. Imaginango que queremos a los elementos de busqueda use la etiqueta <ul> como rederencia y saque su XPATH: //*[@id=“top”]/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul

Les dejo la página de referencia: http://demo.onestepcheckout.com/

Aquí mi código:
PD: Tendrá un Failure en test_language_option porque en el sitio ya no esta.

assertions.py

import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By

class AssertionTests(unittest.TestCase):
    #Prepara entorno de la prueba. 
    def setUp(self):
        self.driver = webdriver.Chrome('../chromedriver.exe')
        driver = self.driver
        driver.implicitly_wait(30)#Para esperar
        driver.maximize_window()
        driver.get("http://demo.onestepcheckout.com/")

    #Casos de prueba
    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'))



    #Finalizar
    def tearDow(self):
        self.driver.quit()

    #Función de utilidad para saber si un elemento esta presente de acuerdo a sus parametros. 
    #how: tipo de selector, what: valor que tiene
    def is_element_present(self,how,what):
        try:
            self.driver.find_element(by = how, value= what)
        except NoSuchElementException as err:
            return False
        return True

if __name__ == "__main__":
    unittest.main(verbosity=2)

searchtests.py

import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By

class SearchTest(unittest.TestCase):
    #Prepara entorno de la prueba. 
    def setUp(self):
        self.driver = webdriver.Chrome('../chromedriver')
        driver = self.driver
        driver.implicitly_wait(30)#Para esperar
        driver.maximize_window()
        driver.get("http://demo.onestepcheckout.com/")

    #Casos de prueba
    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')
        print(products)
        print(len(products))
        self.assertEqual(1,len(products))

    #Finalizar
    def tearDow(self):
        self.driver.quit()


if __name__ == "__main__":
    unittest.main(verbosity=2)

smoketests.py

from unittest import TestLoader, TestSuite
from pyunitreport import HTMLTestRunner
from assertions import AssertionTests
from searchtests import SearchTest

assertions_test = TestLoader().loadTestsFromTestCase(AssertionTests)
search_test = TestLoader().loadTestsFromTestCase(SearchTest)

#Suite de pruebas

smoke_test = TestSuite([assertions_test, search_test])

kwargs = {
    "output": 'smoke-report'
}

runner = HTMLTestRunner(**kwargs)
runner.run(smoke_test)

Funcional, me toco desde Windows y no sobre WSL por que fallaban dos pruebas.

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'./chromedriver.exe')
        driver = self.driver
        driver.get("http://demo-store.seleniumacademy.com/")
        driver.maximize_window()
        driver.implicitly_wait(15)

    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

searchtests2.py

import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.by import By

class SearchTest(unittest.TestCase):
    #Prepara entorno de la prueba. 
    def setUp(self):
        self.driver = webdriver.Chrome(executable_path = r'./chromedriver.exe')
        driver = self.driver
        driver.get("http://demo-store.seleniumacademy.com/")
        driver.maximize_window()
        driver.implicitly_wait(15)

    #Casos de prueba
    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('/html/body/div/div[2]/div[2]/div/div[2]/div[2]/div[3]/ul/li/div/h2/al')
        print(products)
        print(len(products))
        self.assertEqual(1,len(products))

    #Finalizar
    def tearDow(self):
        self.driver.quit()


if __name__ == "__main__":
    unittest.main(verbosity=2)

smoketest.py

from unittest import TestLoader, TestSuite
from pyunitreport import HTMLTestRunner
from assertions import AssertionsTest
from searchtests import SearchTest

assertions_test = TestLoader().loadTestsFromTestCase(AssertionsTest)
search_test = TestLoader().loadTestsFromTestCase(SearchTest)

#Suite de pruebas

smoke_test = TestSuite([assertions_test, search_test])

kwargs = {
    "output": 'smoke-report'
}

runner = HTMLTestRunner(**kwargs)
runner.run(smoke_test)

Porque tengo el error de

$ python smoketest.py
Traceback (most recent call last):
  File "smoketest.py", line 1, in <module>
    import unittest
  File "C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\unittest\__init__.py", line 60, in <module>
    from .async_case import IsolatedAsyncioTestCase
  File "C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\unittest\async_case.py", line 1, in <module>
    import asyncio
  File "C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\asyncio\__init__.py", line 8, in <module>
    from .base_events import *
  File "C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\asyncio\base_events.py", line 23, in <module>
    import socket
  File "C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\socket.py", line 52, in <module>
    import os, sys, io, selectors
  File "C:\Users\Roy\Documents\selemium\selectors.py", line 2, in <module>
    from pyunitreport import HTMLTestRunner
  File "C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyunitreport\__init__.py", line 2, in <module>
    from .runner import HTMLTestRunner
  File "C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pyunitreport\runner.py", line 3, in <module>
    from unittest import TextTestRunner
ImportError: cannot import name 'TextTestRunner' from partially initialized module 'unittest' (most likely due to a circular import) (C:\Users\Roy\AppData\Local\Programs\Python\Python38-32\lib\unittest\__init__.py)```

tengo este error en mi ultimo test de los banners:
TypeError

object of type ‘WebElement’ has no len()

import unittest
from pyunitreport import HTMLTestRunner
from selenium import webdriver



class FindElements(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Chrome(executable_path= '/usr/bin/chromedriver')
        driver = self.driver
       # driver.get("link dado en clase lo comento para poder publicarlo en platzi")
        driver.maximize_window()
        driver.implicitly_wait(5)

    def test_search_text_field(self):
        search_field = self.driver.find_element_by_id("search") 
    

    def test_search_name(self):
        search_name = self.driver.find_element_by_name("q")

    def test_search_class_name(self):
        search_class_name = self.driver.find_element_by_class_name("input-text")

    def test_search_button_enable(self):
        search_button = self.driver.find_element_by_class_name("button")

    def test_count_banner_promos_images(self):
        promo_img_list = self.driver.find_element_by_class_name("promos")
        banners = promo_img_list.find_element_by_tag_name('img')
        self.assertEqual(3, len(banners))    



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

if __name__ == "__main__":
         unittest.main(verbosity = 2, 
                       testRunner = HTMLTestRunner(
                       output='reporte_HTML',
                       report_name='HTML_elements_report'))        

Si bien mis navegadores no se abren (y es porque estoy en WSL), estos fueron mis resultados en consola y en reportes:

ACTUALIZACION: 10/04/2021
Estuve peleando bastante y viendo los errores en consola y creo que esta bueno eso para aprender más.
Les comento para los que les sale error en la función “test_search_salt_shaker” y les sale FAILED el resultado. Yo use el mismo Xpath que del curso que es el mismo que saque personalmente pero siempre me daba que AssertEqual 1 != 0 (osea que 1 es diferente a 0, quiere decir que no lo encontraba el producto de la lista que le pasabamos) y lo que hice fue usar el pensamiento lateral y buscar el Xpath de lo más cercano al producto en vez del titulo se lo saque a la imagen luego de hacer el search. Asi quedaria el codigo

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="product-collection-image-389"]')
        self.assertEqual(1, len(products))

Saludos! Y nunca pares de aprender♥

Les dejo mi codigo de esta clase en este repositorio.

Para combinar los reportes en uno sólo, puede optar por esta alternativa
Primero instalen la siguiente libreria:

pip install html-testRunner

Despues modifiquen su código de python por el siguiente 😄

from unittest import TestLoader, TestSuite, main as Main
from assertions import AssertionsTest
from searchtests import SearchTests
from HtmlTestRunner import HTMLTestRunner


class SuitTest(TestSuite):
    assertions_test = TestLoader().loadTestsFromTestCase(AssertionsTest)  # carga una prueba a realizar
    search_tests = TestLoader().loadTestsFromTestCase(SearchTests)  # carga la otra prueba
    smoke_test = TestSuite([assertions_test, search_tests])


Main(testRunner=HTMLTestRunner(output='smoke-report',
                               report_name="chido",
                               combine_reports=True))

Me costo bastante dar con esa respuesta, pero estoy conforme con el resultado

En mi caso encontró un bug:

no puede ser, en serio se puede hacer eso 😮, que hermoso

hola, tengo un botón de subir archivo, y me abre una ventana de administrador de archivos de windows, ¿como le hago para subir un archivo?