# 3.2 Verificando o Ambiente com TDD

Conforme ressalta [Percival (2017)](http://www.obeythetestinggoat.com/pages/book.html), 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.&#x20;

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:

{% code lineNumbers="true" %}

```python
from selenium import webdriver

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

assert 'worked successfully' in browser.title
```

{% endcode %}

Esse teste deve ser salvo num arquivo `functional_tests.py` dentro da pasta `$HOME/tdd/superlists`.&#x20;

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

```bash
(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:

![](/files/-MZFVa9sszK3S0Ys3VUR)

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.

```bash
(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.

```bash
(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.&#x20;

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.

```bash
(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.

```bash
(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:

```bash
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.

![](/files/-MZF_wykwgMCu1d-vG5_)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://aurimrv.gitbook.io/tdd-python/3-desenvolvimento-dirigido-por-teste/3-2-verificando-o-ambiente-com-tdd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
