{"id":22273498,"url":"https://github.com/dfleta/kata_tdd_pytest","last_synced_at":"2025-07-28T14:32:04.503Z","repository":{"id":94648373,"uuid":"306082200","full_name":"dfleta/kata_tdd_pytest","owner":"dfleta","description":"Kata TDD con pytest","archived":false,"fork":false,"pushed_at":"2024-10-24T12:47:18.000Z","size":130,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-10-25T14:03:06.038Z","etag":null,"topics":["ci-cd","coverage","kata","pytest","pytest-markers","tdd","tdd-kata","tox"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dfleta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-10-21T16:21:08.000Z","updated_at":"2024-10-24T13:57:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"f54d692b-f809-4b6d-bd45-5501e6aaa303","html_url":"https://github.com/dfleta/kata_tdd_pytest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fkata_tdd_pytest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fkata_tdd_pytest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fkata_tdd_pytest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dfleta%2Fkata_tdd_pytest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dfleta","download_url":"https://codeload.github.com/dfleta/kata_tdd_pytest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227922947,"owners_count":17840940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ci-cd","coverage","kata","pytest","pytest-markers","tdd","tdd-kata","tox"],"created_at":"2024-12-03T13:12:49.325Z","updated_at":"2024-12-03T13:12:50.126Z","avatar_url":"https://github.com/dfleta.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kata TDD con Pytest y markers\n\nCómo utilizar `pytest.ini`y los `markers` para configurar los casos test.\n\n## pytest\n\n[Diferencias entre pip y pip3](https://www.pythonpool.com/pip-vs-pip3/#:~:text=PIP%20Vs%20PIP3%20What's%20the%20Difference%3F,-PIP\u0026text=PIP%20is%20a%20soft%20link,in%20the%20system%20PATH%20variable)\n\n[Instalar pytest](https://docs.pytest.org/en/latest/getting-started.html#install-pytest)\n\n[pip install](https://pip.pypa.io/en/stable/cli/pip_install/)\n\nCrea un entorno virtual:\n\n`python3 -m venv venv`\n\ny actívalo (este es el comando en Linux / MacOSX):\n\n`source venv/bin/activate`\n\nInstala pytest:\n\n```bash\n(venv) $ pip3 install -U pytest\n(venv) $ pytest --version\npytest 7.1.3\n```\n\nSi quieres una salida por consola mejor formateada, instala el paquete `pytest-sugar`.\n\n`(venv) $ pip3 install pytest-sugar`\n\nSeleccionar determinados test por nombre del fichero:\n\n```bash\n$ pytest -k \"test_b_c_nulo\"\ncollected 12 items / 11 deselected / 1 selected                                   test/test_b_c_nulo.py .\n```\n\nInvocar pytets como módulo de Python:\n\n`python -m pytest [...]`\n\n## Trabajar con custom markers\n\n### Marking test functions y seleccionarlas para ejecutarse\n\nhttps://docs.pytest.org/en/latest/example/markers.html#mark-examples\n\nSeparar el código en directorios `src` y `test`\n\nEn cada uno de esos dos directorios situar un fichero `__init__.py` vacío para indicar que son módulos (sic)\n\n### Registrar markers para cada test en la suite\n\nEn el raíz del proyecto, situar el fichero `pytest.ini` y escribir nombre del marker y su descripción (opcional) tras los `:`\n\n```ini\n    [pytest]\n    markers =\n        division_cero: coeficiente a es 0\n```\n\nEn cada módulo /fichero correspondiente a los test de cada módulo `test_xxx.py` importar `pytest` para utilizar los decoradores `@pytest.mark`\n\n```python\nimport pytest\n\n@pytest.mark.division_cero\ndef test_division_por_cero():\n    assert raiz_ecuacion_segundo_grado(0, 1, 1) == None\n```\n\n#### Seleccionar el test por marker\n\nSeleccionar el test o `marker`:\n\n```bash\n$ pytest -v -m \"division_cero\"\n==================================== test session starts ===============================\nplatform linux -- Python 3.6.9, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- /usr/bin/python3\ncachedir: .pytest_cache\nrootdir: /home/david/Escritorio/Programacion/codigo/square_test, configfile: pytest.ini\ncollected 3 items / 2 deselected / 1 selected                                                                      \n\ntest/square_root_test.py::test_division_por_cero PASSED                                                      [100%]\n\n================== 1 passed, 2 deselected in 0.01s ======================\n# observar que sólo ha seleccionado 1\n```\n\nUna vez creados los `markers` y registrados en `pytest.ini` , obtenemos una lista de ellos:\n\n`$ pytest --markers`\n\n#### Seleccionar el test por nombre\n\nEmpleamos `-k` para seleccionar los test según su nombre.\n\n`$ pytest -k \"discriminante_cero\"`\n\nO a la inversa, ejecutar todos los tests excepto este:\n\n`$ pytest -k \"not discriminante_cero\"`\n\n\n## Coverage\n\nRecuerda tener activado el entorno virtual.\n\nhttps://coverage.readthedocs.io/en/latest\n\n`$ pip3 install coverage`\n\n`$ coverage run -m pytest`\n\n#### Data file\nCoverage.py collects execution data in a file called “.coverage”\n\n#### Sólo analizar el dir source indicado\n\n`$ coverage run --source ./src -m pytest`\n\n--source creo que se ve sobreescrito por la configuración exclude o include en el fichero de configuración `.coveragerc`\n\nComo invoco coverage llamando al módulo pytest, sólo se analizan los ficheros de código que son ejecutados por los casos test.\n\n#### Excluir líneas de código\n\nhttps://coverage.readthedocs.io/en/latest/excluding.html\n\nVer el fichero `.coveragerc`\n\nPuede moverse al fichero de configuración del proyecto `pyproject.toml` si se instala `coverage` de modo:\n\nhttps://coverage.readthedocs.io/en/latest/config.html#config\n\n`pip install coverage[toml]`\n\n\n##### para ver el report\n\n`$ coverage report`\n\nPara saber qué lineas no se han ejecutado:\n\n`$ coverage report -m`\n\n\n#### Anotar el código\n\n`$ coverage annotate -d ./coverage_annotation`\n\nAntes has de ejecutar:\n\n`$ coverage run --source ./src -m pytest`\n\nProduce un texto anotado del código fuente. Con `-d` especificamos un directorio de salida para el fichero con el código anotado. Sin `-d`, los ficheros anotados son escritos en el directorio original del fichero Python.\n\nCoverage status for each line of source is indicated with a character prefix:\n\n    \u003e executed\n    ! missing (not executed)\n    - excluded\n\n\nSi seguimos este flujo de trabajo:\n\n`$ pytest -m b_nulo`\n\n`$ coverage run --source ./src -m pytest -m b_nulo`\n\n`$ coverage annotate -d ./coverage_annotation`\n\nconseguimos ver en las anotaciones del código sólo el **backward slice** del código que ha sido ejecutado para pasar el caso test del marker indicado.\n\nEs mejor esto que el report, ya que leo si se ha cubierto el código que estoy testeando bajo ese caso test específico.\n\n### Coverage en VSCode\n\nDesde la versión 1.94.0 de VSCode puedes ejecutar las tareas de testing y cobertura de código desde la barra lateral.\n\nEjecutar Python tests con coverage:\n\nhttps://code.visualstudio.com/docs/editor/testing#_test-coverage\n\nInformación general information sobre test coverage en la documentación sobre VSCode's Test Coverage:\n\nhttps://code.visualstudio.com/docs/python/testing#_run-tests-with-coverage\n\n**Es necesario instalar la extensión `pytest-cov` de pytest** desde consola:\n\n`(venv) $ pip3 install pytest-cov`\n\nhttps://pytest-cov.readthedocs.io/en/latest/readme.html#installation\n\n#### Uso:\n\n\u003e To run tests with coverage, select the coverage run icon in the Test Explorer or “Run with coverage” from any menu you normally trigger test runs from. The Python extension will run coverage by using the `pytest-cov` plugin if you are using pytest, or with `coverage.py` for unittest.\nOnce the coverage run is complete, lines are highlighted in the editor for line level coverage.\n\nDESDE CLI:\n\n`(venv) $ pytest --cov=src test/`\n\ndonde `src` es el directorio con el código a testear (y medir su cobertura) y `test` el directorio con los casos test.\n\n\n## Code formatter\n\nBlack\n\nhttps://pypi.org/project/black/\n\n`$ black [source_file_or_directory]`\n\nBlack code style:\n\nhttps://pypi.org/project/black/\n\n### Configuration format\n\nBlack usa `pyproject.toml` que es un TOML file. La ventaja de usar este fichero es que sirve de punto de configuración para muchas de las herramientas que estoy usando: coverage, tox, black.\n\nIt contains separate sections for different tools. Black is using the [tool.black] section. The option keys are the same as long names of options on the command line.\n\nNote that you have to use single-quoted strings in TOML for regular expressions. It's the equivalent of r-strings in Python. Multiline strings are treated as verbose regular expressions by Black. Use [ ] to denote a significant space character.\n\nVer fichero\n\n```toml\n[tool.black]\nline-length = 88\ntarget-version = ['py36', 'py37', 'py38']\ninclude = '\\.pyi?$'\nexclude = '''\n/(\n    \\.eggs\n  | \\.git\n  | \\.hg\n  | \\.mypy_cache\n  | \\.tox\n  | \\.venv\n  | \\.vscode\n  | _build\n  | buck-out\n  | build\n  | dist\n  | venv\n  # The following are specific to Black, you probably don't want those.\n  | blib2to3\n  | tests/data\n  | profiling\n)/\n'''\n```\n\n\n## TOX\n\n![Tox flow](./tox_flow.png)\n\n\nWorkflow de Tox:\n\nhttps://tox.readthedocs.io/en/latest/index.html\n\nPaso a paso aquí:\n\nhttps://tox.readthedocs.io/en/latest/example/basic.html\n\n\n1. Creamos un entorno virtual, lo activamos y chequeamos las dependencias que se instalan:\n\n    ```bash\n    $ python3.6 -m venv venv\n    $ source venv/bin/activate\n    (venv) $ pip3 list\n    pip (9.0.1)\n    pkg-resources (0.0.0)\n    setuptools (39.0.1)\n    ```\n\n2. Instalamos `pytest` y `tox` (no las `setuptools` que ya han sido instaladas al crear el entorno virtual):\n\n    https://pip.pypa.io/en/stable/reference/pip_install/\n\n    https://tox.readthedocs.io/en/latest/\n\n\n    ```bash\n    (venv) $ python3.6 -m pip install pytest\n    (venv) $ python3.6 -m pip install tox\n\n    (venv) $ pip3 list |  grep tox\n    ```\n\n3. Crear `requirements.txt`\n\n   `(venv) $ pip3 freeze \u003e requirements.txt`\n\n4. Crear `setup.py`.\n   Usar como template este: https://github.com/dfleta/api-rest-gildedrose/blob/master/setup.py e incluir las dependencias del fichero `requirements.txt` anterior.\n\n   Eliminar la dependencia `pkg-resources==0.0.0` porque es un bug de pip.\n\n5. Crear un fichero `tox.ini` con la configuración en la raíz del proyecto:\n\n    ```ini\n    # content of: tox.ini , put in same dir as setup.py\n    [tox]\n    envlist = py36\n    # los interpretes a utilizar han de estar instalados en la máquina\n    [testenv]\n    # install testing framework\n    # ... or install anything else you might need here\n    deps =\n            -rrequirements.txt\n    # run the tests\n    # ... or run any other command line tool you need to run here\n    commands = pytest\n    ```\n\n6. Invocar `tox`.\n\n   Hace lo que promete:\n\n    \u003e 1. Chequea que tu paquete instala correctamente en diferentes versiones de Python e intérpretes.\n    \u003e 2. Ejecuta tus tests en cada uno de los entornos, configurando el framework para los test que elijas.\n    \u003e 3. Actúa como un frontend para servidores de Continuous Integration, \"_greatly reducing boilerplate and merging CI and shell-based testing_\". \u003c== siguiente paso en esta práctica.\n\n    Crea un directorio `.tox` bajo el cual encontramos los entornos virtuales indicados en la envlist del tox.ini (py36) y un egg de distribución (leer más adelante);\n\n    ```bash\n    # -l 2 para bajar solo 2 niveles\n    $ tree -L 2 .tox\n    .tox\n    ├── dist\n    │   └── square root testing-0.0.1.zip\n    ├── log\n    │\n    └── py36\n        ├── bin\n        ├── lib\n        ├── log\n        ├── pyvenv.cfg\n        └── tmp\n    ```\n\n    ``` bash\n    (venv) $ tox\n    # Crea el fichero de distribución a partir del setup.py\n    GLOB sdist-make: /square_test/setup.py\n\n    # Crea un entorno virtual para cada uno indicado en la envlist del tox.ini\n    py36 inst-nodeps: /square_test/.tox/.tmp/package/1/square root testing-0.0.1.zip\n\n    # Instala las dependencias en el entorno virtual indicadas en requirements.txt\n    py36 installed: appdirs==1.4.4,attrs==20.3.0,distlib==0.3.1,filelock==3.0.12,importlib-metadata==2.1.1,importlib-resources==4.1.1,iniconfig==1.1.1,packaging==20.8,pluggy==0.13.1,py==1.10.0,pyparsing==2.4.7,pytest==6.2.1,six==1.15.0,square-root-testing\n    py36 run-test-pre: PYTHONHASHSEED='93282115'\n\n    # Ejecuta los comandos de la lista commands del tox.ini\n    py36 run-test: commands[0] | pytest\n\n    ========================== test session starts =======================\n    platform linux -- Python 3.6.9, pytest-6.2.1, py-1.10.0, pluggy-0.13.1\n    cachedir: .tox/py36/.pytest_cache\n    rootdir: /square_test, configfile: pytest.ini\n    collected 6 tems\n    test/test_ square_root.py [ 16%]\n    test/test_b_c_nulo.py     [ 33%]\n    test/test_c_nulo.py .     [ 66%]\n    test/test_division_cero.py .. [100%]\n\n    ========== 6 passed in 0.02s ================\n    _____________summary ________________________\n    py36: commands succeeded\n    congratulations :)\n\n    ```\n\nSe instalan en el entorno virtual las dependencias del `requirements.txt` y todas aquellas dependendencias que indice en la sección `deps = ` del `tox.ini`\nEntiendo que se copian los ficheros de configuración de las herramientas, y los usa tox =\u003e ¿cómo se copiarían los ficheros de configuración de coverage y black al entorno virtual de prueba?\n\n\n## Dist\n\nEn este artículo se explica bien qué sucede con el estándar mínimo que ha de tener un paquete, y los estándares PEP517 y PEP518, las setuptools y wheel y, sobretodo, el fichero `pyproject.toml`\n\nhttps://snarky.ca/what-the-heck-is-pyproject-toml/\n\nLa idea es usar el fichero `pyproject.toml` para ser utilizado para configurar todas las herramientas como coverage, wheels, tox, etc.\n\n\nPackaging en Tox y con otras herramientas =\u003e añadir  `pyproject.toml` con la configuración (no es necesario):\n\n```toml\n[build-system]\nrequires = [\n    \"setuptools \u003e= 35.0.2\",\n    \"setuptools_scm \u003e= 2.0.0, \u003c3\"\n]\nbuild-backend = \"setuptools.build_meta\"\n```\n\nhttps://tox.readthedocs.io/en/latest/example/package.html\n\n\nHe decido hacerlo de este modo:\n\n1. En `tox.ini` indico un directorio fuera de .tox donde situar el `egg.zip`:\n\n    ```ini\n    # content of: tox.ini\n    [tox]\n    envlist = py36\n    # indicar un directorio fuera de .tox donde situar el zip con el egg\n    distdir=./dist-egg\n    ```\n    La configuración de `tox.ini` (como `distdir`) está aquí:\n    https://tox.readthedocs.io/en/latest/config.html\n\n2. Tras pasar los test, empaqueto con wheel\n\n    `(venv) $ pip3 install wheel`\n\n    que crea un directorio `./dist` donde figura el fich `whl`\n\n    Aquí `wheel`:\n\n    https://wheel.readthedocs.io/en/stable/user_guide.html\n\n    En la sección `commands` de tox.ini añadir:\n    `wheel setup.py bdtis_wheel`\n\n    Crea un directorio `dist` donde colocal el fichero wheel.\n\n\nEl problema de esta configuración es que si un caso test falla, el empaquetado con wheel se completa de igua modo, no así el que tox crea en `.tox/dist`.\n\n\n### eggs\n\ntox crea en la carpeta .tox/dist un paquete de distribución `egg` para instalar con `easy_install`:\n\n`square root testing-0.0.1.zip`\n\nContiene el código del paquete y metadatos, como los `.jar`\n\nHa sido superseed por wheel (convertir un egg a wheel:)\n\nhttps://wheel.readthedocs.io/en/stable/quickstart.html\n\n\n\nhttps://stackoverflow.com/questions/2051192/what-is-a-python-egg\n\n    Note: Egg packaging has been superseded by Wheel packaging.\n\nSame concept as a .jar file in Java, it is a .zip file with some metadata files renamed .egg, for distributing code as bundles.\n\nSpecifically: The Internal Structure of Python Eggs: http://svn.python.org/projects/sandbox/trunk/setuptools/doc/formats.txt\n\n    A \"Python egg\" is a logical structure embodying the release of a specific version of a Python project, comprising its code, resources, and metadata. There are multiple formats that can be used to physically encode a Python egg, and others can be developed. However, a key principle of Python eggs is that they should be discoverable and importable. That is, it should be possible for a Python application to easily and efficiently find out what eggs are present on a system, and to ensure that the desired eggs' contents are importable.\n\n    The .egg format is well-suited to distribution and the easy uninstallation or upgrades of code, since the project is essentially self-contained within a single directory or file, unmingled with any other projects' code or resources. It also makes it possible to have multiple versions of a project simultaneously installed, such that individual programs can select the versions they wish to use.\n\n\n## Bandit\n\nEs conveniente integrar en el ciclo CI cuanto antes cuestiones sobre la seguridad de las aplicaciones. De DevOps hay que evolucionar a SecDevOps.\n\nBandit realiza un análisis **estático**  del código en busca de vulnerabilidades:\n\nhttps://pypi.org/project/bandit/\n\nhttps://bandit.readthedocs.io/en/latest/config.html\n\n```bash\n# install\n$ pip3 install bandit\n\n#run\nS bandit -r path/to/your/code\n# Across the examples/ directory, showing three lines of context and only reporting on the high-severity issues:\n$ bandit examples/*.py -n 3 -lll\n\n# Nuesto caso:\n$ bandit -r ./src/ ./test\n# informa de la presencia de assert que eliminarán código cuando se ejecute en producción\n\n$ bandit -r\n[main]  INFO    profile include tests: None\n[main]  INFO    profile exclude tests: None\n[main]  INFO    cli include tests: None\n[main]  INFO    cli exclude tests: None\n[main]  INFO    running on Python 3.6.9\nRun started:2021-03-26 13:09:52.411873\n\nTest results:\n        No issues identified.\n\nCode scanned:\n        Total lines of code: 25\n        Total lines skipped (#nosec): 0\n\nRun metrics:\n        Total issues (by severity):\n                Undefined: 0.0\n                Low: 0.0\n                Medium: 0.0\n                High: 0.0\n        Total issues (by confidence):\n                Undefined: 0.0\n                Low: 0.0\n                Medium: 0.0\n                High: 0.0\nFiles skipped (0): ./src/\n```\n\n### Configuracion\n\nPara generar un fichero de configuración (no es necesario):\n\n`$ bandit-config-generator -o .bandit`\n\nPara usarlo:\n\n`$ bandit-c .bandit`\n\n\nLa lista de test que pasa bandit para chequear vulnerabilidades es esta: muy educativo para aprender las vulnerabilidades en código Python:\n\nhttps://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing\n\nEn el archivo de configuración se pueden excluir los casos test por su etiqueta.\n\n### Actualizar tox.ini\n\nComprobar que bandit está instalado (obviamente)\n\n```bash\n$ pip3 show bandit\nName: bandit\nVersion: 1.7.0\nSummary: Security oriented static analyser for python code.\nHome-page: https://bandit.readthedocs.io/en/latest/\nAuthor: PyCQA\nAuthor-email: code-quality@python.org\nLicense: UNKNOWN\nLocation: /home/david/Escritorio/codigo/square_test/venv/lib/python3.6/site-packages\nRequires: PyYAML, GitPython, six, stevedore\n```\n\n```bash\n$ pip3 freeze | grep bandit\nbandit==1.7.0\n```\nMeter la dependencia a bandit en `tox.ini`:\n\n```\n# ... or install anything else you might need here\ndeps =\n        -rrequirements.txt\n        # Todas las dependencias que no se incluyan en el requirements van aqui\n        # Aqui las dependencias que necesito para CI, no para dev\n        black\n        coverage\n        bandit  \u003c======\n```\n\n\n## Githooks para disparar tox / pre-commit en el master\n\n### pre-commit\n\nhttps://pre-commit.com/\n\n```bash\n#instalacion:\n$ pip3 install pre-commit\n\n$ pip3 list | grep commit\npre-commit (2.11.1)\n\n$ pre-commit --version\npre-commit 2.11.1\n```\n\nCrear el fichero de configuración:\n\n`$ pre-commit sample-config \u003e .pre-commit-config.yaml`\n\nBuscar cada hook de python aquí, Supported hooks:\n\nhttps://pre-commit.com/hooks.html\n\n\nIncluir el hook de `black` (y los deseados) en `.pre-commit-config.yaml`\n\n\n```yaml\n# https://github.com/psf/black#version-control-integration\nrepos:\n  - repo: https://github.com/psf/black\n    rev: 20.8b1\n    hooks:\n      - id: black\n        language_version: python3\n\n# https://github.com/PyCQA/bandit#version-control-integration\nrepos:\n-   repo: https://github.com/PyCQA/bandit\n    rev: 1.7.0\n    hooks:\n        - id: bandit\n```\n\nInstalarlos:\n\n```bash\n$ pre-commit install\npre-commit installed at .git/hooks/pre-commit\n```\n\n`pre-commit` se ejecutará \"on\" `git commit`\n\nEjecutarlo contra todos los ficheros:\n\n`$ pre-commit run --all-files`\n\nPara uno (que voy a crear a continuación):\n\n`$ pre-commit run --files ./src/blame.py`\n\n\nCreo un archivo culpable de todas las cosas:\n\n```py\ndef blame(curses):\n    assert curses\u003e0\n    msg = \"vulture food\"\n    return curses *     \"te lo dije!\"\n    \n\nif __name__ == \"__main__\":\n    print(blame(2))\n```\n\nEjecuto los hooks contra él:\n\n```bash\n$ pre-commit run --files ./src/blame.py \n\nTrim Trailing Whitespace.................................................Passed\nFix End of Files.........................................................Failed  \u003c====\n- hook id: end-of-file-fixer\n- exit code: 1\n- files were modified by this hook\n\nFixing src/blame.py\n\nCheck Yaml...........................................(no files to check)Skipped\nCheck for added large files..............................................Passed\nblack....................................................................Failed   \u003c=====\n- hook id: black\n- files were modified by this hook\n\nreformatted src/blame.py\nAll done! ✨ 🍰 ✨\n1 file reformatted.\n\nbandit...................................................................Failed   \u003c=====\n- hook id: bandit\n- exit code: 1\n\n[main]  INFO    profile include tests: None\n[main]  INFO    profile exclude tests: None\n[main]  INFO    cli include tests: None\n[main]  INFO    cli exclude tests: None\n[main]  INFO    running on Python 3.6.9\nRun started:2021-03-26 19:51:01.497333\n\nTest results:\n\u003e\u003e Issue: [B101:assert_used] Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.\n   Severity: Low   Confidence: High\n   Location: src/blame.py:2\n   More Info: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html\n1       def blame(curses):\n2           assert curses \u003e 0\n3           msg = \"vulture food\"\n\n--------------------------------------------------\n\nCode scanned:\n        Total lines of code: 6\n        Total lines skipped (#nosec): 0\n\nRun metrics:\n        Total issues (by severity):\n                Undefined: 0.0\n                Low: 1.0\n                Medium: 0.0\n                High: 0.0\n        Total issues (by confidence):\n                Undefined: 0.0\n                Low: 0.0\n                Medium: 0.0\n                High: 1.0\nFiles skipped (0):\n```\n\nEl fichero `blame.py` eso sí, queda formateado.\n\n\nSi intentamos hacer un commit con él, comprobamos que los hooks se disparan y se detiene el commit de `blame.py`:\n\n```bash\n$ git commit -m \"ci(pre-commit): Incluir configuracion pre-commit\"\n\nTrim Trailing Whitespace.................................................Failed\n- hook id: trailing-whitespace\n- exit code: 1\n- files were modified by this hook\n\nFixing README.md\nFixing src/blame.py\n\nFix End of Files.........................................................Failed\n- hook id: end-of-file-fixer\n- exit code: 1\n- files were modified by this hook\n\nFixing README.md\n\nCheck Yaml...............................................................Passed\nCheck for added large files..............................................Passed\nblack....................................................................Failed\n- hook id: black\n- files were modified by this hook\n\nreformatted src/blame.py\nAll done! ✨ 🍰 ✨\n1 file reformatted.\n\nbandit...................................................................Failed\n- hook id: bandit\n- exit code: 1\n\n[main]  INFO    profile include tests: None\n[main]  INFO    profile exclude tests: None\n[main]  INFO    cli include tests: None\n[main]  INFO    cli exclude tests: None\n[main]  INFO    running on Python 3.6.9\nRun started:2021-03-26 19:45:16.642375\n\nTest results:\n\u003e\u003e Issue: [B101:assert_used] Use of assert detected. The enclosed code will be removed when compiling to optimised byte code.\n   Severity: Low   Confidence: High\n   Location: src/blame.py:2\n   More Info: https://bandit.readthedocs.io/en/latest/plugins/b101_assert_used.html\n1       def blame(curses):\n2           assert curses \u003e 0\n3           msg = \"vulture food\"\n\n--------------------------------------------------\n\nCode scanned:\n        Total lines of code: 6\n        Total lines skipped (#nosec): 0\n\nRun metrics:\n        Total issues (by severity):\n                Undefined: 0.0\n                Low: 1.0\n                Medium: 0.0\n                High: 0.0\n        Total issues (by confidence):\n                Undefined: 0.0\n                Low: 0.0\n                Medium: 0.0\n                High: 1.0\nFiles skipped (0):\n```\n\n## YAML\n\nEspecificación de YAML:\n\nhttps://yaml.org/spec/1.2/spec.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfleta%2Fkata_tdd_pytest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdfleta%2Fkata_tdd_pytest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdfleta%2Fkata_tdd_pytest/lists"}