Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b5aa29c
:bug: Correção de bug encontrado no teste docente #251
wanessabezerra Dec 10, 2022
536dae7
:wrench: Mudança em Settings #252
wanessabezerra Dec 10, 2022
cd8c414
:memo: Adição do tutorial do MutPy #255
wanessabezerra Dec 14, 2022
84b1720
:hammer: Criação do Teste de Sugestão de Geografia #256
wanessabezerra Dec 14, 2022
b5cf91c
:white_check_mark: Adição de testes de dao.py @renatak12 #259
wanessabezerra Dec 20, 2022
8d9eaa2
:white_check_mark: Adição dos testes de flow_view.py @renatak12 #259
wanessabezerra Dec 20, 2022
8669302
:white_check_mark: Adição de teste de sugestao_view.py @renatak12 #259
wanessabezerra Dec 20, 2022
d8c4533
white_check_mark Adição dos testes de sugestao.py @renatak12 #259
wanessabezerra Dec 20, 2022
ee973e5
white_check_mark Adição dos testes de turma_view.py @renatak12 #259
wanessabezerra Dec 20, 2022
8c36eba
@wanessabezerra
wanessabezerra Dec 20, 2022
f5e49a1
white_check_mark Adição dos testes de discente.py #259
wanessabezerra Dec 20, 2022
5e54565
:white_check_mark: Adição dos testes de turma_view.py @renatak12 #259
wanessabezerra Dec 20, 2022
9862f05
:white_check_mark: Adição de teste de user_view.py @renatak12 #259
wanessabezerra Dec 20, 2022
4dfbd6c
:memo: Adição do resultado gerado pelo teste de mutação MutPy #252
wanessabezerra Dec 20, 2022
28a0d55
Merge branch 'main' into testes3
tacianosilva May 3, 2023
eaefefb
tests: add lib do teste de mutação #252
tacianosilva May 4, 2023
43ec474
Update test_docente.py
tacianosilva May 4, 2023
63b8fd8
Update test_docente.py
tacianosilva May 4, 2023
3b8ac6d
Merge branch 'main' into testes3
tacianosilva Jun 20, 2023
b98e451
Merge branch 'main' into testes3
tacianosilva Dec 9, 2024
938487b
Merge branch 'main' into testes3
tacianosilva Sep 15, 2026
d3b625e
chore: separate mutation testing dependencies
tacianosilva Sep 15, 2026
6ff0a70
fix: run CI tests only on Python 3.12
tacianosilva Sep 15, 2026
39c1ad8
fix: use reverse() in tests and update django-filter for Django 5.2
tacianosilva Sep 15, 2026
cc70afd
docs: update AGENTS.md with requirements, test guidelines, and sessio…
tacianosilva Sep 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ['3.10']
python-version: ['3.12']

services:
postgres:
Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
- name: Lint with flake8
run: |
pip install flake8
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ coverage.xml
*.cover
.hypothesis/
.pytest_cache/
test.txt

# Translations
*.mo
Expand Down
25 changes: 19 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
- `DJANGO_SETTINGS_MODULE=suggestclasses.settings` and `PYTHONPATH` are set by
`.env`; there is no separate `path.env`.

## Requirements and Settings

- `requirements.txt`: Runtime dependencies only.
- `requirements-dev.txt`: Development and testing dependencies (includes `-r requirements.txt`, coverage, selenium, etc.). Used by CI and local test runs.
- `requirements-mutation.txt`: Mutation testing dependencies (includes `-r requirements-dev.txt` and `django-mutpy`). Note: `django-mutpy` / `mutpy` requires Python 3.11 (incompatible with Python 3.12 due to `distutils` / `importlib` removals).
- `suggestclasses/mutation_settings.py`: Settings module that extends base settings and adds `django_mutpy` to `INSTALLED_APPS` for mutation runs (`python manage.py muttest <app> --settings=suggestclasses.mutation_settings`).

## Database and tests

- The application reads the default database configuration from
Expand Down Expand Up @@ -52,11 +59,11 @@

`--keepdb` preserves the test database between executions.

- When writing view tests, always use `reverse('url_name')` from `core/urls.py`. Never hardcode literal paths like `/core/...` because `core.urls` is included under `/suggestclasses/` in `suggestclasses/urls.py`.

## CI

