Skip to content

Commit 8beb7ed

Browse files
committed
fix: code pylint
1 parent 1ee94ff commit 8beb7ed

File tree

5 files changed

+124
-46
lines changed

5 files changed

+124
-46
lines changed

.github/workflows/pylint.yml

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@ name: Pylint
33
on: [push]
44

55
jobs:
6-
build:
6+
lint:
77
runs-on: ubuntu-latest
8-
strategy:
9-
matrix:
10-
python-version: ["3.10"]
118
steps:
12-
- uses: actions/checkout@v4
13-
- name: Set up Python ${{ matrix.python-version }}
14-
uses: actions/setup-python@v3
15-
with:
16-
python-version: ${{ matrix.python-version }}
17-
- name: Install dependencies
18-
run: |
19-
python -m pip install --upgrade pip
20-
pip install pylint
21-
- name: Analysing the code with pylint
22-
run: |
23-
pylint $(git ls-files '*.py')
9+
- name: Checkout code
10+
uses: actions/checkout@v4
11+
12+
- name: Set up Python 3.10
13+
uses: actions/setup-python@v3
14+
with:
15+
python-version: "3.10"
16+
17+
- name: Install dependencies
18+
run: |
19+
python -m pip install --upgrade pip
20+
pip install pylint
21+
22+
- name: Analyse the code with pylint
23+
run: |
24+
pylint $(git ls-files '*.py')

config/db_config.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
"""
2+
Este módulo contém uma função para criar uma conexão com o banco de dados PostgreSQL.
3+
"""
4+
15
from sqlalchemy import create_engine
26

7+
38
def connect_to_db():
9+
"""
10+
Cria e retorna um objeto de conexão com o banco de dados PostgreSQL.
11+
12+
:return: Objeto de conexão do SQLAlchemy.
13+
"""
414
database_url = "postgresql://postgres:123456@localhost:5432/lol"
5-
return create_engine(database_url)
15+
return create_engine(database_url)

tests/test_database.py

Lines changed: 76 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,151 @@
1-
import pytest
1+
"""
2+
Testes automatizados para validar a integridade e qualidade dos dados na tabela '2024_lol_esports'.
3+
"""
4+
25
from utils.db_utils import execute_query
36
from utils.file_utils import load_query
47
from config.db_config import connect_to_db
58

69
engine = connect_to_db()
710

11+
812
class TestLolEsports:
13+
"""
14+
Classe de testes para validar dados da tabela '2024_lol_esports'.
15+
"""
16+
917
def test_tabela_existe(self):
18+
"""
19+
Verifica se a tabela '2024_lol_esports' existe no banco de dados.
20+
"""
1021
query = load_query('check_table_exists')
1122
df = execute_query(engine, query)
1223
assert df['table_exists'][0], 'Tabela "2024_lol_esports" não existe!'
1324

