🧰 CAPÍTULO 00: KIT DE SOBREVIVÊNCIA — ENGENHARIA DE SOFTWARE
Este capítulo assume que você já passou pelo Capítulo 00 — Fundamentos Comuns (terminal, Git, POO em Python, JSON/HTTP). Se ainda não viu, comece por lá.
🎯 Objetivos de Aprendizagem
Estimativa de dedicação: 2 horas de estudo autoguiado. Ao final deste capítulo, você será capaz de:
- 🔹 Ler (não desenhar) os três diagramas UML mais usados no curso: Casos de Uso, Classes e Sequência.
- 🔹 Subir seu primeiro servidor Flask e responder a uma requisição real.
- 🔹 Escrever e rodar seu primeiro teste automatizado com
pytest.
🏢 Por que isso importa
A Atividade 05 já pede um Diagrama de Casos de Uso, a Atividade 06 já pede para rodar um servidor Flask real e testá-lo com curl, e a Atividade 09 já pede testes com pytest — tudo isso antes da teoria completa de cada tópico ter sido consolidada. Este capítulo adianta o mínimo necessário para você não travar nesses pontos.
🧠 1. Como Ler um Diagrama UML
Você não precisa saber desenhar UML perfeitamente ainda — precisa saber ler os três tipos que mais aparecem no curso.
📌 Caso de Uso: "o que o sistema faz, por quem"
Um boneco (ator) se conecta a ações (óvalos). Uma seta pontilhada com <<include>> significa "esse caso de uso sempre aciona o outro".
flowchart LR
Cliente(("👤 Cliente"))
UC1(["Rastrear Pacote"])
UC2(["Cadastrar Pacote"])
UC3(["Validar CEP"])
Cliente --> UC1
Cliente --> UC2
UC2 -.->|"《include》"| UC3
style Cliente fill:#e3f2fd,stroke:#1e88e5
style UC3 fill:#fff8e1,stroke:#fbc02d
Leitura: o Cliente pode Rastrear ou Cadastrar um Pacote; cadastrar sempre inclui validar o CEP.
📌 Classes: "quais entidades existem e como se relacionam"
Cada caixa é uma classe (atributos em cima, métodos embaixo). O número perto da linha é a multiplicidade (quantos de cada lado).
classDiagram
class Cliente {
-nome: str
-email: str
}
class Pacote {
-codigo: str
-peso_kg: float
+calcular_frete() float
}
Cliente "1" --> "*" Pacote : envia
Leitura: 1 Cliente pode enviar * (zero ou muitos) Pacotes.
📌 Sequência: "quem chama quem, em que ordem, ao longo do tempo"
Cada linha vertical é um participante. As setas horizontais são mensagens, lidas de cima para baixo.
sequenceDiagram
actor Cliente
participant App as App Web
participant API as API Flask
Cliente->>App: Rastrear pacote BR123456
App->>API: GET /api/pacotes/BR123456
activate API
API-->>App: 200 OK + status JSON
deactivate API
App-->>Cliente: Mostra status na tela
Leitura: o Cliente pede à tela, a tela pede à API, a API responde, a tela mostra o resultado — nessa ordem exata.
Para desenhar seus próprios diagramas (não só ler), o curso usa o draw.io (extensão hediet.vscode-drawio já no .vscode/extensions.json). O Mermaid acima é só para você aprender a ler rápido, direto no navegador.
🧠 2. Flask: Seu Primeiro "Hello World"
A partir da Atividade 06, você vai rodar um servidor Flask de verdade. Vamos fazer isso uma vez, com calma.
📋 Instalação
pip install flask
💻 Código Completo (app.py)
"""
Módulo: app.py
Primeiro servidor Flask da jornada TecProExpress.
Execução: python app.py
"""
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/")
def index():
return "🚚 TecProExpress API no ar!"
@app.route("/api/saudacao", methods=["POST"])
def saudacao():
dados = request.get_json() or {}
nome = dados.get("nome", "visitante")
return jsonify({"mensagem": f"Olá, {nome}! Bem-vindo à TecProExpress."}), 200
if __name__ == "__main__":
print("🚀 Servidor Flask ativo em: http://127.0.0.1:5000")
app.run(debug=True, port=5000)
🚀 Como Executar
python app.py
🌐 Testando com curl (em outro terminal)
curl -X POST http://127.0.0.1:5000/api/saudacao \
-H "Content-Type: application/json" \
-d "{\"nome\": \"Ana\"}"
🖥️ Resposta Esperada
{"mensagem": "Olá, Ana! Bem-vindo à TecProExpress."}
🔍 Detalhamento do Código:
@app.route("/api/saudacao", methods=["POST"]): registra a rota e o verbo HTTP aceito.request.get_json(): lê o corpo JSON enviado no-ddo curl.jsonify(...): converte o dicionário Python de volta em uma resposta JSON válida.app.run(debug=True, port=5000):debug=Truerecarrega o servidor sozinho a cada alteração salva — ótimo durante o desenvolvimento.
Se a porta 5000 já estiver em uso no seu computador, troque para app.run(debug=True, port=5001) — e lembre de usar a mesma porta no curl. É exatamente esse tipo de divergência (porta do servidor ≠ porta do curl) que mais trava quem está começando.
🧠 3. pytest em 10 Minutos
📋 Instalação
pip install pytest
💻 Código Completo (test_saudacao.py)
Salve no mesmo diretório do app.py criado acima:
"""
Módulo: test_saudacao.py
Execução: pytest test_saudacao.py -v
"""
import pytest
from app import app
@pytest.fixture
def client():
app.config["TESTING"] = True
with app.test_client() as client:
yield client
def test_saudacao_com_nome(client):
resposta = client.post("/api/saudacao", json={"nome": "Ana"})
assert resposta.status_code == 200
assert "Ana" in resposta.get_json()["mensagem"]
def test_saudacao_sem_nome(client):
resposta = client.post("/api/saudacao", json={})
assert resposta.status_code == 200
assert "visitante" in resposta.get_json()["mensagem"]
🚀 Como Executar
pytest test_saudacao.py -v
🖥️ Saída Esperada no Terminal
test_saudacao.py::test_saudacao_com_nome PASSED [ 50%]
test_saudacao.py::test_saudacao_sem_nome PASSED [100%]
============================== 2 passed in 0.08s ===============================
🔍 Detalhamento do Código:
@pytest.fixture: prepara algo reutilizável (aqui, um cliente de testes) para cada função de teste que o receber como parâmetro.app.test_client(): simula requisições HTTP contra o Flask sem precisar subir o servidor de verdade — mais rápido e mais confiável.assert: se a condição for falsa, o teste falha e o pytest mostra exatamente qual valor era esperado.
💡 Checkpoint de Lógica
Reflexão Profissional: Por que testar com app.test_client() é melhor do que abrir o navegador e clicar manualmente toda vez que você muda uma linha de código? (Resposta: um teste automatizado roda em milissegundos, não esquece nenhum caso, e pode rodar sozinho num pipeline de CI/CD a cada push — o que você fará na Atividade 16.) 🧠🛡️
🧪 Quiz de Fixação e Autoavaliação
🧪 Quiz de Autoavaliação — Capítulo 00 (Engenharia de Software)
🧪 Quiz de Autoavaliação — Capítulo 00 (Engenharia de Software)
1. No diagrama de classes, o que a multiplicidade "1" --> "*" entre Cliente e Pacote significa?
- A) Todo Pacote pertence a exatamente 1 Cliente e todo Cliente tem exatamente 1 Pacote.
- B) Um Cliente pode enviar zero ou muitos Pacotes.
- C) Um Pacote pode ter muitos Clientes.
- D) É um erro de sintaxe.
💡 Ver Resposta e Justificativa
Resposta Correta: B
Justificativa: "1" do lado de Cliente e "*" do lado de Pacote significa "1 Cliente para 0..N Pacotes" — a leitura sempre começa do lado com "1".
2. No Flask, qual função converte um dicionário Python em uma resposta JSON válida?
-
A)
request.get_json() -
B)
jsonify() -
C)
app.route() -
D)
json.dumps()é obrigatório,jsonify()não existe no Flask.
💡 Ver Resposta e Justificativa
Resposta Correta: B
Justificativa: jsonify() é a função nativa do Flask para serializar dados Python em uma resposta HTTP com Content-Type: application/json correto.
3. Por que usar app.test_client() em vez de rodar o servidor de verdade nos testes?
- A) É mais rápido e não depende de uma porta de rede estar livre.
- B) É a única forma de testar rotas POST.
- C) Não é possível testar Flask com pytest.
-
D)
test_client()substitui ocurlem produção.
💡 Ver Resposta e Justificativa
Resposta Correta: A
Justificativa: test_client() simula requisições HTTP em memória, sem abrir uma porta de rede real — os testes rodam em milissegundos e não conflitam entre si.
🛠️ Ponte para a Ação
Você está pronto para a jornada. Siga para: 👉 CAPÍTULO 01: INTRODUÇÃO E NATUREZA DO SOFTWARE 👉 ATIVIDADE 01: ESCOPO E PERSONAS
📌 Resumo Executivo & Key Takeaways
- UML: Casos de Uso mostram quem faz o quê; Classes mostram quais entidades existem; Sequência mostra a ordem das chamadas ao longo do tempo.
- Flask: uma rota é uma função decorada com
@app.route;request.get_json()lê a entrada,jsonify()formata a saída. - pytest:
app.test_client()testa rotas Flask sem precisar de um servidor real rodando — é assim que a Atividade 09 e o pipeline de CI/CD da Atividade 16 funcionam.