- The GitHub Actions workflow copies `.env.example` to `.env` and then replaces
the database credentials with those of its PostgreSQL service
(`postgres`/`postgres`).
- The GitHub Actions workflow runs on Python 3.12, installs `requirements-dev.txt`, copies `.env.example` to `.env`, and replaces the database credentials with those of its PostgreSQL service (`postgres`/`postgres`).
- Keep `.env.example` free of real credentials and compatible with the
variables read by `suggestclasses/settings.py`.

Expand All @@ -72,6 +79,12 @@
`path.env` rule from `.gitignore`.
- The test database permission issue was reproduced and resolved locally after
granting `CREATEDB` and `INHERIT` to the database role.
- The test suite still has one unrelated pre-existing failure:
`core/tests/test_historico.py` uses removed `assertEquals`; use
`assertEqual` when addressing that test separately.
- Separated dependencies into `requirements.txt`, `requirements-dev.txt`, and `requirements-mutation.txt`.
- Created `suggestclasses/mutation_settings.py` for mutation testing, removing `django_mutpy` from base `INSTALLED_APPS`.
- Removed the generated `test.txt` artifact and added it to `.gitignore`.
- Updated CI matrix to Python 3.12 and switched to installing `requirements-dev.txt`.
- Fixed pre-existing deprecated `assertEquals` calls to `assertEqual` in `core/tests/test_historico.py`.
- Fixed view tests to use `reverse()` instead of invalid hardcoded `/core/...` paths.
- Standardized `LOGIN_REDIRECT_URL` and `LOGOUT_REDIRECT_URL` with a trailing slash (`/suggestclasses/`).
- Upgraded `django-filter` to `25.1` for Django 5.2 compatibility.

34 changes: 33 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,21 @@ source .venv/bin/activate
pip install -r requirements.txt
```

O arquivo `requirements.txt` contém somente as dependências necessárias para
executar a aplicação. Para desenvolvimento e testes, instale também:

```console
pip install -r requirements-dev.txt
```

As dependências específicas dos testes de mutação ficam em
`requirements-mutation.txt`. Elas incluem as dependências de desenvolvimento e
o `django-mutpy`:

```console
pip install -r requirements-mutation.txt
```

Atualize os arquivos estáticos.

```console
Expand Down Expand Up @@ -166,13 +181,30 @@ source .env
python manage.py test --keepdb
```

### Executar os Testes de Unidade e Cobertura
### Executar os Testes de Unidade, Testes de Mutação e Cobertura

```shell script
source .env
coverage run manage.py test
```

Para executar os testes de mutação, use o settings específico de mutação, que
adiciona o `django_mutpy` somente nesse contexto. O MutPy 0.6.1 e o
`django-mutpy` 0.1.2 exigem Python 3.11 ou anterior; os testes normais do
projeto usam Python 3.12 no CI.

```shell script
python3.11 -m venv .venv311
source .venv311/bin/activate
pip install -r requirements-mutation.txt
source .env
export DJANGO_SETTINGS_MODULE=suggestclasses.mutation_settings
python manage.py muttest core
```

O settings padrão não registra o `django_mutpy`, portanto a ferramenta não é
carregada no ambiente normal da aplicação.

## Executar o Sonar

```shell script
Expand Down
17 changes: 16 additions & 1 deletion core/tests/test_curriculo.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import django
django.setup()

from core.bo.curriculo import get_curriculo_by_cc
from core.bo.curriculo import get_curriculo_by_cc, get_semestres_by_curso, get_componentes_by_curso,get_componentes_by_curso_semestre
from core.models import ComponenteCurricular
from core.tests.povoar_testes import criar_dados, remover_dados
from django.test import TestCase
Expand Down Expand Up @@ -32,3 +32,18 @@ def test_get_curriculo_by_cc(self):

self.assertIsNotNone(curriculos, 'Curriculos 2 não é None?')
self.assertEqual(2, len(curriculos), 'Testando quantidade de currículos 2.')

def test_get_semestres_by_curso(self):
semestre = get_semestres_by_curso(9999)

self.assertIsNotNone(semestre, 'Semestre 1 não é None?')
self.assertEqual(0, len(semestre), 'Testando quantidade de currículos 1.')

def test_get_componentes_by_curso(self):
oc = get_componentes_by_curso(9999)

self.assertIsNotNone(oc, 'Componentes por curso não é None?')
self.assertEqual(0, len(oc), 'Testando quantidade de componentes.')