1425
def test_colunas_existem(self):
26+
"""
27+
Verifica se as colunas esperadas estão presentes na tabela.
28+
"""
1529
expected_columns = [
16-
'gameid', 'datacompleteness', 'url', 'league', 'year', 'split', 'playoffs', 'date', 'game', 'patch', 'participantid',
17-
'side', 'position', 'playername', 'playerid', 'teamname', 'teamid', 'champion', 'ban1', 'ban2', 'ban3', 'ban4', 'ban5',
18-
'pick1', 'pick2', 'pick3', 'pick4', 'pick5', 'gamelength', 'result', 'kills', 'deaths', 'assists', 'teamkills',
19-
'teamdeaths', 'doublekills', 'triplekills', 'quadrakills', 'pentakills', 'firstblood', 'firstbloodkill',
20-
'firstbloodassist', 'firstbloodvictim', 'team kpm', 'ckpm', 'firstdragon', 'dragons', 'opp_dragons', 'elementaldrakes',
21-
'opp_elementaldrakes', 'infernals', 'mountains', 'clouds', 'oceans', 'chemtechs', 'hextechs', 'dragons (type unknown)',
22-
'elders', 'opp_elders', 'firstherald', 'heralds', 'opp_heralds', 'void_grubs', 'opp_void_grubs', 'firstbaron', 'barons',
23-
'opp_barons', 'firsttower', 'towers', 'opp_towers', 'firstmidtower', 'firsttothreetowers', 'turretplates',
24-
'opp_turretplates', 'inhibitors', 'opp_inhibitors', 'damagetochampions', 'dpm', 'damageshare', 'damagetakenperminute',
25-
'damagemitigatedperminute', 'wardsplaced', 'wpm', 'wardskilled', 'wcpm', 'controlwardsbought', 'visionscore', 'vspm',
26-
'totalgold', 'earnedgold', 'earned gpm', 'earnedgoldshare', 'goldspent', 'gspd', 'gpr', 'total cs', 'minionkills',
27-
'monsterkills', 'monsterkillsownjungle', 'monsterkillsenemyjungle', 'cspm', 'goldat10', 'xpat10', 'csat10', 'opp_goldat10',
28-
'opp_xpat10', 'opp_csat10', 'golddiffat10', 'xpdiffat10', 'csdiffat10', 'killsat10', 'assistsat10', 'deathsat10',
29-
'opp_killsat10', 'opp_assistsat10', 'opp_deathsat10', 'goldat15', 'xpat15', 'csat15', 'opp_goldat15', 'opp_xpat15',
30-
'opp_csat15', 'golddiffat15', 'xpdiffat15', 'csdiffat15', 'killsat15', 'assistsat15', 'deathsat15', 'opp_killsat15',
31-
'opp_assistsat15', 'opp_deathsat15', 'goldat20', 'xpat20', 'csat20', 'opp_goldat20', 'opp_xpat20', 'opp_csat20',
32-
'golddiffat20', 'xpdiffat20', 'csdiffat20', 'killsat20', 'assistsat20', 'deathsat20', 'opp_killsat20', 'opp_assistsat20',
33-
'opp_deathsat20', 'goldat25', 'xpat25', 'csat25', 'opp_goldat25', 'opp_xpat25', 'opp_csat25', 'golddiffat25', 'xpdiffat25',
34-
'csdiffat25', 'killsat25', 'assistsat25', 'deathsat25', 'opp_killsat25', 'opp_assistsat25', 'opp_deathsat25'
30+
'gameid', 'datacompleteness', 'url', 'league', 'year', 'split', 'playoffs', 'date',
31+
'game', 'patch', 'participantid', 'side', 'position', 'playername', 'playerid',
32+
'teamname', 'teamid', 'champion', 'ban1', 'ban2', 'ban3', 'ban4', 'ban5', 'pick1',
33+
'pick2', 'pick3', 'pick4', 'pick5', 'gamelength', 'result', 'kills', 'deaths',
34+
'assists', 'teamkills', 'teamdeaths', 'doublekills', 'triplekills', 'quadrakills',
35+
'pentakills', 'firstblood', 'firstbloodkill', 'firstbloodassist', 'firstbloodvictim',
36+
'team kpm', 'ckpm', 'firstdragon', 'dragons', 'opp_dragons', 'elementaldrakes',
37+
'opp_elementaldrakes', 'infernals', 'mountains', 'clouds', 'oceans', 'chemtechs',
38+
'hextechs', 'dragons (type unknown)', 'elders', 'opp_elders', 'firstherald', 'heralds',
39+
'opp_heralds', 'void_grubs', 'opp_void_grubs', 'firstbaron', 'barons', 'opp_barons',
40+
'firsttower', 'towers', 'opp_towers', 'firstmidtower', 'firsttothreetowers',
41+
'turretplates', 'opp_turretplates', 'inhibitors', 'opp_inhibitors', 'damagetochampions',
42+
'dpm', 'damageshare', 'damagetakenperminute', 'damagemitigatedperminute', 'wardsplaced',
43+
'wpm', 'wardskilled', 'wcpm', 'controlwardsbought', 'visionscore', 'vspm', 'totalgold',
44+
'earnedgold', 'earned gpm', 'earnedgoldshare', 'goldspent', 'gspd', 'gpr', 'total cs',
45+
'minionkills', 'monsterkills', 'monsterkillsownjungle', 'monsterkillsenemyjungle',
46+
'cspm', 'goldat10', 'xpat10', 'csat10', 'opp_goldat10', 'opp_xpat10', 'opp_csat10',
47+
'golddiffat10', 'xpdiffat10', 'csdiffat10', 'killsat10', 'assistsat10', 'deathsat10',
48+
'opp_killsat10', 'opp_assistsat10', 'opp_deathsat10', 'goldat15', 'xpat15', 'csat15',
49+
'opp_goldat15', 'opp_xpat15', 'opp_csat15', 'golddiffat15', 'xpdiffat15', 'csdiffat15',
50+
'killsat15', 'assistsat15', 'deathsat15', 'opp_killsat15', 'opp_assistsat15',
51+
'opp_deathsat15', 'goldat20', 'xpat20', 'csat20', 'opp_goldat20', 'opp_xpat20',
52+
'opp_csat20', 'golddiffat20', 'xpdiffat20', 'csdiffat20', 'killsat20', 'assistsat20',
53+
'deathsat20', 'opp_killsat20', 'opp_assistsat20', 'opp_deathsat20', 'goldat25',
54+
'xpat25', 'csat25', 'opp_goldat25', 'opp_xpat25', 'opp_csat25', 'golddiffat25',
55+
'xpdiffat25', 'csdiffat25', 'killsat25', 'assistsat25', 'deathsat25', 'opp_killsat25',
56+
'opp_assistsat25', 'opp_deathsat25'
3557
]
3658
query = load_query('check_columns_exist')
3759
df = execute_query(engine, query)['column_name'].tolist()
3860
missing = set(expected_columns) - set(df)
3961
assert not missing, f'Colunas ausentes: {missing}'
4062

