рдПрдХ Django рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ .pre-рдкреНрд░рддрд┐рдмрджреНрдз рд╣реБрдХ рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рдирд╛

рдЕрдЪреНрдЫрд╛ рджрд┐рди!

рдореЗрд░рд╛ рдирд╛рдо рдПрдВрдбреНрд░реА рд╕реЛрдмреЛрд▓реЗрд╡ рд╣реИ рдФрд░ рдЖрдЬ рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреИрд╕реЗ рд╣рдордиреЗ рдЕрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдкрд░ .pre-рдкреНрд░рддрд┐рдмрджреНрдз рд╣реБрдХ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ред

рдкрд░рд┐рдЪрдп


рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣реБрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд╢рдмреНрдж рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рд╣реИрдВ рдФрд░ рдЙрдирдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реЛ рд╕рдХрддреА рд╣реИред рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдЧреЗрдЯ рдПрдХ рдЙрдкрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдХрд┐рд╕реА рдШрдЯрдирд╛ рдХреЗ рд╣реЛрдиреЗ рдкрд░ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рд╕рд░реНрд╡рд░ рдХреЛ рдзрдХреЗрд▓рдирд╛ рдЖрджрд┐) рдЖрдкрдХреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЪрд▓рд╛ рд╕рдХрддрд╛ рд╣реИред

рдкреНрд░реА-рдХрдорд┐рдЯ рдбрд┐рдлреЙрд▓реНрдЯ рдЧрд┐рдЯ рдкреНрд░реА-рдХрдорд┐рдЯ рд╣реБрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдРрдб-рдСрди рд╣реИ рдЬреЛ рд╡рд░реНрдгрд┐рдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреЛ рдЪрд▓рд╛рддрд╛ рд╣реИред .pre-рдкреНрд░рддрд┐рдмрджреНрдз-config.yaml рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗред рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдпрд╣ рд╕рд░рд▓ рд▓рдЧрддрд╛ рд╣реИ, рдЪрд▓реЛ рдЕрднреНрдпрд╛рд╕ рдХрд░реЗрдВред

рд╕реНрдерд╛рдкрдирд╛


рдЖрд╡рд╢реНрдпрдХ рдирд┐рд░реНрднрд░рддрд╛рдПрдБ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ:

pre-commit
#   https://pre-commit.com/

autoflake
#     (  )
black
#  
pyupgrade
#     
reorder-python-imports
#   
yesqa
#   noqa  ( )

# 
flake8
flake8-annotations
flake8-annotations-coverage
flake8-bandit
flake8-broken-line
flake8-bugbear
flake8-builtins
flake8-commas
flake8-comprehensions
flake8-debugger
flake8-eradicate
flake8-executable
flake8-fixme
flake8-future-import
flake8-pyi
flake8-pytest
flake8-pytest-style
flake8-mutable
flake8-string-format
flake8-todo
flake8-unused-arguments

# 
pytest

рдореИрдВ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рдлреНрд▓реИрдХ -8 рдФрд░ рд▓рд┐рдВрдЯрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдкрдиреА рд░рд╛рдп рд╡реНрдпрдХреНрдд рдХрд░реВрдВрдЧрд╛ред рдпрджрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ рд╡рд┐рд░рд╛рд╕рдд рдХреЛрдб рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреЗ рд╕рд╛рде рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рдмрдбрд╝реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╣реИ, рддреЛ рдЖрдк рд╕реБрд░рдХреНрд╖рд┐рдд рд░реВрдк рд╕реЗ рд▓рд┐рдВрдЯрд░ рдХреЛ рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВред "рдЖрджрд░реНрд╢ рдХреЛ рд▓рд╛рдиреЗ" рдкрд░ рдЦрд░реНрдЪ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рд▓рд╛рдЧрдд, рдЕрдзрд┐рдХрд╛рд░реА рд╕рд░рд╛рд╣рдирд╛ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рд╣рдо рдирдП (рдФрд░ рдЫреЛрдЯреЗ) рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдЯрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВред рдореИрдВ рджреЛрд╣рд░рд╛рддрд╛ рд╣реВрдВ, рдпрд╣ рдореЗрд░реА рдирд┐рдЬреА рд░рд╛рдп рд╣реИ, рдореИрдВ рдЗрд╕реЗ рдХрд┐рд╕реА рдкрд░ рдереЛрдкрддрд╛ рдирд╣реАрдВ рд╣реВрдВред

рдкрд░реНрдпрд╛рд╡рд░рдг рдПрдХреАрдХрд░рдг


рд╣рдо рд╡рд┐рдХрд╛рд╕ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреА рдореВрд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрджреЗрд╢реЛрдВ рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ

$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
$ pre-commit --version
pre-commit 2.4.0

