frlp-utn-ingsoft / orderingg

Aplicación utilizada en la cursada 2018 de Ingenieria de Software. UTN-FRLP
4 stars 20 forks source link

Mensaje al ejecutar pytest #42

Closed Alexissiminkowich closed 6 years ago

Alexissiminkowich commented 6 years ago

Ejecuto pytest y me tira todo lo siguiente, me faltara actualizar alguna carpeta? Sino vuelvo a actualizar todo contra el repo de ustedes:

Equipo@Equipo-PC MINGW32 ~/Desktop/ING DE SOFTWARE/orderingg (dev) $ pytest ============================= test session starts ============================= platform win32 -- Python 3.4.0, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 rootdir: C:\Users\Equipo\Desktop\ING DE SOFTWARE\orderingg, inifile: collected 3 items

test\test_e2e.py F [ 33%] test\test_unit.py .. [100%]

================================== FAILURES =================================== _____ Ordering.testtitle ____

self = result = <TestCaseFunction 'test_title'>

def __call__(self, result=None):
    """
        Does the required setup, doing it here means you don't have to
        call super.setUp in subclasses.
        """

    # Get the app
    self.app = self.create_app()

    self._configured_port = self.app.config.get('LIVESERVER_PORT', 5000)
    self._port_value = multiprocessing.Value('i', self._configured_port)

    # We need to create a context in order for extensions to catch up
    self._ctx = self.app.test_request_context()
    self._ctx.push()

    try:
      self._spawn_live_server()

C:\Python34\lib\site-packages\flask_testing\utils.py:446:


self =

def _spawn_live_server(self):
    self._process = None
    port_value = self._port_value

    def worker(app, port):
        # Based on solution: http://stackoverflow.com/a/27598916
        # Monkey-patch the server_bind so we can determine the port bound by Flask.
        # This handles the case where the port specified is `0`, which means that
        # the OS chooses the port. This is the only known way (currently) of getting
        # the port out of Flask once we call `run`.
        original_socket_bind = socketserver.TCPServer.server_bind
        def socket_bind_wrapper(self):
            ret = original_socket_bind(self)

            # Get the port and save it into the port_value, so the parent process
            # can read it.
            (_, port) = self.socket.getsockname()
            port_value.value = port
            socketserver.TCPServer.server_bind = original_socket_bind
            return ret

        socketserver.TCPServer.server_bind = socket_bind_wrapper
        app.run(port=port, use_reloader=False)

    self._process = multiprocessing.Process(
        target=worker, args=(self.app, self._configured_port)
    )
  self._process.start()

C:\Python34\lib\site-packages\flask_testing\utils.py:486:


self = <Process(Process-1, initial)>

def start(self):
    '''
        Start child process
        '''
    assert self._popen is None, 'cannot start a process twice'
    assert self._parent_pid == os.getpid(), \
           'can only start a process object created by current process'
    assert not _current_process._config.get('daemon'), \
           'daemonic processes are not allowed to have children'
    _cleanup()
  self._popen = self._Popen(self)

C:\Python34\lib\multiprocessing\process.py:105:


process_obj = <Process(Process-1, initial)>

@staticmethod
def _Popen(process_obj):
  return _default_context.get_context().Process._Popen(process_obj)

C:\Python34\lib\multiprocessing\context.py:212:


process_obj = <Process(Process-1, initial)>

@staticmethod
def _Popen(process_obj):
    from .popen_spawn_win32 import Popen
  return Popen(process_obj)

C:\Python34\lib\multiprocessing\context.py:313:


self = <multiprocessing.popen_spawn_win32.Popen object at 0x03C5D3B0> process_obj = <Process(Process-1, initial)>

def __init__(self, process_obj):
    prep_data = spawn.get_preparation_data(process_obj._name)

    # read end of pipe will be "stolen" by the child process
    # -- see spawn_main() in spawn.py.
    rhandle, whandle = _winapi.CreatePipe(None, 0)
    wfd = msvcrt.open_osfhandle(whandle, 0)
    cmd = spawn.get_command_line(parent_pid=os.getpid(),
                                 pipe_handle=rhandle)
    cmd = ' '.join('"%s"' % x for x in cmd)

    with open(wfd, 'wb', closefd=True) as to_child:
        # start process
        try:
            hp, ht, pid, tid = _winapi.CreateProcess(
                spawn.get_executable(), cmd,
                None, None, False, 0, None, None, None)
            _winapi.CloseHandle(ht)
        except:
            _winapi.CloseHandle(rhandle)
            raise

        # set attributes of self
        self.pid = pid
        self.returncode = None
        self._handle = hp
        self.sentinel = int(hp)
        util.Finalize(self, _winapi.CloseHandle, (self.sentinel,))

        # send information to child
        context.set_spawning_popen(self)
        try:
            reduction.dump(prep_data, to_child)
          reduction.dump(process_obj, to_child)