4163
def test_campos_obrigatorios_nao_nulos(self):
64+
"""
65+
Verifica se os campos obrigatórios não possuem valores nulos.
66+
"""
4267
required_columns = ['gameid', 'league', 'year', 'playername', 'teamname', 'champion']
4368
for col in required_columns:
4469
query = load_query('check_no_nulls_in_required_columns').replace('{{column_name}}', col)
4570
df = execute_query(engine, query)
4671
assert df['null_count'][0] == 0, f'Coluna {col} contém valores nulos!'
4772

4873
def test_valores_nao_negativos(self):
74+
"""
75+
Verifica se não há valores negativos em métricas importantes.
76+
"""
4977
query = load_query('check_no_negative_values')
5078
df = execute_query(engine, query)
5179
assert df['negative_count'][0] == 0, 'Existem valores negativos em métricas!'
5280

5381
def test_times_vitoriosos(self):
82+
"""
83+
Verifica se há times registrados como vencedores.
84+
"""
5485
query = load_query('count_victorious_teams')
5586
df = execute_query(engine, query)
5687
assert df['victorious_teams'][0] > 0, 'Nenhum time registrado como vencedor!'
5788

5889
def test_numero_jogadores_unicos(self):
90+
"""
91+
Verifica se há jogadores únicos na tabela.
92+
"""
5993
query = load_query('count_unique_players')
6094
df = execute_query(engine, query)
6195
assert df['unique_players'][0] > 0, 'Não há jogadores únicos na tabela!'
6296

6397
def test_campeoes_mais_jogados(self):
98+
"""
99+
Verifica se há campeões registrados como os mais jogados.
100+
"""
64101
query = load_query('most_played_champions')
65102
df = execute_query(engine, query)
66103
assert not df.empty, 'Não há campeões registrados como mais jogados!'
67104

68105
def test_campeoes_nao_repetidos_em_uma_partida(self):
106+
"""
107+
Verifica se não há campeões repetidos em partidas.
108+
"""
69109
query = load_query('unique_champions_per_game')
70110
df = execute_query(engine, query)
71111
assert df['repeated_champions'].empty, 'Há campeões repetidos em partidas!'
72112