рдпрджрд┐ .pre-рдкреНрд░рддрд┐рдмрджреНрдз sqlite рдкрд░ рд╢рдкрде рд▓реЗрдЧрд╛, рддреЛ рдЖрдкрдХреЛ рдЗрд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП $ yum sqlite рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ) рдФрд░ рдлрд┐рд░ рд╕реЗ рдЕрдЬрдЧрд░ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВ

.Pre-рдкреНрд░рддрд┐рдмрджреНрдз-config.yaml рдлрд╝рд╛рдЗрд▓ рд╕реЗрдЯ рдХрд░рдирд╛


рд╡рд╛рддрд╛рд╡рд░рдг рдХреА рд░реВрдЯ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ, .pre-рдкреНрд░рддрд┐рдмрджреНрдз-config.yaml рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдБ

- repo: https://github.com/pre-commit/pre-commit-hooks
  rev: "v2.5.0"
  hooks:
    - id: check-merge-conflict
    - id: debug-statements

- repo: local

  hooks:
    - id: black
      name: black
      entry: black
      language: system
      types: [python]
      args: [--line-length=200, --target-version=py37]

    - id: autoflake
      name: autoflake
      entry: autoflake
      language: system
      types: [python]
      args: [--in-place, --remove-all-unused-imports, --remove-duplicate-keys]

    # -   id: flake8
    #     name: flake8
    #     entry: flake8
    #     language: system
    #     types: [python]
    #     args: [
    #         "--ignore=E203,W503,FI10,FI11,FI12,FI13,FI14,FI15,FI16,FI17,FI58,PT013",
    #         # black
    #             # E203 whitespace before ':'
    #             # W503 line break before binary operator
    #         # flake8-future-import
    #             # FI10 __future__ import "division" missing
    #             # FI11 __future__ import "absolute_import" missing
    #             # FI12 __future__ import "with_statement" missing
    #             # FI13 __future__ import "print_function" missing
    #             # FI14 __future__ import "unicode_literals" missing
    #             # FI15 __future__ import "generator_stop" missing
    #             # FI16 __future__ import "nested_scopes" missing
    #             # FI17 __future__ import "generators" missing
    #             # FI58 __future__ import "annotations" present
    #         # flake8-pytest-style
    #             # PT013 found incorrect import of pytest, use simple 'import pytest' instead
    #         "--max-line-length=110",
    #         "--per-file-ignores=tests/*.py:S101"
    #         # S101 Use of assert detected
    #     ]

    - id: pyupgrade
      name: pyupgrade
      entry: pyupgrade
      language: system
      types: [python]
      args: [--py37-plus]

    - id: reorder-python-imports
      name: reorder-python-imports
      entry: reorder-python-imports
      language: system
      types: [python]
      args: [--py37-plus]

    - id: yesqa
      name: yesqa
      entry: yesqa
      language: system
      types: [python]

    - id: tests
      name: Run tests
      entry: "bash tests.sh"
      language: system
      verbose: true


рдЯреЗрд╕реНрдЯ


рдХреЛрдб рдХреА рдЬрд╛рдБрдЪ рдФрд░ рдкреНрд░рд╛рд░реВрдкрдг рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдкреНрд░рддрд┐рдмрджреНрдз рдмрдирд╛рдиреЗ рдХреЗ рдЪрд░рдг рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВрдЧреЗред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо pytest (https://docs.pytest.org/en/latest/) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ рдФрд░ рдЗрд╕реЗ рдЕрдкрдиреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВрдЧреЗред

рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЗ рд░реВрдЯ рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдореЗрдВ, рдкрд░реАрдХреНрд╖рдг рдлрд╝реЛрд▓реНрдбрд░ рдмрдирд╛рдПрдВ рдФрд░ рдирд┐рдореНрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ
рд░рдЦреЗрдВ test_example_without_db.py, test_example_with_db.py,

рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП, рдкрд░реАрдХреНрд╖рдг рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ рддрд╛рдХрд┐ рдЖрдк рд╡рд░реНрддрдорд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХреЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд▓рдбрд╝рд╛рдИ рд╕рд░реНрд╡рд░ рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреА рдПрдХ рдкреНрд░рддрд┐), рдФрд░ рд╣рд░ рдмрд╛рд░ рдПрдХ рдирдпрд╛ рдирд╣реАрдВ рдмрдирд╛рдПрдВред ред

рд╕рд░рд▓ рдкрд░реАрдХреНрд╖рдг test_example_without_db.py

def inc(x):
    return x + 1

def test_answer():
    assert inc(3) == 4

рд╕рд░рд▓ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ, рд╣рдо рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рд╡реЗрдмрдмреЛрдЯ рд╕реЗ рдЬреБрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд░реАрдХреНрд╖рдХ рдХреЗ рдореИрдиреБрдЕрд▓ рдХрд╛рдо рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рдкреНрд░рдгрд╛рд▓реА рдХреЗ рдиреЛрдбреНрд╕ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред Test_example_with_db.py

рдбреЗрдЯрд╛рдмреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХрд░реЗрдВ