def test_get_componentes_by_curso_semestre(self):
pass
21 changes: 19 additions & 2 deletions core/tests/test_dao.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import django
django.setup()
from core.bo.curso import get_cursos
from core.bo.curso import get_cursos, get_cursos_by_centro, get_curso_by_codigo
from core.bo.sala import get_salas
from django.test import TestCase
from core.tests.povoar_testes import criar_dados, remover_dados
from core.dao.centro_dao import get_centro_by_id, get_centros
from core.dao.componente_dao import get_componentes_by_depto
from core.dao.departamento_dao import get_depto_by_id, get_departamentos


class DAOTests(TestCase):

@classmethod
Expand Down Expand Up @@ -88,3 +87,21 @@ def test_get_salas(self):

self.assertIsNotNone(cursos, 'Testando cursos')
self.assertTrue(len(cursos) > 0, 'Testando cursos')

def test_get_curso(self):
cursos = get_cursos_by_centro()

self.assertIsNotNone(cursos, 'Discentes não é None?')
self.assertTrue(len(cursos) > 0, 'Testando cursos')

def test_get_curso(self):
cursos = get_curso_by_codigo(9999)

self.assertIsNotNone(cursos, 'Discentes não é None?')
self.assertTrue(len(cursos) > 0, 'Testando cursos')

def test_get_curso(self):
cursos = get_cursos()

self.assertIsNotNone(cursos, 'Discentes não é None?')
self.assertTrue(len(cursos) > 0, 'Testando cursos')
10 changes: 9 additions & 1 deletion core/tests/test_discente.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import django
django.setup()
from core.bo.discentes import get_discentes, get_discente_by_matricula, get_discentes_ativos
from core.bo.discentes import get_discentes, get_discente_by_matricula, get_discentes_ativos, get_qtd_discentes_ativos, get_discentes_by_centro
from core.tests.povoar_testes import criar_dados, remover_dados

from django.test import TestCase
Expand Down Expand Up @@ -34,8 +34,16 @@ def test_get_discentes(self):
self.assertIsNotNone(discentes, 'Discentes não é None?')
self.assertTrue(len(discentes) > 0, 'Existe pelo menos um discente')

def test_get_discentes_by_centro(self):
pass

def test_get_discentes_ativos(self):
discentes = get_discentes_ativos()

self.assertIsNotNone(discentes, 'Discentes não é None?')
self.assertTrue(len(discentes) > 0, 'Existe pelo menos um discente')

def test_get_qtd_discentes_ativos(self):
discentes = get_qtd_discentes_ativos()

self.assertIsNotNone(discentes, 'Quantidade de Discentes ativos não é None?')
10 changes: 5 additions & 5 deletions core/tests/test_enquetes.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import django
django.setup()

from core.bo.enquetes import get_enquetes, get_enquetes_por_curso, get_componentes_enquete
from core.bo.enquetes import get_enquetes, get_enquetes_por_curso, get_componentes_enquete, get_estrutura_by_curso
from core.tests.povoar_testes import criar_dados, remover_dados, criar_enquetes
from core.models import Enquete

Expand Down Expand Up @@ -31,15 +31,15 @@ def test_get_enquetes(self):
enquete = get_enquetes()

self.assertIsNotNone(enquete, 'Enquete não é None?')
self.assertTrue(len(enquete) > 0, 'Existe pelo menos uma enquete')

def test_get_enquetes_por_curso(self):
enquete = get_enquetes_por_curso(7191770)
enquete = get_enquetes_por_curso(9999)

self.assertIsNotNone(enquete, 'Enquete não é None?')
# self.assertEqual()
self.assertTrue(len(enquete) > 0, 'Existe pelo menos uma enquete')

def test_get_componentes_enquete(self):
enquete = get_enquetes_por_curso(7191770)
print(enquete)
pass


28 changes: 28 additions & 0 deletions core/tests/test_flow_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,31 @@ def test_get_flow(self):
response = client.get(url)

self.assertEqual(200, response.status_code)

def test_get_flow_contabeis(self):
client = Client()
url = reverse('flow_cont_op')
response = client.get(url)

self.assertEqual(200, response.status_code)

def test_get_flow_direito(self):
client = Client()
url = reverse('flow_dir_op')
response = client.get(url)

self.assertEqual(200, response.status_code)

def test_get_flow_geo(self):
client = Client()
url = reverse('flow_geo_lic_op')
response = client.get(url)

self.assertEqual(200, response.status_code)

