3.2 Verificando o Ambiente com TDD

Conforme ressalta Percival (2017), utilizar o estilo de programação do TDD pode não ser algo que surja naturalmente e é importante não desistir quando surgirem as primeiras dificuldades e/ou dúvidas quanto ao seu uso.

A ideia geral é de que nada seja feito sem que exista um teste para verificar o funcionamento de tudo. Por exemplo, sabendo que nossa aplicação irá executar no django, podemos redigir um teste para nos certificarmos de que o django esteja ativo e pronto para ser utilizado.

Para isso, podemos escrever um teste conforme apresentado abaixo:

from selenium import webdriver

browser = webdriver.Firefox()
browser.get("http://localhost:8000")

assert 'worked successfully' in browser.title

Esse teste deve ser salvo num arquivo functional_tests.py dentro da pasta $HOME/tdd/superlists.

Feito isso, é possível executar o teste com o comando abaixo:

(superlists) tdd@mlp:~/superlists$ python functional_tests.py 
Traceback (most recent call last):
  File "/home/tdd/superlists/functional_tests.py", line 4, in <module>
    browser.get("http://localhost:8000")
  File "/home/tdd/.pyenv/versions/superlists/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 363, in get
    self.execute(Command.GET, {"url": url})
  File "/home/tdd/.pyenv/versions/superlists/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 354, in execute
    self.error_handler.check_response(response)
  File "/home/tdd/.pyenv/versions/superlists/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Reached error page: about:neterror?e=connectionFailure&u=http%3A//localhost%3A8000/&c=UTF-8&d=Firefox%20can%E2%80%99t%20establish%20a%20connection%20to%20the%20server%20at%20localhost%3A8000.
Stacktrace:
RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8
WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:193:5
UnknownError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:832:5
checkReadyState@chrome://remote/content/marionette/navigate.sys.mjs:58:24
onNavigation@chrome://remote/content/marionette/navigate.sys.mjs:330:39
emit@resource://gre/modules/EventEmitter.sys.mjs:148:20
receiveMessage@chrome://remote/content/marionette/actors/MarionetteEventsParent.sys.mjs:33:25

A execução do teste causa a abertura de uma janela do Firefox com uma mensagem de erro, conforme ilustrado abaixo:

Como era de se esperar, o teste falhou, exatamente por não conseguir encontrar uma instância ativa do django em execução.

Fazendo o teste passar

Para fazermos o teste passar é necessário colocarmos uma instância do django em execução. Para isso, o primeiro passo é a criação de um projeto que será o contêiner principal de nosso site. A criação de um projeto em django pode ser feita com a ferramenta django-admin. O comando abaixo, executado dentro da pasta superlists do nosso ambiente virtual, irá criar esse projeto para nós.

(superlists) tdd@mlp:~/superlists$ django-admin startproject superlists

Em caso de sucesso, o comando não emite qualquer saída, mas irá criar um subdiretório superlists abaixo do diretório corrente. Parte da estrutura de diretórios do ambiente virtual com o projeto do django fica conforme apresentado na figura abaixo:

(superlists) tdd@mlp:~/superlists$ tree -L 3
.
├── functional_tests.py
├── requirements.txt
└── superlists
    ├── manage.py
    └── superlists
        ├── asgi.py
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py

2 directories, 8 files

Para inicializar o servidor django, basta executar o comando manage.py, conforme ilustrado abaixo, dentro do ambiente virtual.

(superlists) tdd@mlp:~/superlists$ cd superlists/
(superlists) tdd@mlp:~/superlists/superlists$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
June 22, 2024 - 09:17:04
Django version 5.0.6, using settings 'superlists.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

No exemplo acima, o django alerta que é necessário executar um comando para fazer a migração do projeto.

Quando você cria um novo projeto Django, ele já vem com várias aplicações padrão, como admin, auth, contenttypes e sessions. Cada uma dessas aplicações tem suas próprias tabelas e relações no banco de dados. As migrações para essas tabelas já existem, mas ainda não foram aplicadas ao banco de dados. Para aplicar essas migrações, pressionamos CONTROL-C para interromper a execução do servidor e, em seguida, executamos o comando indicado abaixo.

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

Feito isso é possível iniciar novamente o servidor e agora sem qualquer mensagem de aviso.

(superlists) tdd@mlp:~/superlists/superlists$ python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
June 22, 2024 - 09:23:01
Django version 5.0.6, using settings 'superlists.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Agora com o servidor no ar é possível reexecutar o teste para verificar se o mesmo passa. Para isso, basta abrir um novo terminal, se conectar ao ambiente virtual, entrar no diretório superlists (primeiro nível) e executar o comando para a execução, conforme abaixo:

tdd@mlp:~$ pyenv activate superlists
(superlists) tdd@mlp:~$ cd superlists/
(superlists) tdd@mlp:~/superlists$ python functional_tests.py 
(superlists) tdd@mlp:~/superlists$ 

Como consequência da execução, será aberta uma janela do Firefox mas desta vez o servidor django será encontrado e o teste irá se comportar conforme o esperado.

Last updated