C:\Python34\lib\multiprocessing\popen_spawn_win32.py:66:


obj = <Process(Process-1, initial)>, file = <_io.BufferedWriter name=8> protocol = None

def dump(obj, file, protocol=None):
    '''Replacement for pickle.dump() using ForkingPickler.'''
  ForkingPickler(file, protocol).dump(obj)

E _pickle.PicklingError: Can't pickle <function LiveServerTestCase._spawn_live_server..worker at 0x03C87150>: attribute lookup worker on flask_testing.utils failed

C:\Python34\lib\multiprocessing\reduction.py:60: PicklingError

During handling of the above exception, another exception occurred:

self = result = <TestCaseFunction 'test_title'>

def __call__(self, result=None):
    """
        Does the required setup, doing it here means you don't have to
        call super.setUp in subclasses.
        """

    # Get the app
    self.app = self.create_app()

    self._configured_port = self.app.config.get('LIVESERVER_PORT', 5000)
    self._port_value = multiprocessing.Value('i', self._configured_port)

    # We need to create a context in order for extensions to catch up
    self._ctx = self.app.test_request_context()
    self._ctx.push()

    try:
        self._spawn_live_server()
        super(LiveServerTestCase, self).__call__(result)
    finally:
        self._post_teardown()
      self._terminate_live_server()

C:\Python34\lib\site-packages\flask_testing\utils.py:450:


C:\Python34\lib\site-packages\flask_testing\utils.py:552: in _terminate_live_server self._process.terminate()


self = <Process(Process-1, initial)>

def terminate(self):
    '''
        Terminate process; sends SIGTERM signal or uses TerminateProcess()
        '''
  self._popen.terminate()

E AttributeError: 'NoneType' object has no attribute 'terminate'

C:\Python34\lib\multiprocessing\process.py:113: AttributeError -------------------------- Captured stderr teardown --------------------------- Traceback (most recent call last): File "", line 1, in File "C:\Python34\lib\multiprocessing\spawn.py", line 98, in spawn_main exitcode = _main(fd) File "C:\Python34\lib\multiprocessing\spawn.py", line 108, in _main self = pickle.load(from_parent) EOFError: Ran out of input ===================== 1 failed, 2 passed in 4.04 seconds ======================

RodrigoJacznik commented 6 years ago

Estas en windows? Creo que es un issue de la libreria con windows. Arranca con los test de unidad (Corre esos solos con pytest test/test_unit.py) y yo me fijo si encuentro algo mas de info.

Saludos.

Alexissiminkowich commented 6 years ago

Sisi, es windows. Para hacer pytest de unidad como me mencionas funciona bien.

RodrigoJacznik commented 6 years ago

Alexis, podes probar con reemplazar el contenido de test_e2e.py con lo siguiente

import unittest
import os
import time
import threading

from selenium import webdriver

from app import create_app, db
from app.models import Product, Order, OrderProduct

basedir = os.path.abspath(os.path.dirname(__file__))

class Ordering(unittest.TestCase):
    # Creamos la base de datos de test
    def setUp(self):
        self.app = create_app()
        self.app.config.update(
            SQLALCHEMY_DATABASE_URI='sqlite:///' + os.path.join(basedir, 'test.db'),
            SQLALCHEMY_TRACK_MODIFICATIONS=False,
            TESTING=True
        )
        self.app_context = self.app.app_context()
        self.app_context.push()

        self.baseURL = 'http://localhost:5000'

        db.session.commit()
        db.drop_all()
        db.create_all()

        # start the Flask server in a thread
        threading.Thread(target=self.app.run).start()

        # give the server a second to ensure it is up
        time.sleep(1)

        self.driver = webdriver.Chrome()

    def test_title(self):
        driver = self.driver
        driver.get(self.baseURL)
        add_product_button = driver.find_element_by_xpath('/html/body/main/div[1]/div/button')
        add_product_button.click()
        modal = driver.find_element_by_id('modal')
        assert modal.is_displayed(), "El modal no esta visible"

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.driver.close()