73113
def test_time_com_maior_media_de_kills(self):
114+
"""
115+
Verifica qual time tem a maior média de kills.
116+
"""
74117
query = load_query('team_highest_avg_kills')
75118
df = execute_query(engine, query)
76119
assert not df.empty, 'Nenhum time encontrado com maior média de kills!'
77120

78121
def test_duracao_media_de_jogos(self):
122+
"""
123+
Verifica se a duração média dos jogos é válida.
124+
"""
79125
query = load_query('average_game_length')
80126
df = execute_query(engine, query)
81127
assert df['average_length'][0] > 0, 'A duração média dos jogos é inválida!'
82128

83129
def test_jogadores_com_mais_de_uma_pentakill(self):
130+
"""
131+
Verifica se há jogadores com múltiplas pentakills registradas.
132+
"""
84133
query = load_query('players_multiple_pentakills')
85134
df = execute_query(engine, query)
86135
assert not df.empty, 'Nenhum jogador possui múltiplas pentakills registradas!'
87136

88137
def test_primeiro_sangue_registrado(self):
138+
"""
139+
Verifica se há registro de First Blood nas partidas.
140+
"""
89141
query = load_query('games_with_first_blood')
90142
df = execute_query(engine, query)
91143
assert df['games_with_first_blood'][0] > 0, 'Nenhuma partida possui First Blood registrado!'
92144

93145
def test_vitorias_por_lado(self):
146+
"""
147+
Verifica se há vitórias registradas para ambos os lados (azul e vermelho).
148+
"""
94149
query = load_query('victories_by_side')
95150
df = execute_query(engine, query)
96-
assert df['blue_wins'][0] > 0 and df['red_wins'][0] > 0, 'Não há registro de vitórias para ambos os lados!'
151+
assert df['blue_wins'][0] > 0 and df['red_wins'][0] > 0, 'Não há registro de vitórias'

utils/db_utils.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1+
"""
2+
Este módulo contém utilitários para interagir com bancos de dados usando SQLAlchemy e Pandas.
3+
"""
4+
15
import pandas as pd
26
from sqlalchemy.engine import Engine
37

8+
49
def execute_query(engine: Engine, query: str, params: dict = None) -> pd.DataFrame:
510
"""
611
Executa uma consulta SQL e retorna os resultados como DataFrame.
7-
:param engine: Objeto de conexão do SQLAlchemy
8-
:param query: Consulta SQL
9-
:param params: Parâmetros opcionais para a consulta
10-
:return: DataFrame com os resultados
12+
13+
:param engine: Objeto de conexão do SQLAlchemy.
14+
:param query: Consulta SQL.
15+
:param params: Parâmetros opcionais para a consulta.
16+
:return: DataFrame com os resultados.
1117
"""
1218
with engine.connect() as conn:
1319
return pd.read_sql_query(query, conn, params=params)

utils/file_utils.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1+
"""
2+
Este módulo contém utilitários para carregar queries SQL de arquivos.
3+
"""
4+
15
import os
26

7+
38
def load_query(query_name: str) -> str:
49
"""
510
Carrega o conteúdo de um arquivo SQL da pasta de queries.
6-
:param query_name: Nome do arquivo SQL sem a extensão
7-
:return: Conteúdo da query como string
11+
12+
:param query_name: Nome do arquivo SQL sem a extensão.
13+
:return: Conteúdo da query como string.
814
"""
915
base_dir = os.path.dirname(os.path.abspath(__file__))
1016
queries_dir = os.path.join(base_dir, '../queries')
1117
query_path = os.path.join(queries_dir, f'{query_name}.sql')
12-
18+
1319
if not os.path.exists(query_path):
1420
raise FileNotFoundError(f'Query "{query_name}.sql" não encontrada!')
15-
21+
1622
with open(query_path, 'r', encoding='utf-8') as file:
1723
return file.read()

0 commit comments

Comments
 (0)