import pytest
from chat.models import ChatRoom
from settings import POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD, \
                    POSTGRES_HOST, POSTGRES_PORT

@pytest.fixture(scope='session')
def django_db_setup():
    settings.DATABASES['default'] = {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': POSTGRES_DB,
        'USER': POSTGRES_USER,
        'PASSWORD': POSTGRES_PASSWORD,
        'HOST': POSTGRES_HOST,
        'PORT': POSTGRES_PORT,
    }   
    
    
@pytest.fixture
def db_access_without_rollback_and_truncate(request, django_db_setup, django_db_blocker):
    django_db_blocker.unblock()
    request.addfinalizer(django_db_blocker.restore)

def chat():
    return ChatRoom.objects.all().count()

@pytest.mark.django_db
def test_chat():
    assert chat() > 0

рдЙрджрд╛рд╣рд░рдг рдХрд╛рдлреА рдХреГрддреНрд░рд┐рдо рд╣реИ рдФрд░ рдЗрд╕ рдиреЛрдЯ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА рдпрд╣ рд╣рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдФрд░ рдЬрдЯрд┐рд▓ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХрд╛ рд╕рдВрдЪрд╛рд▓рди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдореИрдиреНрдпреБрдЕрд▓ рдкрд░реАрдХреНрд╖рдг рд╕реЗ рдкрд░реЗ рд╣реИрдВред

рд╣рдо .pre-рдкреНрд░рддрд┐рдмрджреНрдз рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рд╢рд╛рдорд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ


рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреА рдореВрд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдПрдХ рд╢реЗрд▓ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо test.sh рдХрд╣реЗрдВрдЧреЗ:

source ../../python38_env/bin/activate && python -m pytest -v tests

рдЗрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡рд░реНрдЪреБрдЕрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдХреА рд╕рдХреНрд░рд┐рдпрддрд╛ рдХреЛрдб рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд▓рд┐рдЦреА рдЧрдИ рд╣реИред рдпрд╣ рдЕрд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдЖрдкрдХреА рдЯреАрдо рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпрд╕реНрдерд╛рдиреЛрдВ рдкрд░ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛ рд░рд╣реА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрд┐рд╕рдиреЗ рд╕реНрдерд╛рдиреАрдп рдорд╢реАрди рдкрд░ рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЛ рддреИрдирд╛рдд рдХрд┐рдпрд╛ рд╣реИ, рдФрд░ рдХреЛрдИ рд╡реНрдпрдХреНрддрд┐ рд╕рд░реНрд╡рд░ рдкрд░ рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрддрд╛ рд╣реИ)ред

рдЖрдк .env рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдЪрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ :

github.com/Sobolev5/starlette-vue-backend/blob/master/.env.example (рдЪрд░ ENV_ACTACTATE рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ)

github.com/Sobolev5/starlette-vue-backend /blob/master/tests.sh (рдкрд░реНрдпрд╛рд╡рд░рдг рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░реЗрдВ рдФрд░ рд╕рдХреНрд░рд┐рдп рдХрд░реЗрдВ)

рдПрдХ рдХрдорд┐рдЯ рдмрдирд╛рдПрдБ


рдЕрдм рдпрд╣ рдПрдХ рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рдмрдирд╛рдиреЗ рдФрд░ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ

$ git add .
$ git commit -m Sobolev:TestPreCommitHook
Check for merge conflicts................................................Passed
Debug Statements (Python)................................................Passed
black....................................................................Failed
- hook id: black
- files were modified by this hook

reformatted /var/www/file.py
All done!   
1 file reformatted, 2 files left unchanged.

autoflake................................................................Passed
pyupgrade................................................................Passed
reorder-python-imports...................................................Failed
- hook id: reorder-python-imports
- exit code: 1
- files were modified by this hook

Reordering imports in file.py

yesqa....................................................................Passed
Run tests................................................................Passed
- hook id: tests
- duration: 2.85s

tests/test_example_with_db.py::test_chat PASSED                          [ 66%]
tests/test_example_without_db.py::test_answer PASSED                     [100%]

рдПрдХ рдХрдорд┐рдЯ рдЕрдм рджреЛ рдЪрд░рдгреЛрдВ рдореЗрдВ рдмрдирд╛рдИ рдЧрдИ рд╣реИред рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ, рд╣реБрдХ рдХреЛрдб рдХреЛ рдкреНрд░рд╛рд░реВрдкрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЙрдирдХреЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдореЗрдВ рдмрд╕ рдЖрджреЗрд╢реЛрдВ рдХреЛ "рджреЛрд╣рд░рд╛рдиреЗ" рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд░рдо рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИред

$ git add .
$ git commit -m Sobolev:TestPreCommitHook
$ git add .
$ git commit -m Sobolev:TestPreCommitHook

рдпрд╣ рд╕рдм, рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

Sitelinks рдХреЗ


тЖТ рд╣реБрдХ рдХреА рдкреВрд░реА рд╕реВрдЪреА

All Articles