if __name__ == "__main__":
    unittest.main()
RodrigoJacznik commented 6 years ago

Pudiste probar? Actualice el repo para que funcionen los test con selenium desde Windows

Alexissiminkowich commented 6 years ago

Puse en el test_e2e.py lo que me pasaste pero sigue dando el mismo error. Igualmente, ahora voy a tratar de hacer algun test de unidad... tuve una semana ocupada con el tema de mi señora y casi no me pude sentar a trabajar. Saludos

Alexissiminkowich commented 6 years ago

Rodrigo, supuestamente ya tengo todo actualizado a su ultima version, en tag 4.0.2, tambien ya corri el pip install -r requirements.txt

Pero al tirar pytest me tira lo siguiente, igualmente voy a seguir creando los test que pueda:

Recuerdo: Uso WIN 7 32 bit,

Resultado del pytest:

Equipo@Equipo-PC MINGW32 ~/Desktop/ING DE SOFTWARE/orderingg (master) $ pytest ============================= test session starts ============================= platform win32 -- Python 3.4.0, pytest-3.5.1, py-1.5.3, pluggy-0.6.0 rootdir: C:\Users\Equipo\Desktop\ING DE SOFTWARE\orderingg, inifile: collected 4 items

test\test_e2e.py F [ 25%] test\test_unit.py ..F [100%]

================================== FAILURES =================================== _____ Ordering.testtitle ____

self = <selenium.webdriver.chrome.service.Service object at 0x03D074F0>

def start(self):
    """
        Starts the Service.

        :Exceptions:
         - WebDriverException : Raised either when it can't start the servic                               e
           or when it can't connect to the service
        """
    try:
        cmd = [self.path]
        cmd.extend(self.command_line_args())
        self.process = subprocess.Popen(cmd, env=self.env,
                                        close_fds=platform.system() != 'Wind                               ows',
                                        stdout=self.log_file,
                                        stderr=self.log_file,
                                      stdin=PIPE)

C:\Python34\lib\site-packages\selenium\webdriver\common\service.py:76:


self = <subprocess.Popen object at 0x03D075B0> args = ['chromedriver', '--port=50114'], bufsize = -1, executable = None stdin = -1, stdout = -3, stderr = -3, preexec_fn = None, close_fds = False shell = False, cwd = None env = environ({'MINGW_CHOST': 'i686-w64-mingw32', 'INFOPATH': 'C:\Program Files \Git\usr\local\info;C:\Program Files\G... Files/Git/mingw32/etc/config.sit e', 'APPDATA': 'C:\Users\Equipo\AppData\Roaming', 'LOGONSERVER': '\\EQUIPO -PC'}) universal_newlines = False, startupinfo = None, creationflags = 0 restore_signals = True, start_new_session = False, pass_fds = ()

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
             shell=False, cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=()):
    """Create new Popen instance."""
    _cleanup()

    self._child_created = False
    self._input = None
    self._communication_started = False
    if bufsize is None:
        bufsize = -1  # Restore default
    if not isinstance(bufsize, int):
        raise TypeError("bufsize must be an integer")

    if mswindows:
        if preexec_fn is not None:
            raise ValueError("preexec_fn is not supported on Windows "
                             "platforms")
        any_stdio_set = (stdin is not None or stdout is not None or
                         stderr is not None)
        if close_fds is _PLATFORM_DEFAULT_CLOSE_FDS:
            if any_stdio_set:
                close_fds = False
            else:
                close_fds = True
        elif close_fds and any_stdio_set:
            raise ValueError(
                    "close_fds is not supported on Windows platforms"
                    " if you redirect stdin/stdout/stderr")
    else:
        # POSIX
        if close_fds is _PLATFORM_DEFAULT_CLOSE_FDS:
            close_fds = True
        if pass_fds and not close_fds:
            warnings.warn("pass_fds overriding close_fds.", RuntimeWarning)
            close_fds = True
        if startupinfo is not None:
            raise ValueError("startupinfo is only supported on Windows "
                             "platforms")
        if creationflags != 0:
            raise ValueError("creationflags is only supported on Windows "
                             "platforms")

    self.args = args
    self.stdin = None
    self.stdout = None
    self.stderr = None
    self.pid = None
    self.returncode = None
    self.universal_newlines = universal_newlines

    # Input and output objects. The general principle is like
    # this:
    #
    # Parent                   Child
    # ------                   -----
    # p2cwrite   ---stdin--->  p2cread
    # c2pread    <--stdout---  c2pwrite
    # errread    <--stderr---  errwrite
    #
    # On POSIX, the child objects are file descriptors.  On
    # Windows, these are Windows file handles.  The parent objects
    # are file descriptors on both platforms.  The parent objects
    # are -1 when not using PIPEs. The child objects are -1
    # when not redirecting.

    (p2cread, p2cwrite,
     c2pread, c2pwrite,
     errread, errwrite) = self._get_handles(stdin, stdout, stderr)

    # We wrap OS handles *before* launching the child, otherwise a
    # quickly terminating child could make our fds unwrappable
    # (see #8458).

    if mswindows:
        if p2cwrite != -1:
            p2cwrite = msvcrt.open_osfhandle(p2cwrite.Detach(), 0)
        if c2pread != -1:
            c2pread = msvcrt.open_osfhandle(c2pread.Detach(), 0)
        if errread != -1:
            errread = msvcrt.open_osfhandle(errread.Detach(), 0)

    if p2cwrite != -1:
        self.stdin = io.open(p2cwrite, 'wb', bufsize)
        if universal_newlines:
            self.stdin = io.TextIOWrapper(self.stdin, write_through=True)
    if c2pread != -1:
        self.stdout = io.open(c2pread, 'rb', bufsize)
        if universal_newlines:
            self.stdout = io.TextIOWrapper(self.stdout)
    if errread != -1:
        self.stderr = io.open(errread, 'rb', bufsize)
        if universal_newlines:
            self.stderr = io.TextIOWrapper(self.stderr)

    self._closed_child_pipe_fds = False
    try:
        self._execute_child(args, executable, preexec_fn, close_fds,
                            pass_fds, cwd, env,
                            startupinfo, creationflags, shell,
                            p2cread, p2cwrite,
                            c2pread, c2pwrite,
                            errread, errwrite,
                          restore_signals, start_new_session)

C:\Python34\lib\subprocess.py:848:


self = <subprocess.Popen object at 0x03D075B0> args = 'chromedriver --port=50114', executable = None, preexec_fn = None close_fds = False, pass_fds = (), cwd = None env = environ({'MINGW_CHOST': 'i686-w64-mingw32', 'INFOPATH': 'C:\Program Files \Git\usr\local\info;C:\Program Files\G... Files/Git/mingw32/etc/config.sit e', 'APPDATA': 'C:\Users\Equipo\AppData\Roaming', 'LOGONSERVER': '\\EQUIPO -PC'}) startupinfo = <subprocess.STARTUPINFO object at 0x03D07750>, creationflags = 0 shell = False, p2cread = Handle(820), p2cwrite = 10, c2pread = -1 c2pwrite = Handle(824), errread = -1, errwrite = Handle(828) unused_restore_signals = True, unused_start_new_session = False

def _execute_child(self, args, executable, preexec_fn, close_fds,
                   pass_fds, cwd, env,
                   startupinfo, creationflags, shell,
                   p2cread, p2cwrite,
                   c2pread, c2pwrite,
                   errread, errwrite,
                   unused_restore_signals, unused_start_new_session):
    """Execute program (MS Windows version)"""

    assert not pass_fds, "pass_fds not supported on Windows."

    if not isinstance(args, str):
        args = list2cmdline(args)

    # Process startup details
    if startupinfo is None:
        startupinfo = STARTUPINFO()
    if -1 not in (p2cread, c2pwrite, errwrite):
        startupinfo.dwFlags |= _winapi.STARTF_USESTDHANDLES
        startupinfo.hStdInput = p2cread
        startupinfo.hStdOutput = c2pwrite
        startupinfo.hStdError = errwrite

    if shell:
        startupinfo.dwFlags |= _winapi.STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = _winapi.SW_HIDE
        comspec = os.environ.get("COMSPEC", "cmd.exe")
        args = '{} /c "{}"'.format (comspec, args)

    # Start the process
    try:
        hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
                                 # no special security
                                 None, None,
                                 int(not close_fds),
                                 creationflags,
                                 env,
                                 cwd,
                               startupinfo)