def test_get_flow_mat(self):
client = Client()
url = reverse('flow_mat_op')
response = client.get(url)

self.assertEqual(200, response.status_code)
14 changes: 7 additions & 7 deletions core/tests/test_historico.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ def test_add_historico(self):

self.assertIsNotNone(historico, 'Histórico não é None?')
self.assertIsNotNone(historico.pk, 'Histórico pk não é None?')
self.assertEquals('20209876543', historico.discente.matricula, 'Recuperar matrícula do histórico')
self.assertEquals('Zé Silva', historico.discente.nome_discente, 'Recuperar nome discente do histórico')
self.assertEquals('DCT9999', historico.componente.codigo, 'Recuperar código componente do histórico')
self.assertEquals('BANCO DE DADOS', historico.componente.nome, 'Recuperar nome componente do histórico')
self.assertEqual('20209876543', historico.discente.matricula, 'Recuperar matrícula do histórico')
self.assertEqual('Zé Silva', historico.discente.nome_discente, 'Recuperar nome discente do histórico')
self.assertEqual('DCT9999', historico.componente.codigo, 'Recuperar código componente do histórico')
self.assertEqual('BANCO DE DADOS', historico.componente.nome, 'Recuperar nome componente do histórico')

historicos = listar_historicos()
print(historicos)
self.assertEquals(1, len(historicos))
self.assertEqual(1, len(historicos))

historicos = listar_historicos_by_discente(discente=discente)
print(historicos)
self.assertEquals(1, len(historicos))
self.assertEqual(1, len(historicos))


excluir_historico(discente=discente, componente=componente)
self.assertEquals(1, len(historicos))
self.assertEqual(1, len(historicos))
26 changes: 26 additions & 0 deletions core/tests/test_profile_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import django
django.setup()

from core.forms import HistoricoForm
from unittest.case import TestCase

from django.contrib.auth.models import User
from django.test import Client, SimpleTestCase

from core.tests.povoar_testes import criar_dados, remover_dados


class ProfileViewTests(TestCase):

@classmethod
def setUpClass(cls):
super().setUpClass()
print('\nProfileViewTests')
criar_dados()

@classmethod
def tearDownClass(cls):
super().tearDownClass()
remover_dados()


56 changes: 56 additions & 0 deletions core/tests/test_sugestao_geografia_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import django
django.setup()

from unittest.case import TestCase

from django.contrib.auth.models import User
from django.test import Client
from django.urls import reverse

from core.models import SugestaoTurma
from core.tests.povoar_testes import criar_dados, remover_dados

class SugestaoGeografiaViewTests(TestCase):

@classmethod
def setUpClass(cls):
super(SugestaoGeografiaViewTests, cls).setUpClass()
print('\nSugestaoGeografiaViewTests')
criar_dados()

@classmethod
def tearDownClass(cls):
super().tearDownClass()
remover_dados()

def test_sugestao_detalhar(self):
client = Client()
sugestao = SugestaoTurma.objects.get(codigo_turma='01', componente__id_componente=99999)

url = reverse('sugestao_detalhar', args=(sugestao.pk,))
response = client.get(url)

self.assertEqual(200, response.status_code)

def sugestao_geo_bac_manter(self):
client = Client()
sugestao = SugestaoTurma.objects.get(codigo_turma='01', componente__id_componente=99999)

url = reverse('sugestao_geo_bac_incluir', args=(sugestao.pk,))
url2 = '/core/sugestao/geo-bac/incluir' + sugestao.pk.__str__() + '/'
response = client.get(url2)
self.assertEqual(302, response.status_code)

def test_login_success(self):
client = Client()
user = User.objects.get(username='john')
response = client.post(reverse('Login de Usuário'), {'username': user.username, 'password': 'johnpassword'})
self.assertEqual(response.url, reverse('index'))
self.assertEqual(302, response.status_code)

def test_get_turmas_(self):
client = Client()
url = reverse('turmas_historia_lic')
response = client.get(url)

self.assertEqual(200, response.status_code)
7 changes: 7 additions & 0 deletions core/tests/test_sugestao_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,10 @@ def test_login_success(self):
response = client.post(url, {'username': user.username, 'password': 'johnpassword'})
self.assertEqual(response.url, index)
self.assertEqual(302, response.status_code)

def test_solicitacao_listar(self):
client = Client()
response = client.get('core/sugestao/solicitacao_listar')

self.assertEqual(response.status_code, 404)

Loading
Loading