E FileNotFoundError: [WinError 2] El sistema no puede encontrar el archivo especificado

C:\Python34\lib\subprocess.py:1104: FileNotFoundError

During handling of the above exception, another exception occurred:

self =

def setUp(self):
    self.app = create_app()
    self.app.config.update(
        SQLALCHEMY_DATABASE_URI='sqlite:///' + os.path.join(basedir, 'test.d                               b'),
        SQLALCHEMY_TRACK_MODIFICATIONS=False,
        TESTING=True
    )
    self.app_context = self.app.app_context()
    self.app_context.push()

    self.baseURL = 'http://localhost:5000'

    db.session.commit()
    db.drop_all()
    db.create_all()

    # start the Flask server in a thread
    threading.Thread(target=self.app.run).start()

    # give the server a second to ensure it is up
    time.sleep(1)
  self.driver = webdriver.Chrome()

test\test_e2e.py:37:


C:\Python34\lib\site-packages\selenium\webdriver\chrome\webdriver.py:68: in in it self.service.start()


self = <selenium.webdriver.chrome.service.Service object at 0x03D074F0>

def start(self):
    """
        Starts the Service.

        :Exceptions:
         - WebDriverException : Raised either when it can't start the servic                               e
           or when it can't connect to the service
        """
    try:
        cmd = [self.path]
        cmd.extend(self.command_line_args())
        self.process = subprocess.Popen(cmd, env=self.env,
                                        close_fds=platform.system() != 'Wind                               ows',
                                        stdout=self.log_file,
                                        stderr=self.log_file,
                                        stdin=PIPE)
    except TypeError:
        raise
    except OSError as err:
        if err.errno == errno.ENOENT:
            raise WebDriverException(
                "'%s' executable needs to be in PATH. %s" % (
                  os.path.basename(self.path), self.start_error_message)

E selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.c om/a/chromium.org/chromedriver/home

C:\Python34\lib\site-packages\selenium\webdriver\common\service.py:83: WebDriver Exception OrderingTestCase.test_instance_of_OrderProduct_with_negative_quantity

seft =

def test_instance_of_OrderProduct_with_negative_quantity(seft):
    o = Order(id=1)
    db.session.add (o)
    p = Product(id=1, name='Armario', price=800)
    db.session.add(p)
    orderProduct = OrderProduct(order_id=1, product_id=1, quantity=-1, produ                               ct=p)
    db.session.add(orderProduct)
    db.session.commit()
    ordp = OrderProduct.query.all()
  self.assertEqual(len(ordp),1, "Se creo el prod con cantidad negativa")

E NameError: name 'self' is not defined

test\test_unit.py:66: NameError ===================== 2 failed, 2 passed in 7.15 seconds ======================

Alexissiminkowich commented 6 years ago

Lo que hice fue "borrar" el test def test_title(self) de ustedes poniendo # para ignorarlo (era el que me tiraba el error). Así continuo con los de unidad mientras tanto

RodrigoJacznik commented 6 years ago

Hola Alexis, me parece que te falto instalar chromedriver y ponerlo en el path de windows. Te paso el link de chromedriver. Si tenes algún problema avísame y lo revisamos

Alexissiminkowich commented 6 years ago

Ya baje el ChromeDriver 2.39 , al ejecutarlo me abre una pantalla de cmd con lo siguiente:

Starting ChromeDriver 2.39.562718 (9a2698cba08cf5a471a29d30c8b3e12becabb0e9) on port 9515 Only local connections are allowed.

Y no hace nada. Despues de hacer eso sigo intentanto el pytest con el test de ejemplo de integracion y sigue dando el mismo error

RodrigoJacznik commented 6 years ago

Esta bien, el único paso que te falto es agregar al path de windows la carpeta donde esta el chromdriver.exe

Alexissiminkowich commented 6 years ago

Mil gracias!! (cuantas vueltas para que ande jaja). Voy a intentar hacer los de integración, disculpen la hora... trabaje todo el día y sumado visita al medico por mi mujer. Este tema esta terminado ya, me ejecuto bien el test de integración de ejemplo de ustedes.

Saludos!

RodrigoJacznik commented 6 years ago

Genial, no hay drama. Cualquier cosa subi una issue