{"id":590,"date":"2026-07-22T08:17:32","date_gmt":"2026-07-22T08:17:32","guid":{"rendered":"https:\/\/matforge.org\/?p=590","raw":"https:\/\/matforge.org\/?p=590"},"modified":"2026-07-22T08:17:32","modified_gmt":"2026-07-22T08:17:32","slug":"continuous-integration-research-software-automated-testing-validation","status":"publish","type":"post","link":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/","title":{"rendered":"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas","raw":"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 13<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span><p>La integraci\u00f3n continua (CI) crea, prueba y valida autom\u00e1ticamente el c\u00f3digo de investigaci\u00f3n en cada confirmaci\u00f3n. Para el software cient\u00edfico, CI es esencial para la reproducibilidad, la detecci\u00f3n temprana de errores y el mantenimiento de la calidad a lo largo del tiempo. Implementar CI: (1) Escribir pruebas automatizadas con PyTest, (2) configurar una canalizaci\u00f3n de CI utilizando GitHub Actions o GitLab CI, (3) usar Docker\/Conda para la coherencia del entorno, (4) agregar informes de cobertura y (5) incorporar puntos de referencia de rendimiento. Maneje las pruebas num\u00e9ricas con <code>pytest.approx<\/code>, use estrategias de matriz para probar en versiones de Python y dependencias de cach\u00e9 para reducir el tiempo de ejecuci\u00f3n. CI transforma el c\u00f3digo de investigaci\u00f3n de scripts fr\u00e1giles en software confiable y mantenible.<\/p>\n<h2>Introducci\u00f3n: \u00bfPor qu\u00e9 la integraci\u00f3n continua es importante para la investigaci\u00f3n?<\/h2>\n<p>El software de investigaci\u00f3n es conocido por romper en silencio. Un peque\u00f1o cambio en una parte del c\u00f3digo puede producir resultados sutilmente diferentes aguas abajo, invalidando los hallazgos publicados o perdiendo meses de tiempo de c\u00e1lculo. Las pruebas manuales tradicionales, ejecutando algunos ejemplos a mano, no se escalan a c\u00f3digos de simulaci\u00f3n complejos con docenas de m\u00f3dulos interdependientes.<\/p>\n<p>La integraci\u00f3n continua (CI) soluciona esto ejecutando autom\u00e1ticamente un conjunto de pruebas completo cada vez que se confirma el c\u00f3digo. Pero CI es m\u00e1s que solo automatizaci\u00f3n; Es una disciplina de calidad que hace cumplir la reproducibilidad y valida la correcci\u00f3n continuamente. Como <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\">Mejores pr\u00e1cticas de computaci\u00f3n cient\u00edfica<\/a> Notas en papel, \u00abAutomated Las pruebas no son negociables para un software cient\u00edfico de confianza\u00bb (Wilson et al., 2012).<\/p>\n<p>Para los equipos de investigaci\u00f3n, CI ofrece beneficios concretos:<\/p>\n<ul>\n<li><strong>Reproducibilidad<\/strong>: CI verifica que el c\u00f3digo produce resultados consistentes en entornos y en el tiempo.<\/li>\n<li><strong>Detecci\u00f3n temprana de defectos<\/strong>: los errores se detectan minutos despu\u00e9s de que se introducen, no semanas despu\u00e9s durante la preparaci\u00f3n del manuscrito.<\/li>\n<li><strong>Confianza para refactor<\/strong>: Con una red de seguridad de pruebas, puedes mejorar la estructura del c\u00f3digo sin temor a romper algo.<\/li>\n<li><strong>Habilitaci\u00f3n de colaboraci\u00f3n<\/strong>: varios contribuyentes pueden trabajar en la misma base de c\u00f3digo con comprobaciones automatizadas que evitan las regresiones.<\/li>\n<li><strong>Documentaci\u00f3n de las expectativas<\/strong>: las pruebas sirven como especificaciones ejecutables que documentan c\u00f3mo debe comportarse el c\u00f3digo.<\/li>\n<\/ul>\n<p>A pesar de estos beneficios, muchos proyectos de investigaci\u00f3n a\u00fan carecen de IC. Las excusas comunes incluyen \u00abnuestro c\u00f3digo es demasiado complejo para probar\u00bb, \u00ablas pruebas tardan demasiado\u00bb o \u00abno tenemos tiempo para configurar CI\u00bb. Esta gu\u00eda desmantela estas objeciones y proporciona un enfoque pr\u00e1ctico y paso a paso para CI adaptado al software cient\u00edfico.<\/p>\n<h2>\u00bfQu\u00e9 es la integraci\u00f3n continua, realmente?<\/h2>\n<p>La integraci\u00f3n continua es la pr\u00e1ctica de fusionar los cambios de c\u00f3digo en un repositorio compartido con frecuencia, idealmente varias veces al d\u00eda, y verificar autom\u00e1ticamente cada combinaci\u00f3n con una compilaci\u00f3n y una canalizaci\u00f3n de prueba automatizadas. La parte \u00abcontinua\u00bb significa que la retroalimentaci\u00f3n es r\u00e1pida; Los desarrolladores saben en cuesti\u00f3n de minutos si su cambio rompi\u00f3 algo.<\/p>\n<p>Una canalizaci\u00f3n de CI generalmente incluye:<\/p>\n<ol>\n<li><strong>checkout<\/strong>: el sistema CI obtiene el c\u00f3digo m\u00e1s reciente.<\/li>\n<li><strong>Configuraci\u00f3n de entorno<\/strong>: Las dependencias se instalan (a menudo dentro de un contenedor).<\/li>\n<li><strong>An\u00e1lisis est\u00e1tico<\/strong>: el c\u00f3digo est\u00e1 enlazado por problemas de estilo y posibles errores.<\/li>\n<li><strong>Pruebas unitarias<\/strong>: Las funciones y los m\u00f3dulos individuales se prueban de forma aislada.<\/li>\n<li><strong>Pruebas de integraci\u00f3n<\/strong>: se prueban varios componentes juntos.<\/li>\n<li><strong>Informes de cobertura<\/strong>: se mide la fracci\u00f3n de c\u00f3digo ejercido por las pruebas.<\/li>\n<li><strong>Edificio de artefacto<\/strong>: se generan documentaci\u00f3n, paquetes o binarios.<\/li>\n<li><strong>Benchmarks de rendimiento<\/strong> (opcional): se realiza un seguimiento de la velocidad de ejecuci\u00f3n y el uso de memoria.<\/li>\n<\/ol>\n<p>Para el software de investigaci\u00f3n, agregamos:<\/p>\n<ul>\n<li><strong>Validaci\u00f3n num\u00e9rica<\/strong>: pruebas que dan cuenta de las tolerancias de punto flotante y la variaci\u00f3n estoc\u00e1stica.<\/li>\n<li><strong>Verificaciones de reproducibilidad<\/strong>: verificaci\u00f3n de que los resultados coinciden con los resultados de referencia dentro de los l\u00edmites aceptables.<\/li>\n<li><strong>Validaci\u00f3n de datos<\/strong>: garantiza la integridad de los datos de entrada y salida.<\/li>\n<\/ul>\n<h2>Componentes centrales: Construyendo una tuber\u00eda de CI lista para la investigaci\u00f3n<\/h2>\n<p>Una tuber\u00eda de CI s\u00f3lida para proyectos cient\u00edficos de Python debe incluir estos componentes, cada uno de los cuales aborda un aspecto de calidad espec\u00edfico.<\/p>\n<h3>Pruebas automatizadas con PyTest<\/h3>\n<p>La Fundaci\u00f3n es un conjunto de pruebas completo que utiliza <a href=\"https:\/\/docs.pytest.org\/\">pytest<\/a>. PyTest es el est\u00e1ndar de facto para las pruebas de Python debido a su simplicidad, potentes accesorios y rico ecosistema.<\/p>\n<p>Para el c\u00f3digo cient\u00edfico, conc\u00e9ntrese en:<\/p>\n<ul>\n<li><strong>Pruebas unitarias<\/strong> para funciones individuales (por ejemplo, \u00bfun solucionador de difusi\u00f3n calcula correctamente en una malla simple?).<\/li>\n<li><strong>Pruebas de regresi\u00f3n<\/strong> que comparan los resultados con los buenos resultados conocidos (esencial para los solucionadores de PDE).<\/li>\n<li><strong>Pruebas basadas en la propiedad<\/strong> usando <a href=\"https:\/\/hypothesis.readthedocs.io\/\">hip\u00f3tesis<\/a> para generar entradas aleatorias y verificar invariantes.<\/li>\n<\/ul>\n<p>La prueba unitaria para el borrador del C\u00f3digo Cient\u00edfico (en progreso) cubre en profundidad las estrategias de PyTest, incluido el manejo de la precisi\u00f3n num\u00e9rica.<\/p>\n<h3>Manejo de comparaciones num\u00e9ricas<\/h3>\n<p>El c\u00f3digo cient\u00edfico se ocupa de la aritm\u00e9tica de punto flotante, donde la igualdad exacta suele ser imposible debido a errores de redondeo. PyTest proporciona <code>pytest.approx<\/code> para comparaciones aproximadas:<\/p>\n<pre><code class=\"language-python\">def test_diffusion_result():\n    result = run_simulation()\n    expected = 0.123456\n    assert result == pytest.approx(expected, rel=1e-6)  # 0.1% tolerance\n<\/code><\/pre>\n<p>Para matrices, use <code>numpy.testing.assert_allclose<\/code>:<\/p>\n<pre><code class=\"language-python\">import numpy.testing as npt\n\ndef test_field_solution():\n    computed = solve_pde()\n    reference = load_reference_solution()\n    npt.assert_allclose(computed, reference, rtol=1e-5, atol=1e-10)\n<\/code><\/pre>\n<p>Elija tolerancias basadas en la precisi\u00f3n de la f\u00edsica y la discretizaci\u00f3n. Documente por qu\u00e9 se eligieron tolerancias espec\u00edficas.<\/p>\n<h3>Medici\u00f3n de cobertura de c\u00f3digo<\/h3>\n<p>La cobertura de c\u00f3digo mide cu\u00e1nto de su base de c\u00f3digo se ejecuta durante las pruebas. Si bien la cobertura del 100% no siempre es necesaria (o alcanzable), el seguimiento de la cobertura ayuda a identificar las rutas de c\u00f3digo no probadas.<\/p>\n<p>Utilice <a href=\"https:\/\/pytest-cov.readthedocs.io\/\">pytest-cov<\/a> para generar informes de cobertura:<\/p>\n<pre><code class=\"language-bash\">pytest --cov=src\/ --cov-report=xml --cov-report=html\n<\/code><\/pre>\n<p>Integre con <a href=\"https:\/\/codecov.io\/\">codecov<\/a> o <a href=\"https:\/\/coveralls.io\/\">coveralls<\/a> para rastrear la cobertura a lo largo del tiempo y hacer cumplir los umbrales m\u00ednimos en CI.<\/p>\n<p>El <a href=\"https:\/\/learn.scientific-python.org\/development\/guides\/coverage\/\">gu\u00eda de desarrollo de Python cient\u00edfico<\/a> proporciona ejemplos detallados de configuraci\u00f3n de cobertura.<\/p>\n<h3>An\u00e1lisis est\u00e1tico y pelusa<\/h3>\n<p>Las herramientas de an\u00e1lisis est\u00e1tico detectan errores y aplican la coherencia del estilo antes de que se fusione el c\u00f3digo:<\/p>\n<ul>\n<li><strong>Flake8<\/strong>: Aplicaci\u00f3n de la gu\u00eda de estilo de PEP 8 y verificaci\u00f3n b\u00e1sica de errores.<\/li>\n<li><strong>MyPy<\/strong>: comprobaci\u00f3n de tipo est\u00e1tico (la escritura gradual es valiosa incluso en el c\u00f3digo de investigaci\u00f3n).<\/li>\n<li><strong>negro<\/strong>: formato autom\u00e1tico de c\u00f3digo (elimina los debates de estilo).<\/li>\n<li><strong>Pylint<\/strong>: an\u00e1lisis de calidad de c\u00f3digo m\u00e1s profundo (util\u00edcelo con cautela; algunas reglas pueden ser demasiado estrictas para el c\u00f3digo de investigaci\u00f3n).<\/li>\n<\/ul>\n<p>Ejecute estos como trabajos de CI separados para que las fallas no bloqueen las iteraciones de prueba r\u00e1pida.<\/p>\n<h3>Consistencia del entorno con Docker o Conda<\/h3>\n<p>Uno de los mayores desaf\u00edos de reproducibilidad es el infierno de la dependencia: las diferentes versiones de las bibliotecas producen resultados diferentes. CI elimina esto instalando dependencias en un entorno limpio y controlado.<\/p>\n<p><strong>Opci\u00f3n A: Docker<\/strong> (Recomendado para CI)<\/p>\n<p>Docker proporciona una completa contenedorizaci\u00f3n a nivel de sistema. A <code>Dockerfile<\/code> define el entorno exacto:<\/p>\n<pre><code class=\"language-dockerfile\">FROM python:3.11-slim\n\nWORKDIR \/app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY . .\n<\/code><\/pre>\n<p><a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\">Boettiger (2015)<\/a> argumenta que Docker \u00abes lo mejor que le ha pasado a la reproducibilidad cient\u00edfica\u00bb porque bloquea toda la pila de software, desde el sistema operativo hasta las bibliotecas.<\/p>\n<p><strong>Opci\u00f3n B: Entornos de Conda<\/strong><\/p>\n<p>Si su proyecto se basa en dependencias que no son de Python (p. ej., HDF5, MPI), utilice Conda:<\/p>\n<pre><code class=\"language-yaml\"># environment.yml\nname: research-ci\ndependencies:\n  - python=3.11\n  - numpy&gt;=1.24\n  - scipy\n  - pip:\n    - pytest\n    - pytest-cov\n<\/code><\/pre>\n<p>Los sistemas CI pueden crear y activar este entorno con <code>conda env create -f environment.yml<\/code>.<\/p>\n<p><strong>Importante<\/strong>: <a href=\"https:\/\/arxiv.org\/html\/2601.12811v1\">Docker no garantiza la reproducibilidad<\/a> advierte que incluso los contenedores pueden tener diferencias sutiles (timestamps, aleatorio semillas). Para una m\u00e1xima reproducibilidad, tambi\u00e9n corrija las versiones de la biblioteca y las semillas.<\/p>\n<h3>Edificio de documentaci\u00f3n<\/h3>\n<p>Incluya un paso para crear la documentaci\u00f3n (Sphinx, MKDOC) y, opcionalmente, despliegue. La documentaci\u00f3n como c\u00f3digo garantiza que los documentos se mantengan sincronizados con el c\u00f3digo. El borrador de paquetes de Python Scientific Python analiza esto en detalle.<\/p>\n<h3>Puntos de referencia de rendimiento<\/h3>\n<p>Para software de investigaci\u00f3n computacionalmente intensivo, monitoree el rendimiento para detectar regresiones. Herramientas como <a href=\"https:\/\/asv.readthedocs.io\/\">asv (velocidad airspeed)<\/a> Ejecutar puntos de referencia autom\u00e1ticamente y comparar con ejecuciones anteriores.<\/p>\n<p>Waller et al. (2015) describen <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\">incluidos los puntos de referencia de rendimiento en CI<\/a> para detectar las degradaciones de rendimiento antes de tiempo. Esto es particularmente importante para los solucionadores de PDE donde los cambios algor\u00edtmicos pueden afectar dr\u00e1sticamente el tiempo de ejecuci\u00f3n.<\/p>\n<h2>Comparaci\u00f3n de plataformas: Acciones de GitHub vs Gitlab CI<\/h2>\n<p>Existen dos plataformas de CI dominantes: GitHub Actions y Gitlab CI. Ambos son maduros y listos para la producci\u00f3n. La elecci\u00f3n a menudo depende de d\u00f3nde est\u00e9 alojado su c\u00f3digo.<\/p>\n<h3>Acciones de GitHub<\/h3>\n<p><strong>Fuerzas<\/strong>:<\/p>\n<ul>\n<li>Integraci\u00f3n profunda con GitHub (cheques de solicitud de extracci\u00f3n, mercado de acciones).<\/li>\n<li>Sintaxis de configuraci\u00f3n m\u00e1s simple para flujos de trabajo comunes.<\/li>\n<li>comunidad m\u00e1s grande y m\u00e1s acciones de terceros.<\/li>\n<li>gratis para repositorios p\u00fablicos; Nivel gratuito generoso para repositorios privados.<\/li>\n<\/ul>\n<p><strong>Debilidades<\/strong>:<\/p>\n<ul>\n<li>Menos potente para flujos de trabajo complejos en comparaci\u00f3n con Gitlab.<\/li>\n<li>Funciones integradas limitadas para el almacenamiento en cach\u00e9 de dependencias en las primeras versiones (ahora mejoradas).<\/li>\n<li>Atado al ecosistema de GitHub.<\/li>\n<\/ul>\n<p><strong>adopci\u00f3n<\/strong>: el 33% de las organizaciones usan acciones de GitHub (JetBrains, 2026).<\/p>\n<h3>GITLAB CI<\/h3>\n<p><strong>Fuerzas<\/strong>:<\/p>\n<ul>\n<li>M\u00e1s rico en funciones fuera de la caja (todo en una plataforma).<\/li>\n<li>Potentes estrategias matriciales y canalizaciones padre-hijo.<\/li>\n<li>Mejor soporte para monorepos.<\/li>\n<li>Opci\u00f3n de autohospedaje para entornos de investigaci\u00f3n con espacios de aire.<\/li>\n<\/ul>\n<p><strong>Debilidades<\/strong>:<\/p>\n<ul>\n<li>Curva de aprendizaje m\u00e1s pronunciada.<\/li>\n<li>comunidad m\u00e1s peque\u00f1a que las acciones de GitHub.<\/li>\n<li>La interfaz puede sentirse menos pulida.<\/li>\n<\/ul>\n<p><strong>Adopci\u00f3n<\/strong>: 19% de las organizaciones (JetBrains, 2026).<\/p>\n<h3>Recomendaci\u00f3n<\/h3>\n<p>Si su c\u00f3digo est\u00e1 en GitHub, use <strong>acciones de github<\/strong> para la simplicidad y la integraci\u00f3n del ecosistema. Si est\u00e1 en GitLab o necesita funciones avanzadas de canalizaci\u00f3n, seleccione <strong>Gitlab CI<\/strong>. Para entornos HPC con espacios de aire, considere Gitlab autohospedado.<\/p>\n<p>Ambas plataformas pueden lograr los mismos resultados; Las diferencias son en su mayor\u00eda preferencias de flujo de trabajo. Los ejemplos a continuaci\u00f3n utilizan acciones de GitHub debido a su popularidad, pero los equivalentes de Gitlab CI son f\u00e1ciles de construir.<\/p>\n<h2>Configuraci\u00f3n de CI: un flujo de trabajo completo de acciones de GitHub<\/h2>\n<p>Esta secci\u00f3n proporciona un flujo de trabajo de acciones de GitHub listo para la producci\u00f3n para un paquete cient\u00edfico de Python. Adaptalo a la estructura de tu proyecto.<\/p>\n<h3>requisitos previos<\/h3>\n<ol>\n<li><strong> Existen pruebas<\/strong> (<code>tests\/<\/code> directorio).<\/li>\n<li><strong>Los requisitos est\u00e1n anclados<\/strong> (<code>requirements.txt<\/code> o <code>environment.yml<\/code>).<\/li>\n<li><strong>opcional pero recomendado<\/strong>: <code>Dockerfile<\/code> para la reproducibilidad del entorno.<\/li>\n<li>El repositorio de c\u00f3digo est\u00e1 en GitHub.<\/li>\n<\/ol>\n<h3>Flujo de trabajo b\u00e1sico<\/h3>\n<p>Crear <code>.github\/workflows\/ci.yml<\/code>:<\/p>\n<pre><code class=\"language-yaml\">name: CI\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version: [\"3.9\", \"3.10\", \"3.11\", \"3.12\"]\n\n    steps:\n    - uses: actions\/checkout@v4\n\n    - name: Set up Python ${{ matrix.python-version }}\n      uses: actions\/setup-python@v5\n      with:\n        python-version: ${{ matrix.python-version }}\n        cache: 'pip'\n        cache-dependency-path: 'requirements.txt'\n\n    - name: Install dependencies\n      run: |\n        pip install --upgrade pip\n        pip install -r requirements.txt\n        pip install pytest pytest-cov\n\n    - name: Run tests with coverage\n      run: |\n        pytest --cov=src\/ --cov-report=xml --cov-report=term-missing --junitxml=test-results.xml\n\n    - name: Upload coverage to Codecov\n      uses: codecov\/codecov-action@v4\n      with:\n        file: .\/coverage.xml\n        flags: unittests\n        name: codecov-umbrella\n\n    - name: Upload test results\n      if: always()\n      uses: actions\/upload-artifact@v4\n      with:\n        name: test-results-${{ matrix.python-version }}\n        path: test-results.xml\n<\/code><\/pre>\n<p><strong>Caracter\u00edsticas clave<\/strong>:<\/p>\n<ul>\n<li><strong>Estrategia de matriz<\/strong>: las pruebas se ejecutan en Python 3.9\u20133.12 en paralelo, detectando problemas de compatibilidad con anticipaci\u00f3n.<\/li>\n<li><strong>Cach\u00e9<\/strong>: <code>actions\/setup-python<\/code> Almacenamiento en cach\u00e9s de paquetes PIP, reduciendo dr\u00e1sticamente el tiempo de instalaci\u00f3n.<\/li>\n<li><strong>Cobertura<\/strong>: salida terminal y XML para CodeCoV.<\/li>\n<li><strong>artefactos<\/strong>: los resultados de las pruebas se cargan incluso si fallan las pruebas, conservando la evidencia.<\/li>\n<\/ul>\n<h3>Uso de Docker en CI<\/h3>\n<p>Si tiene un <code>Dockerfile<\/code>, \u00faselo para garantizar la coherencia del entorno:<\/p>\n<pre><code class=\"language-yaml\">    - name: Build Docker image\n      run: docker build -t myproject-ci -f Dockerfile.ci .\n\n    - name: Run tests in Docker\n      run: |\n        docker run --rm \n          -v ${{ github.workspace }}:\/app \n          myproject-ci \n          pytest --cov=src\/ --cov-report=xml\n<\/code><\/pre>\n<h3>Manejo de pruebas de larga duraci\u00f3n<\/h3>\n<p>Las simulaciones cient\u00edficas pueden tomar horas. Los corredores de CI tienen l\u00edmites de tiempo (a menudo 6 horas). Estrategias:<\/p>\n<ol>\n<li><strong>Separe las pruebas r\u00e1pidas y lentas<\/strong>: use marcadores PyTest.<\/li>\n<\/ol>\n<pre><code class=\"language-python\"># In test file\nimport pytest\n\n@pytest.mark.slow\ndef test_large_simulation():\n    # Takes &gt;5 minutes\n    pass\n<\/code><\/pre>\n<p>en CI:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run quick tests\n      run: pytest -m \"not slow\"\n\n    - name: Run slow tests (optional, separate job)\n      if: github.event_name == 'schedule'  # Only on schedule, not on every PR\n      run: pytest -m slow\n<\/code><\/pre>\n<ol start=\"2\">\n<li><strong>Selecci\u00f3n de prueba<\/strong>: Ejecutar solo las pruebas afectadas por el cambio de c\u00f3digo usando <code>pytest --last-failed<\/code> o <code>pytest -k \"test_name\"<\/code>.<\/li>\n<li><strong>paralelizar<\/strong>: divida las pruebas en varios trabajos de CI usando <code>pytest-xdist<\/code>.<\/li>\n<\/ol>\n<h3>Dependencias de almacenamiento en cach\u00e9<\/h3>\n<p>M\u00e1s all\u00e1 del almacenamiento en cach\u00e9 de paquetes de Python, extensiones compiladas de cach\u00e9 y archivos de datos grandes:<\/p>\n<pre><code class=\"language-yaml\">    - name: Cache pip packages\n      uses: actions\/cache@v4\n      with:\n        path: ~\/.cache\/pip\n        key: ${{ runner.os }}-pip-${{ hashFiles('**\/requirements.txt') }}\n        restore-keys: |\n          ${{ runner.os }}-pip-\n\n    - name: Cache pytest\n      uses: actions\/cache@v4\n      with:\n        path: .pytest_cache\n        key: ${{ runner.os }}-pytest-${{ hashFiles('**\/*.py') }}\n<\/code><\/pre>\n<h3>Agregando pelusas<\/h3>\n<p>Agregue un trabajo separado para que los problemas de estilo no bloqueen la ejecuci\u00f3n de la prueba:<\/p>\n<pre><code class=\"language-yaml\">  lint:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - uses: actions\/setup-python@v5\n      with:\n        python-version: \"3.11\"\n    - run: pip install flake8 black mypy\n    - run: flake8 src\/ tests\/\n    - run: black --check src\/ tests\/\n    - run: mypy src\/\n<\/code><\/pre>\n<h2>Trampas comunes y c\u00f3mo evitarlas<\/h2>\n<p>Basado en los desaf\u00edos de CI\/CD identificados en el software de investigaci\u00f3n (<a href=\"https:\/\/www.testmuai.com\/blog\/cicd-pipeline-challenges\/\">testmu AI, 2026<\/a>), aqu\u00ed hay errores y soluciones frecuentes.<\/p>\n<h3>Escoma 1: Pruebas que escama<\/h3>\n<p>Las pruebas escamosas pasan a veces y fallan a otras, erosionando la confianza en CI. Son especialmente comunes con:<\/p>\n<ul>\n<li><strong>Condiciones de carrera<\/strong> en pruebas paralelas.<\/li>\n<li><strong>Supuestos de tiempo<\/strong> (por ejemplo, \u00abespera 1 segundo\u00bb).<\/li>\n<li><strong>Aleatoriedad<\/strong> sin semillas fijas.<\/li>\n<\/ul>\n<p><strong>Soluci\u00f3n<\/strong>: Determine todo. Use <code>pytest<\/code> accesorios con <code>scope=\"session\"<\/code> para recursos compartidos. Establezca semillas aleatorias al comienzo de cada prueba:<\/p>\n<pre><code class=\"language-python\">import random\nimport numpy as np\n\ndef setup_function():\n    random.seed(42)\n    np.random.seed(42)\n<\/code><\/pre>\n<h3>Escoma 2: CI que lleva demasiado tiempo<\/h3>\n<p>Si su canalizaci\u00f3n toma horas, los desarrolladores lo pasar\u00e1n por alto.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>:<\/p>\n<ul>\n<li>Dividido en trabajos r\u00e1pidos (en cada compromiso) y lentos (noche).<\/li>\n<li>Cach\u00e9 agresivamente (PIP, capas de Docker, datos de prueba).<\/li>\n<li>Paralelice utilizando estrategias de matriz.<\/li>\n<li>Marque las pruebas de Slow Know con <code>@pytest.mark.slow<\/code> y ejec\u00fatelas por separado.<\/li>\n<\/ul>\n<h3>Escollo 3: Deriva del medio ambiente entre CI y desarrollo<\/h3>\n<p>Las pruebas pasan en CI pero fallan localmente porque los entornos difieren.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: use la misma definici\u00f3n de entorno en todas partes. Docker es ideal: los desarrolladores ejecutan <code>docker-compose run test<\/code> localmente y CI usa el mismo Dockerfile. Alternativamente, use <code>tox<\/code> para administrar m\u00faltiples entornos de manera consistente.<\/p>\n<h3>Escollo 4: Dependencias faltantes o desactualizadas<\/h3>\n<p>CI falla porque se actualiz\u00f3 una dependencia ascendente y se rompi\u00f3 la compatibilidad.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: Dependencias de pines exactamente en <code>requirements.txt<\/code> (<code>package==1.2.3<\/code>), no con rangos (<code>&gt;=1.0<\/code>). Utilice un archivo de bloqueo de dependencia (<code>pip freeze &gt; requirements.txt<\/code>). Actualice regularmente las dependencias de manera controlada (por ejemplo, PRS semanal <code>dependabot<\/code>).<\/p>\n<h3>Escolar 5: Sin monitoreo de rendimiento<\/h3>\n<p>El c\u00f3digo se vuelve m\u00e1s lento con el tiempo, pero solo se nota cuando es catastr\u00f3fico.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: agregue puntos de referencia a CI con <a href=\"https:\/\/asv.readthedocs.io\/\">asv<\/a>. Config\u00farelo para que falle si el rendimiento se degrada m\u00e1s all\u00e1 de un umbral (por ejemplo, un 5% m\u00e1s lento). Consulte <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\">gu\u00eda de la velocidad de Python<\/a> para la implementaci\u00f3n.<\/p>\n<h3>Escolar 6: Ignorar la validaci\u00f3n num\u00e9rica<\/h3>\n<p>Las pruebas usan <code>==<\/code> en flotadores y fallan de forma intermitente, o peor, pasan incorrectamente.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: use <code>pytest.approx<\/code> y <code>numpy.testing.assert_allclose<\/code> en todas partes. Elija tolerancias basadas en el an\u00e1lisis num\u00e9rico (por ejemplo, el error de discretizaci\u00f3n debe ser O(H\u00b2) para los m\u00e9todos de segundo orden). Justificaci\u00f3n de la tolerancia del documento en las cadenas de documentos de prueba.<\/p>\n<h2>Gu\u00eda de Decisiones: Cu\u00e1ndo usar lo que<\/h2>\n<h3>Selecci\u00f3n de plataforma<\/h3>\n<table>\n<thead>\n<tr>\n<th>Situaci\u00f3n<\/th>\n<th>plataforma recomendada<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>C\u00f3digo alojado en GitHub<\/td>\n<td>Acciones de GitHub<\/td>\n<\/tr>\n<tr>\n<td>C\u00f3digo alojado en Gitlab<\/td>\n<td>GITLAB CI<\/td>\n<\/tr>\n<tr>\n<td>Necesita corredores auto-hospedados (con espacios en el aire)<\/td>\n<td>Gitlab CI (auto-hospedado)<\/td>\n<\/tr>\n<tr>\n<td>Quiere la configuraci\u00f3n m\u00e1s simple<\/td>\n<td>Acciones de GitHub<\/td>\n<\/tr>\n<tr>\n<td>Pipelines complejos multiproyectos<\/td>\n<td>Gitlab CI (Tuber\u00edas padre-hijo)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>estrategia de prueba<\/h3>\n<table>\n<thead>\n<tr>\n<th>Tipo de c\u00f3digo<\/th>\n<th>Enfoque recomendado<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Funciones de pit\u00f3n pura<\/td>\n<td>Pruebas unitarias con PyTest, objetivo de alta cobertura (&gt;90%)<\/td>\n<\/tr>\n<tr>\n<td>Solucionados de PDE<\/td>\n<td>Pruebas de regresi\u00f3n contra soluciones de referencia, pruebas basadas en la propiedad<\/td>\n<\/tr>\n<tr>\n<td>Algoritmos estoc\u00e1sticos<\/td>\n<td>Semilla aleatoria fija + pruebas estad\u00edsticas (media, varianza)<\/td>\n<\/tr>\n<tr>\n<td>Simulaciones grandes (&gt;5 min)<\/td>\n<td>Separe las pruebas lentas, ejecute todas las noches; Usar <code>@pytest.mark.slow<\/code><\/td>\n<\/tr>\n<tr>\n<td>Acoplamiento multicomponente<\/td>\n<td>Pruebas de integraci\u00f3n con peque\u00f1os casos de prueba, validar la correcci\u00f3n de acoplamiento<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Opci\u00f3n de contenedor<\/h3>\n<table>\n<thead>\n<tr>\n<th>Necesidad<\/th>\n<th>Recomendaci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>M\u00e1xima reproducibilidad, incluye DEPS de nivel OS<\/td>\n<td>Estibador<\/td>\n<\/tr>\n<tr>\n<td>Gesti\u00f3n de Python, m\u00e1s simple<\/td>\n<td>Medio Ambiente<\/td>\n<\/tr>\n<tr>\n<td>HPC con bibliotecas MPI<\/td>\n<td>conda (o acoplador con <code>--network=host<\/code> y <code>--ipc=host<\/code>)<\/td>\n<\/tr>\n<tr>\n<td>Entorno con espacios de aire<\/td>\n<td>Conda Pack o Docker Guardar\/Cargar<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Integraci\u00f3n de CI con flujos de trabajo de investigaci\u00f3n<\/h2>\n<p>CI no existe de forma aislada. Se conecta con otras herramientas y pr\u00e1cticas.<\/p>\n<h3>Integraci\u00f3n de seguimiento de problemas<\/h3>\n<p>El estado de CI aparece autom\u00e1ticamente en las solicitudes de extracci\u00f3n de GitHub\/Gitlab. Configure las reglas de protecci\u00f3n de rama para requerir el paso de CI antes de la combinaci\u00f3n. Esto garantiza que solo el c\u00f3digo validado entre en la rama principal.<\/p>\n<p>Las publicaciones existentes de MatForge en <a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">seguimiento de problemas<\/a> y <a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">deuda t\u00e9cnica<\/a> complementar CI definiendo c\u00f3mo se gestionan los problemas. CI proporciona verificaci\u00f3n automatizada de que los problemas se solucionan correctamente.<\/p>\n<h3>Conexi\u00f3n de reproducibilidad<\/h3>\n<p>Como se discuti\u00f3 en <a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\">reproducibilidad y su papel en la depuraci\u00f3n<\/a>, CI es una piedra angular de la investigaci\u00f3n reproducible. Se puede confiar en cada confirmaci\u00f3n que pasa CI para producir los mismos resultados en cualquier m\u00e1quina con el mismo entorno. Esto es esencial para:<\/p>\n<ul>\n<li><strong>Reproducibilidad del papel<\/strong>: cuando los revisores piden c\u00f3digo, puede se\u00f1alar un compromiso espec\u00edfico que pas\u00f3 CI y produjo las cifras.<\/li>\n<li><strong>Colaboraci\u00f3n<\/strong>: los contribuyentes externos pueden ejecutar las mismas pruebas localmente.<\/li>\n<li><strong>Mantenimiento a largo plazo<\/strong>: a\u00f1os m\u00e1s tarde, a\u00fan puede reconstruir los resultados de una confirmaci\u00f3n CI-validada.<\/li>\n<\/ul>\n<h3>Flujo de trabajo de revisi\u00f3n de c\u00f3digo<\/h3>\n<p>Empareja CI con revisi\u00f3n de c\u00f3digo obligatoria:<\/p>\n<ol>\n<li>El desarrollador empuja la rama, CI se ejecuta.<\/li>\n<li>Si pasa CI, abra una solicitud de extracci\u00f3n.<\/li>\n<li>Los revisores verifican la l\u00f3gica del c\u00f3digo y aseguran que las pruebas sean adecuadas.<\/li>\n<li>Fusionar solo despu\u00e9s de que CI pase y revisar aprobado.<\/li>\n<\/ol>\n<p>Este flujo de trabajo es est\u00e1ndar en la industria, pero a\u00fan es raro en la investigaci\u00f3n. Implementarlo aumenta dr\u00e1sticamente la calidad del software.<\/p>\n<h2>Temas avanzados<\/h2>\n<h3>Pruebas de matriz para m\u00faltiples dependencias<\/h3>\n<p>Los paquetes cient\u00edficos a menudo dependen de Numpy\/Scipy con un comportamiento espec\u00edfico de versi\u00f3n. Pruebe a trav\u00e9s de una matriz de versiones de Python y dependencias:<\/p>\n<pre><code class=\"language-yaml\">strategy:\n  matrix:\n    python-version: [\"3.9\", \"3.10\", \"3.11\"]\n    numpy-version: [\"1.24\", \"1.25\", \"1.26\"]\n<\/code><\/pre>\n<p>Instale la versi\u00f3n numpy espec\u00edfica en el paso <code>Install dependencies<\/code>:<\/p>\n<pre><code class=\"language-yaml\">    - run: |\n        pip install \"numpy==${{ matrix.numpy-version }}\" scipy\n<\/code><\/pre>\n<p>Esto detecta problemas de compatibilidad con anticipaci\u00f3n.<\/p>\n<h3>Detecci\u00f3n de regresi\u00f3n de rendimiento<\/h3>\n<p>Use <a href=\"https:\/\/asv.readthedocs.io\/\">asv<\/a> para realizar un seguimiento del rendimiento a lo largo del tiempo:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run benchmarks\n      run: |\n        asv run --quick --show-stderr\n      # asv compares against previous commits and reports regressions\n<\/code><\/pre>\n<p>Configure ASV para que falle el trabajo de CI si un punto de referencia es &gt;10% m\u00e1s lento que la ejecuci\u00f3n anterior. Consulte <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\">art\u00edculo de pythonspeed<\/a> para obtener m\u00e1s detalles.<\/p>\n<h3>Despliegue continuo de documentaci\u00f3n<\/h3>\n<p>CI puede implementar la documentaci\u00f3n autom\u00e1ticamente en las p\u00e1ginas de GitHub:<\/p>\n<pre><code class=\"language-yaml\">  deploy-docs:\n    needs: test  # Only run after tests pass\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - run: pip install -r requirements-docs.txt\n    - run: sphinx-build -b html docs\/ public\/\n    - uses: peaceiris\/actions-gh-pages@v3\n      with:\n        github_token: ${{ secrets.GITHUB_TOKEN }}\n        publish_dir: .\/public\n<\/code><\/pre>\n<p>Esto mantiene la documentaci\u00f3n sincronizada con los cambios de c\u00f3digo.<\/p>\n<h2>Gu\u00edas relacionadas<\/h2>\n<ul>\n<li><strong><a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\">La reproducibilidad y su papel en la depuraci\u00f3n<\/a><\/strong>: c\u00f3mo las pr\u00e1cticas de reproducibilidad mejoran la eficiencia de la depuraci\u00f3n.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">seguimiento de la deuda t\u00e9cnica a largo plazo en software de investigaci\u00f3n<\/a><\/strong> \u2013 gesti\u00f3n de la calidad del c\u00f3digo a lo largo del tiempo; IC ayuda a prevenir nuevas deudas.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/managing-research-software-through-tickets\/\">administrar software de investigaci\u00f3n a trav\u00e9s de tickets<\/a><\/strong>: integrando CI con flujos de trabajo de seguimiento de problemas.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">Por qu\u00e9 el seguimiento de problemas es fundamental en los proyectos cient\u00edficos<\/a><\/strong> \u2013 Comprender la importancia del seguimiento de problemas en el software cient\u00edfico desarrollo.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/collaboration-between-developers-and-researchers-turning-innovation-into-scalable-impact\/\">Colaboraci\u00f3n entre desarrolladores y Investigadores<\/a><\/strong>: convertir la innovaci\u00f3n en un impacto escalable a trav\u00e9s del trabajo en equipo efectivo.<\/li>\n<\/ul>\n<h2>Resumen y pr\u00f3ximos pasos<\/h2>\n<p>La integraci\u00f3n continua transforma el software de investigaci\u00f3n de scripts fr\u00e1giles e indocumentados en activos confiables y mantenibles. Los pasos centrales son:<\/p>\n<ol>\n<li>Escriba las pruebas automatizadas con PyTest, usando <code>pytest.approx<\/code> para comparaciones num\u00e9ricas.<\/li>\n<li>Configure una canalizaci\u00f3n de CI (Acciones de GitHub o CI de Gitlab) que se ejecuta en cada solicitud de empuje y extracci\u00f3n.<\/li>\n<li>Use Docker o Conda para garantizar la coherencia del entorno entre CI y el desarrollo.<\/li>\n<li>Agregue informes de cobertura, pelusas y creaci\u00f3n de documentaci\u00f3n.<\/li>\n<li>Supervise el rendimiento con puntos de referencia para capturar regresiones.<\/li>\n<li>Integre CI con sus procesos existentes de seguimiento de problemas y revisi\u00f3n de c\u00f3digo.<\/li>\n<\/ol>\n<p><strong>Acciones inmediatas<\/strong>:<\/p>\n<ul>\n<li>Si no tiene pruebas, comience escribiendo algunas para las funciones m\u00e1s cr\u00edticas. Incluso la cobertura del 20% es mejor que ninguna.<\/li>\n<li>Cree un archivo de configuraci\u00f3n de CI b\u00e1sico (<code>.github\/workflows\/ci.yml<\/code> como se muestra arriba) e iterar.<\/li>\n<li>Arregle las pruebas escamosas de inmediato: erosionan la confianza.<\/li>\n<li>Agregue una \u00abinsignia\u00bb a su L\u00e9ame que muestra el estado de CI (por ejemplo, <img decoding=\"async\" src=\"https:\/\/img.shields.io\/badge\/CI-passing-green\" alt=\"IC\">).<\/li>\n<\/ul>\n<p><strong>Cu\u00e1ndo buscar consulta<\/strong>: si su proyecto involucra dependencias complejas (MPi, c\u00f3digo GPU, bibliotecas patentadas) o tiene &gt;10,000 l\u00edneas de c\u00f3digo, considere una revisi\u00f3n profesional de su configuraci\u00f3n de CI. Ofrecemos <a href=\"\/category\/issue-tracking-tickets-technical-requests\/\">servicios de implementaci\u00f3n personalizados de CI\/CD<\/a> para equipos de investigaci\u00f3n.<\/p>\n<h2>Referencias y lectura adicional<\/h2>\n<ul>\n<li>Wilson, G., et al. (2012). <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\">Mejores pr\u00e1cticas de computaci\u00f3n cient\u00edfica<\/a>. <em>PLOS BIOLOG\u00cdA<\/em>.<\/li>\n<li>Boettiger, C. (2015). <a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\">Una introducci\u00f3n a Docker para la investigaci\u00f3n reproducible<\/a>. <em>ACM Sigops<\/em>.<\/li>\n<li>Waller, J., et al. (2015). <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\">Incluyendo puntos de referencia de rendimiento en integraci\u00f3n continua<\/a>. <em>Sean<\/em>.<\/li>\n<li><a href=\"https:\/\/imperialcollegelondon.github.io\/ci-best-practice\/\">Integraci\u00f3n continua de software de investigaci\u00f3n<\/a> \u2013 Gu\u00eda de mejores pr\u00e1cticas de Imperial College London.<\/li>\n<li><a href=\"https:\/\/docs.github.com\/actions\/guides\/building-and-testing-python\">Acciones de GitHub: Creaci\u00f3n y prueba de Python<\/a> \u2013 Documentaci\u00f3n oficial.<\/li>\n<li><a href=\"https:\/\/github.com\/swcarpentry\/good-enough-practices-in-scientific-computing\">Pr\u00e1cticas lo suficientemente buenas en inform\u00e1tica cient\u00edfica<\/a> \u2013 Carpinter\u00eda de software.<\/li>\n<\/ul>\n<hr>\n<p><strong>Recuento de palabras<\/strong>: ~2,200<br \/> <strong>Tiempo de lectura<\/strong>: ~10 minutos<br \/> <strong>Audiencia de destino<\/strong>: investigadores, estudiantes graduados y desarrolladores que trabajan en proyectos cient\u00edficos de Python que necesitan establecer una calidad automatizada y confiable seguridad.<\/p>\n","protected":false,"raw":"<p>La integraci\u00f3n continua (CI) crea, prueba y valida autom\u00e1ticamente el c\u00f3digo de investigaci\u00f3n en cada confirmaci\u00f3n. Para el software cient\u00edfico, CI es esencial para la reproducibilidad, la detecci\u00f3n temprana de errores y el mantenimiento de la calidad a lo largo del tiempo. Implementar CI: (1) Escribir pruebas automatizadas con PyTest, (2) configurar una canalizaci\u00f3n de CI utilizando GitHub Actions o GitLab CI, (3) usar Docker\/Conda para la coherencia del entorno, (4) agregar informes de cobertura y (5) incorporar puntos de referencia de rendimiento. Maneje las pruebas num\u00e9ricas con <code>pytest.approx<\/code>, use estrategias de matriz para probar en versiones de Python y dependencias de cach\u00e9 para reducir el tiempo de ejecuci\u00f3n. CI transforma el c\u00f3digo de investigaci\u00f3n de scripts fr\u00e1giles en software confiable y mantenible.<\/p>\n<h2>Introducci\u00f3n: \u00bfPor qu\u00e9 la integraci\u00f3n continua es importante para la investigaci\u00f3n?<\/h2>\n<p>El software de investigaci\u00f3n es conocido por romper en silencio. Un peque\u00f1o cambio en una parte del c\u00f3digo puede producir resultados sutilmente diferentes aguas abajo, invalidando los hallazgos publicados o perdiendo meses de tiempo de c\u00e1lculo. Las pruebas manuales tradicionales, ejecutando algunos ejemplos a mano, no se escalan a c\u00f3digos de simulaci\u00f3n complejos con docenas de m\u00f3dulos interdependientes.<\/p>\n<p>La integraci\u00f3n continua (CI) soluciona esto ejecutando autom\u00e1ticamente un conjunto de pruebas completo cada vez que se confirma el c\u00f3digo. Pero CI es m\u00e1s que solo automatizaci\u00f3n; Es una disciplina de calidad que hace cumplir la reproducibilidad y valida la correcci\u00f3n continuamente. Como <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\">Mejores pr\u00e1cticas de computaci\u00f3n cient\u00edfica<\/a> Notas en papel, \"Automated Las pruebas no son negociables para un software cient\u00edfico de confianza\" (Wilson et al., 2012).<\/p>\n<p>Para los equipos de investigaci\u00f3n, CI ofrece beneficios concretos:<\/p>\n<ul>\n<li><strong>Reproducibilidad<\/strong>: CI verifica que el c\u00f3digo produce resultados consistentes en entornos y en el tiempo.<\/li>\n<li><strong>Detecci\u00f3n temprana de defectos<\/strong>: los errores se detectan minutos despu\u00e9s de que se introducen, no semanas despu\u00e9s durante la preparaci\u00f3n del manuscrito.<\/li>\n<li><strong>Confianza para refactor<\/strong>: Con una red de seguridad de pruebas, puedes mejorar la estructura del c\u00f3digo sin temor a romper algo.<\/li>\n<li><strong>Habilitaci\u00f3n de colaboraci\u00f3n<\/strong>: varios contribuyentes pueden trabajar en la misma base de c\u00f3digo con comprobaciones automatizadas que evitan las regresiones.<\/li>\n<li><strong>Documentaci\u00f3n de las expectativas<\/strong>: las pruebas sirven como especificaciones ejecutables que documentan c\u00f3mo debe comportarse el c\u00f3digo.<\/li>\n<\/ul>\n<p>A pesar de estos beneficios, muchos proyectos de investigaci\u00f3n a\u00fan carecen de IC. Las excusas comunes incluyen \"nuestro c\u00f3digo es demasiado complejo para probar\", \"las pruebas tardan demasiado\" o \"no tenemos tiempo para configurar CI\". Esta gu\u00eda desmantela estas objeciones y proporciona un enfoque pr\u00e1ctico y paso a paso para CI adaptado al software cient\u00edfico.<\/p>\n<h2>\u00bfQu\u00e9 es la integraci\u00f3n continua, realmente?<\/h2>\n<p>La integraci\u00f3n continua es la pr\u00e1ctica de fusionar los cambios de c\u00f3digo en un repositorio compartido con frecuencia, idealmente varias veces al d\u00eda, y verificar autom\u00e1ticamente cada combinaci\u00f3n con una compilaci\u00f3n y una canalizaci\u00f3n de prueba automatizadas. La parte \"continua\" significa que la retroalimentaci\u00f3n es r\u00e1pida; Los desarrolladores saben en cuesti\u00f3n de minutos si su cambio rompi\u00f3 algo.<\/p>\n<p>Una canalizaci\u00f3n de CI generalmente incluye:<\/p>\n<ol>\n<li><strong>checkout<\/strong>: el sistema CI obtiene el c\u00f3digo m\u00e1s reciente.<\/li>\n<li><strong>Configuraci\u00f3n de entorno<\/strong>: Las dependencias se instalan (a menudo dentro de un contenedor).<\/li>\n<li><strong>An\u00e1lisis est\u00e1tico<\/strong>: el c\u00f3digo est\u00e1 enlazado por problemas de estilo y posibles errores.<\/li>\n<li><strong>Pruebas unitarias<\/strong>: Las funciones y los m\u00f3dulos individuales se prueban de forma aislada.<\/li>\n<li><strong>Pruebas de integraci\u00f3n<\/strong>: se prueban varios componentes juntos.<\/li>\n<li><strong>Informes de cobertura<\/strong>: se mide la fracci\u00f3n de c\u00f3digo ejercido por las pruebas.<\/li>\n<li><strong>Edificio de artefacto<\/strong>: se generan documentaci\u00f3n, paquetes o binarios.<\/li>\n<li><strong>Benchmarks de rendimiento<\/strong> (opcional): se realiza un seguimiento de la velocidad de ejecuci\u00f3n y el uso de memoria.<\/li>\n<\/ol>\n<p>Para el software de investigaci\u00f3n, agregamos:<\/p>\n<ul>\n<li><strong>Validaci\u00f3n num\u00e9rica<\/strong>: pruebas que dan cuenta de las tolerancias de punto flotante y la variaci\u00f3n estoc\u00e1stica.<\/li>\n<li><strong>Verificaciones de reproducibilidad<\/strong>: verificaci\u00f3n de que los resultados coinciden con los resultados de referencia dentro de los l\u00edmites aceptables.<\/li>\n<li><strong>Validaci\u00f3n de datos<\/strong>: garantiza la integridad de los datos de entrada y salida.<\/li>\n<\/ul>\n<h2>Componentes centrales: Construyendo una tuber\u00eda de CI lista para la investigaci\u00f3n<\/h2>\n<p>Una tuber\u00eda de CI s\u00f3lida para proyectos cient\u00edficos de Python debe incluir estos componentes, cada uno de los cuales aborda un aspecto de calidad espec\u00edfico.<\/p>\n<h3>Pruebas automatizadas con PyTest<\/h3>\n<p>La Fundaci\u00f3n es un conjunto de pruebas completo que utiliza <a href=\"https:\/\/docs.pytest.org\/\">pytest<\/a>. PyTest es el est\u00e1ndar de facto para las pruebas de Python debido a su simplicidad, potentes accesorios y rico ecosistema.<\/p>\n<p>Para el c\u00f3digo cient\u00edfico, conc\u00e9ntrese en:<\/p>\n<ul>\n<li><strong>Pruebas unitarias<\/strong> para funciones individuales (por ejemplo, \u00bfun solucionador de difusi\u00f3n calcula correctamente en una malla simple?).<\/li>\n<li><strong>Pruebas de regresi\u00f3n<\/strong> que comparan los resultados con los buenos resultados conocidos (esencial para los solucionadores de PDE).<\/li>\n<li><strong>Pruebas basadas en la propiedad<\/strong> usando <a href=\"https:\/\/hypothesis.readthedocs.io\/\">hip\u00f3tesis<\/a> para generar entradas aleatorias y verificar invariantes.<\/li>\n<\/ul>\n<p>La prueba unitaria para el borrador del C\u00f3digo Cient\u00edfico (en progreso) cubre en profundidad las estrategias de PyTest, incluido el manejo de la precisi\u00f3n num\u00e9rica.<\/p>\n<h3>Manejo de comparaciones num\u00e9ricas<\/h3>\n<p>El c\u00f3digo cient\u00edfico se ocupa de la aritm\u00e9tica de punto flotante, donde la igualdad exacta suele ser imposible debido a errores de redondeo. PyTest proporciona <code>pytest.approx<\/code> para comparaciones aproximadas:<\/p>\n<pre><code class=\"language-python\">def test_diffusion_result():\n    result = run_simulation()\n    expected = 0.123456\n    assert result == pytest.approx(expected, rel=1e-6)  # 0.1% tolerance\n<\/code><\/pre>\n<p>Para matrices, use <code>numpy.testing.assert_allclose<\/code>:<\/p>\n<pre><code class=\"language-python\">import numpy.testing as npt\n\ndef test_field_solution():\n    computed = solve_pde()\n    reference = load_reference_solution()\n    npt.assert_allclose(computed, reference, rtol=1e-5, atol=1e-10)\n<\/code><\/pre>\n<p>Elija tolerancias basadas en la precisi\u00f3n de la f\u00edsica y la discretizaci\u00f3n. Documente por qu\u00e9 se eligieron tolerancias espec\u00edficas.<\/p>\n<h3>Medici\u00f3n de cobertura de c\u00f3digo<\/h3>\n<p>La cobertura de c\u00f3digo mide cu\u00e1nto de su base de c\u00f3digo se ejecuta durante las pruebas. Si bien la cobertura del 100% no siempre es necesaria (o alcanzable), el seguimiento de la cobertura ayuda a identificar las rutas de c\u00f3digo no probadas.<\/p>\n<p>Utilice <a href=\"https:\/\/pytest-cov.readthedocs.io\/\">pytest-cov<\/a> para generar informes de cobertura:<\/p>\n<pre><code class=\"language-bash\">pytest --cov=src\/ --cov-report=xml --cov-report=html\n<\/code><\/pre>\n<p>Integre con <a href=\"https:\/\/codecov.io\/\">codecov<\/a> o <a href=\"https:\/\/coveralls.io\/\">coveralls<\/a> para rastrear la cobertura a lo largo del tiempo y hacer cumplir los umbrales m\u00ednimos en CI.<\/p>\n<p>El <a href=\"https:\/\/learn.scientific-python.org\/development\/guides\/coverage\/\">gu\u00eda de desarrollo de Python cient\u00edfico<\/a> proporciona ejemplos detallados de configuraci\u00f3n de cobertura.<\/p>\n<h3>An\u00e1lisis est\u00e1tico y pelusa<\/h3>\n<p>Las herramientas de an\u00e1lisis est\u00e1tico detectan errores y aplican la coherencia del estilo antes de que se fusione el c\u00f3digo:<\/p>\n<ul>\n<li><strong>Flake8<\/strong>: Aplicaci\u00f3n de la gu\u00eda de estilo de PEP 8 y verificaci\u00f3n b\u00e1sica de errores.<\/li>\n<li><strong>MyPy<\/strong>: comprobaci\u00f3n de tipo est\u00e1tico (la escritura gradual es valiosa incluso en el c\u00f3digo de investigaci\u00f3n).<\/li>\n<li><strong>negro<\/strong>: formato autom\u00e1tico de c\u00f3digo (elimina los debates de estilo).<\/li>\n<li><strong>Pylint<\/strong>: an\u00e1lisis de calidad de c\u00f3digo m\u00e1s profundo (util\u00edcelo con cautela; algunas reglas pueden ser demasiado estrictas para el c\u00f3digo de investigaci\u00f3n).<\/li>\n<\/ul>\n<p>Ejecute estos como trabajos de CI separados para que las fallas no bloqueen las iteraciones de prueba r\u00e1pida.<\/p>\n<h3>Consistencia del entorno con Docker o Conda<\/h3>\n<p>Uno de los mayores desaf\u00edos de reproducibilidad es el infierno de la dependencia: las diferentes versiones de las bibliotecas producen resultados diferentes. CI elimina esto instalando dependencias en un entorno limpio y controlado.<\/p>\n<p><strong>Opci\u00f3n A: Docker<\/strong> (Recomendado para CI)<\/p>\n<p>Docker proporciona una completa contenedorizaci\u00f3n a nivel de sistema. A <code>Dockerfile<\/code> define el entorno exacto:<\/p>\n<pre><code class=\"language-dockerfile\">FROM python:3.11-slim\n\nWORKDIR \/app\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\nCOPY . .\n<\/code><\/pre>\n<p><a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\">Boettiger (2015)<\/a> argumenta que Docker \"es lo mejor que le ha pasado a la reproducibilidad cient\u00edfica\" porque bloquea toda la pila de software, desde el sistema operativo hasta las bibliotecas.<\/p>\n<p><strong>Opci\u00f3n B: Entornos de Conda<\/strong><\/p>\n<p>Si su proyecto se basa en dependencias que no son de Python (p. ej., HDF5, MPI), utilice Conda:<\/p>\n<pre><code class=\"language-yaml\"># environment.yml\nname: research-ci\ndependencies:\n  - python=3.11\n  - numpy&gt;=1.24\n  - scipy\n  - pip:\n    - pytest\n    - pytest-cov\n<\/code><\/pre>\n<p>Los sistemas CI pueden crear y activar este entorno con <code>conda env create -f environment.yml<\/code>.<\/p>\n<p><strong>Importante<\/strong>: <a href=\"https:\/\/arxiv.org\/html\/2601.12811v1\">Docker no garantiza la reproducibilidad<\/a> advierte que incluso los contenedores pueden tener diferencias sutiles (timestamps, aleatorio semillas). Para una m\u00e1xima reproducibilidad, tambi\u00e9n corrija las versiones de la biblioteca y las semillas.<\/p>\n<h3>Edificio de documentaci\u00f3n<\/h3>\n<p>Incluya un paso para crear la documentaci\u00f3n (Sphinx, MKDOC) y, opcionalmente, despliegue. La documentaci\u00f3n como c\u00f3digo garantiza que los documentos se mantengan sincronizados con el c\u00f3digo. El borrador de paquetes de Python Scientific Python analiza esto en detalle.<\/p>\n<h3>Puntos de referencia de rendimiento<\/h3>\n<p>Para software de investigaci\u00f3n computacionalmente intensivo, monitoree el rendimiento para detectar regresiones. Herramientas como <a href=\"https:\/\/asv.readthedocs.io\/\">asv (velocidad airspeed)<\/a> Ejecutar puntos de referencia autom\u00e1ticamente y comparar con ejecuciones anteriores.<\/p>\n<p>Waller et al. (2015) describen <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\">incluidos los puntos de referencia de rendimiento en CI<\/a> para detectar las degradaciones de rendimiento antes de tiempo. Esto es particularmente importante para los solucionadores de PDE donde los cambios algor\u00edtmicos pueden afectar dr\u00e1sticamente el tiempo de ejecuci\u00f3n.<\/p>\n<h2>Comparaci\u00f3n de plataformas: Acciones de GitHub vs Gitlab CI<\/h2>\n<p>Existen dos plataformas de CI dominantes: GitHub Actions y Gitlab CI. Ambos son maduros y listos para la producci\u00f3n. La elecci\u00f3n a menudo depende de d\u00f3nde est\u00e9 alojado su c\u00f3digo.<\/p>\n<h3>Acciones de GitHub<\/h3>\n<p><strong>Fuerzas<\/strong>:<\/p>\n<ul>\n<li>Integraci\u00f3n profunda con GitHub (cheques de solicitud de extracci\u00f3n, mercado de acciones).<\/li>\n<li>Sintaxis de configuraci\u00f3n m\u00e1s simple para flujos de trabajo comunes.<\/li>\n<li>comunidad m\u00e1s grande y m\u00e1s acciones de terceros.<\/li>\n<li>gratis para repositorios p\u00fablicos; Nivel gratuito generoso para repositorios privados.<\/li>\n<\/ul>\n<p><strong>Debilidades<\/strong>:<\/p>\n<ul>\n<li>Menos potente para flujos de trabajo complejos en comparaci\u00f3n con Gitlab.<\/li>\n<li>Funciones integradas limitadas para el almacenamiento en cach\u00e9 de dependencias en las primeras versiones (ahora mejoradas).<\/li>\n<li>Atado al ecosistema de GitHub.<\/li>\n<\/ul>\n<p><strong>adopci\u00f3n<\/strong>: el 33% de las organizaciones usan acciones de GitHub (JetBrains, 2026).<\/p>\n<h3>GITLAB CI<\/h3>\n<p><strong>Fuerzas<\/strong>:<\/p>\n<ul>\n<li>M\u00e1s rico en funciones fuera de la caja (todo en una plataforma).<\/li>\n<li>Potentes estrategias matriciales y canalizaciones padre-hijo.<\/li>\n<li>Mejor soporte para monorepos.<\/li>\n<li>Opci\u00f3n de autohospedaje para entornos de investigaci\u00f3n con espacios de aire.<\/li>\n<\/ul>\n<p><strong>Debilidades<\/strong>:<\/p>\n<ul>\n<li>Curva de aprendizaje m\u00e1s pronunciada.<\/li>\n<li>comunidad m\u00e1s peque\u00f1a que las acciones de GitHub.<\/li>\n<li>La interfaz puede sentirse menos pulida.<\/li>\n<\/ul>\n<p><strong>Adopci\u00f3n<\/strong>: 19% de las organizaciones (JetBrains, 2026).<\/p>\n<h3>Recomendaci\u00f3n<\/h3>\n<p>Si su c\u00f3digo est\u00e1 en GitHub, use <strong>acciones de github<\/strong> para la simplicidad y la integraci\u00f3n del ecosistema. Si est\u00e1 en GitLab o necesita funciones avanzadas de canalizaci\u00f3n, seleccione <strong>Gitlab CI<\/strong>. Para entornos HPC con espacios de aire, considere Gitlab autohospedado.<\/p>\n<p>Ambas plataformas pueden lograr los mismos resultados; Las diferencias son en su mayor\u00eda preferencias de flujo de trabajo. Los ejemplos a continuaci\u00f3n utilizan acciones de GitHub debido a su popularidad, pero los equivalentes de Gitlab CI son f\u00e1ciles de construir.<\/p>\n<h2>Configuraci\u00f3n de CI: un flujo de trabajo completo de acciones de GitHub<\/h2>\n<p>Esta secci\u00f3n proporciona un flujo de trabajo de acciones de GitHub listo para la producci\u00f3n para un paquete cient\u00edfico de Python. Adaptalo a la estructura de tu proyecto.<\/p>\n<h3>requisitos previos<\/h3>\n<ol>\n<li><strong> Existen pruebas<\/strong> (<code>tests\/<\/code> directorio).<\/li>\n<li><strong>Los requisitos est\u00e1n anclados<\/strong> (<code>requirements.txt<\/code> o <code>environment.yml<\/code>).<\/li>\n<li><strong>opcional pero recomendado<\/strong>: <code>Dockerfile<\/code> para la reproducibilidad del entorno.<\/li>\n<li>El repositorio de c\u00f3digo est\u00e1 en GitHub.<\/li>\n<\/ol>\n<h3>Flujo de trabajo b\u00e1sico<\/h3>\n<p>Crear <code>.github\/workflows\/ci.yml<\/code>:<\/p>\n<pre><code class=\"language-yaml\">name: CI\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    strategy:\n      fail-fast: false\n      matrix:\n        python-version: [\"3.9\", \"3.10\", \"3.11\", \"3.12\"]\n\n    steps:\n    - uses: actions\/checkout@v4\n\n    - name: Set up Python ${{ matrix.python-version }}\n      uses: actions\/setup-python@v5\n      with:\n        python-version: ${{ matrix.python-version }}\n        cache: 'pip'\n        cache-dependency-path: 'requirements.txt'\n\n    - name: Install dependencies\n      run: |\n        pip install --upgrade pip\n        pip install -r requirements.txt\n        pip install pytest pytest-cov\n\n    - name: Run tests with coverage\n      run: |\n        pytest --cov=src\/ --cov-report=xml --cov-report=term-missing --junitxml=test-results.xml\n\n    - name: Upload coverage to Codecov\n      uses: codecov\/codecov-action@v4\n      with:\n        file: .\/coverage.xml\n        flags: unittests\n        name: codecov-umbrella\n\n    - name: Upload test results\n      if: always()\n      uses: actions\/upload-artifact@v4\n      with:\n        name: test-results-${{ matrix.python-version }}\n        path: test-results.xml\n<\/code><\/pre>\n<p><strong>Caracter\u00edsticas clave<\/strong>:<\/p>\n<ul>\n<li><strong>Estrategia de matriz<\/strong>: las pruebas se ejecutan en Python 3.9\u20133.12 en paralelo, detectando problemas de compatibilidad con anticipaci\u00f3n.<\/li>\n<li><strong>Cach\u00e9<\/strong>: <code>actions\/setup-python<\/code> Almacenamiento en cach\u00e9s de paquetes PIP, reduciendo dr\u00e1sticamente el tiempo de instalaci\u00f3n.<\/li>\n<li><strong>Cobertura<\/strong>: salida terminal y XML para CodeCoV.<\/li>\n<li><strong>artefactos<\/strong>: los resultados de las pruebas se cargan incluso si fallan las pruebas, conservando la evidencia.<\/li>\n<\/ul>\n<h3>Uso de Docker en CI<\/h3>\n<p>Si tiene un <code>Dockerfile<\/code>, \u00faselo para garantizar la coherencia del entorno:<\/p>\n<pre><code class=\"language-yaml\">    - name: Build Docker image\n      run: docker build -t myproject-ci -f Dockerfile.ci .\n\n    - name: Run tests in Docker\n      run: |\n        docker run --rm \n          -v ${{ github.workspace }}:\/app \n          myproject-ci \n          pytest --cov=src\/ --cov-report=xml\n<\/code><\/pre>\n<h3>Manejo de pruebas de larga duraci\u00f3n<\/h3>\n<p>Las simulaciones cient\u00edficas pueden tomar horas. Los corredores de CI tienen l\u00edmites de tiempo (a menudo 6 horas). Estrategias:<\/p>\n<ol>\n<li><strong>Separe las pruebas r\u00e1pidas y lentas<\/strong>: use marcadores PyTest.<\/li>\n<\/ol>\n<pre><code class=\"language-python\"># In test file\nimport pytest\n\n@pytest.mark.slow\ndef test_large_simulation():\n    # Takes &gt;5 minutes\n    pass\n<\/code><\/pre>\n<p>en CI:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run quick tests\n      run: pytest -m \"not slow\"\n\n    - name: Run slow tests (optional, separate job)\n      if: github.event_name == 'schedule'  # Only on schedule, not on every PR\n      run: pytest -m slow\n<\/code><\/pre>\n<ol start=\"2\">\n<li><strong>Selecci\u00f3n de prueba<\/strong>: Ejecutar solo las pruebas afectadas por el cambio de c\u00f3digo usando <code>pytest --last-failed<\/code> o <code>pytest -k \"test_name\"<\/code>.<\/li>\n<li><strong>paralelizar<\/strong>: divida las pruebas en varios trabajos de CI usando <code>pytest-xdist<\/code>.<\/li>\n<\/ol>\n<h3>Dependencias de almacenamiento en cach\u00e9<\/h3>\n<p>M\u00e1s all\u00e1 del almacenamiento en cach\u00e9 de paquetes de Python, extensiones compiladas de cach\u00e9 y archivos de datos grandes:<\/p>\n<pre><code class=\"language-yaml\">    - name: Cache pip packages\n      uses: actions\/cache@v4\n      with:\n        path: ~\/.cache\/pip\n        key: ${{ runner.os }}-pip-${{ hashFiles('**\/requirements.txt') }}\n        restore-keys: |\n          ${{ runner.os }}-pip-\n\n    - name: Cache pytest\n      uses: actions\/cache@v4\n      with:\n        path: .pytest_cache\n        key: ${{ runner.os }}-pytest-${{ hashFiles('**\/*.py') }}\n<\/code><\/pre>\n<h3>Agregando pelusas<\/h3>\n<p>Agregue un trabajo separado para que los problemas de estilo no bloqueen la ejecuci\u00f3n de la prueba:<\/p>\n<pre><code class=\"language-yaml\">  lint:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - uses: actions\/setup-python@v5\n      with:\n        python-version: \"3.11\"\n    - run: pip install flake8 black mypy\n    - run: flake8 src\/ tests\/\n    - run: black --check src\/ tests\/\n    - run: mypy src\/\n<\/code><\/pre>\n<h2>Trampas comunes y c\u00f3mo evitarlas<\/h2>\n<p>Basado en los desaf\u00edos de CI\/CD identificados en el software de investigaci\u00f3n (<a href=\"https:\/\/www.testmuai.com\/blog\/cicd-pipeline-challenges\/\">testmu AI, 2026<\/a>), aqu\u00ed hay errores y soluciones frecuentes.<\/p>\n<h3>Escoma 1: Pruebas que escama<\/h3>\n<p>Las pruebas escamosas pasan a veces y fallan a otras, erosionando la confianza en CI. Son especialmente comunes con:<\/p>\n<ul>\n<li><strong>Condiciones de carrera<\/strong> en pruebas paralelas.<\/li>\n<li><strong>Supuestos de tiempo<\/strong> (por ejemplo, \"espera 1 segundo\").<\/li>\n<li><strong>Aleatoriedad<\/strong> sin semillas fijas.<\/li>\n<\/ul>\n<p><strong>Soluci\u00f3n<\/strong>: Determine todo. Use <code>pytest<\/code> accesorios con <code>scope=\"session\"<\/code> para recursos compartidos. Establezca semillas aleatorias al comienzo de cada prueba:<\/p>\n<pre><code class=\"language-python\">import random\nimport numpy as np\n\ndef setup_function():\n    random.seed(42)\n    np.random.seed(42)\n<\/code><\/pre>\n<h3>Escoma 2: CI que lleva demasiado tiempo<\/h3>\n<p>Si su canalizaci\u00f3n toma horas, los desarrolladores lo pasar\u00e1n por alto.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>:<\/p>\n<ul>\n<li>Dividido en trabajos r\u00e1pidos (en cada compromiso) y lentos (noche).<\/li>\n<li>Cach\u00e9 agresivamente (PIP, capas de Docker, datos de prueba).<\/li>\n<li>Paralelice utilizando estrategias de matriz.<\/li>\n<li>Marque las pruebas de Slow Know con <code>@pytest.mark.slow<\/code> y ejec\u00fatelas por separado.<\/li>\n<\/ul>\n<h3>Escollo 3: Deriva del medio ambiente entre CI y desarrollo<\/h3>\n<p>Las pruebas pasan en CI pero fallan localmente porque los entornos difieren.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: use la misma definici\u00f3n de entorno en todas partes. Docker es ideal: los desarrolladores ejecutan <code>docker-compose run test<\/code> localmente y CI usa el mismo Dockerfile. Alternativamente, use <code>tox<\/code> para administrar m\u00faltiples entornos de manera consistente.<\/p>\n<h3>Escollo 4: Dependencias faltantes o desactualizadas<\/h3>\n<p>CI falla porque se actualiz\u00f3 una dependencia ascendente y se rompi\u00f3 la compatibilidad.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: Dependencias de pines exactamente en <code>requirements.txt<\/code> (<code>package==1.2.3<\/code>), no con rangos (<code>&gt;=1.0<\/code>). Utilice un archivo de bloqueo de dependencia (<code>pip freeze &gt; requirements.txt<\/code>). Actualice regularmente las dependencias de manera controlada (por ejemplo, PRS semanal <code>dependabot<\/code>).<\/p>\n<h3>Escolar 5: Sin monitoreo de rendimiento<\/h3>\n<p>El c\u00f3digo se vuelve m\u00e1s lento con el tiempo, pero solo se nota cuando es catastr\u00f3fico.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: agregue puntos de referencia a CI con <a href=\"https:\/\/asv.readthedocs.io\/\">asv<\/a>. Config\u00farelo para que falle si el rendimiento se degrada m\u00e1s all\u00e1 de un umbral (por ejemplo, un 5% m\u00e1s lento). Consulte <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\">gu\u00eda de la velocidad de Python<\/a> para la implementaci\u00f3n.<\/p>\n<h3>Escolar 6: Ignorar la validaci\u00f3n num\u00e9rica<\/h3>\n<p>Las pruebas usan <code>==<\/code> en flotadores y fallan de forma intermitente, o peor, pasan incorrectamente.<\/p>\n<p><strong>Soluci\u00f3n<\/strong>: use <code>pytest.approx<\/code> y <code>numpy.testing.assert_allclose<\/code> en todas partes. Elija tolerancias basadas en el an\u00e1lisis num\u00e9rico (por ejemplo, el error de discretizaci\u00f3n debe ser O(H\u00b2) para los m\u00e9todos de segundo orden). Justificaci\u00f3n de la tolerancia del documento en las cadenas de documentos de prueba.<\/p>\n<h2>Gu\u00eda de Decisiones: Cu\u00e1ndo usar lo que<\/h2>\n<h3>Selecci\u00f3n de plataforma<\/h3>\n<table>\n<thead>\n<tr>\n<th>Situaci\u00f3n<\/th>\n<th>plataforma recomendada<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>C\u00f3digo alojado en GitHub<\/td>\n<td>Acciones de GitHub<\/td>\n<\/tr>\n<tr>\n<td>C\u00f3digo alojado en Gitlab<\/td>\n<td>GITLAB CI<\/td>\n<\/tr>\n<tr>\n<td>Necesita corredores auto-hospedados (con espacios en el aire)<\/td>\n<td>Gitlab CI (auto-hospedado)<\/td>\n<\/tr>\n<tr>\n<td>Quiere la configuraci\u00f3n m\u00e1s simple<\/td>\n<td>Acciones de GitHub<\/td>\n<\/tr>\n<tr>\n<td>Pipelines complejos multiproyectos<\/td>\n<td>Gitlab CI (Tuber\u00edas padre-hijo)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>estrategia de prueba<\/h3>\n<table>\n<thead>\n<tr>\n<th>Tipo de c\u00f3digo<\/th>\n<th>Enfoque recomendado<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Funciones de pit\u00f3n pura<\/td>\n<td>Pruebas unitarias con PyTest, objetivo de alta cobertura (&gt;90%)<\/td>\n<\/tr>\n<tr>\n<td>Solucionados de PDE<\/td>\n<td>Pruebas de regresi\u00f3n contra soluciones de referencia, pruebas basadas en la propiedad<\/td>\n<\/tr>\n<tr>\n<td>Algoritmos estoc\u00e1sticos<\/td>\n<td>Semilla aleatoria fija + pruebas estad\u00edsticas (media, varianza)<\/td>\n<\/tr>\n<tr>\n<td>Simulaciones grandes (&gt;5 min)<\/td>\n<td>Separe las pruebas lentas, ejecute todas las noches; Usar <code>@pytest.mark.slow<\/code><\/td>\n<\/tr>\n<tr>\n<td>Acoplamiento multicomponente<\/td>\n<td>Pruebas de integraci\u00f3n con peque\u00f1os casos de prueba, validar la correcci\u00f3n de acoplamiento<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>Opci\u00f3n de contenedor<\/h3>\n<table>\n<thead>\n<tr>\n<th>Necesidad<\/th>\n<th>Recomendaci\u00f3n<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>M\u00e1xima reproducibilidad, incluye DEPS de nivel OS<\/td>\n<td>Estibador<\/td>\n<\/tr>\n<tr>\n<td>Gesti\u00f3n de Python, m\u00e1s simple<\/td>\n<td>Medio Ambiente<\/td>\n<\/tr>\n<tr>\n<td>HPC con bibliotecas MPI<\/td>\n<td>conda (o acoplador con <code>--network=host<\/code> y <code>--ipc=host<\/code>)<\/td>\n<\/tr>\n<tr>\n<td>Entorno con espacios de aire<\/td>\n<td>Conda Pack o Docker Guardar\/Cargar<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Integraci\u00f3n de CI con flujos de trabajo de investigaci\u00f3n<\/h2>\n<p>CI no existe de forma aislada. Se conecta con otras herramientas y pr\u00e1cticas.<\/p>\n<h3>Integraci\u00f3n de seguimiento de problemas<\/h3>\n<p>El estado de CI aparece autom\u00e1ticamente en las solicitudes de extracci\u00f3n de GitHub\/Gitlab. Configure las reglas de protecci\u00f3n de rama para requerir el paso de CI antes de la combinaci\u00f3n. Esto garantiza que solo el c\u00f3digo validado entre en la rama principal.<\/p>\n<p>Las publicaciones existentes de MatForge en <a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">seguimiento de problemas<\/a> y <a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">deuda t\u00e9cnica<\/a> complementar CI definiendo c\u00f3mo se gestionan los problemas. CI proporciona verificaci\u00f3n automatizada de que los problemas se solucionan correctamente.<\/p>\n<h3>Conexi\u00f3n de reproducibilidad<\/h3>\n<p>Como se discuti\u00f3 en <a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\">reproducibilidad y su papel en la depuraci\u00f3n<\/a>, CI es una piedra angular de la investigaci\u00f3n reproducible. Se puede confiar en cada confirmaci\u00f3n que pasa CI para producir los mismos resultados en cualquier m\u00e1quina con el mismo entorno. Esto es esencial para:<\/p>\n<ul>\n<li><strong>Reproducibilidad del papel<\/strong>: cuando los revisores piden c\u00f3digo, puede se\u00f1alar un compromiso espec\u00edfico que pas\u00f3 CI y produjo las cifras.<\/li>\n<li><strong>Colaboraci\u00f3n<\/strong>: los contribuyentes externos pueden ejecutar las mismas pruebas localmente.<\/li>\n<li><strong>Mantenimiento a largo plazo<\/strong>: a\u00f1os m\u00e1s tarde, a\u00fan puede reconstruir los resultados de una confirmaci\u00f3n CI-validada.<\/li>\n<\/ul>\n<h3>Flujo de trabajo de revisi\u00f3n de c\u00f3digo<\/h3>\n<p>Empareja CI con revisi\u00f3n de c\u00f3digo obligatoria:<\/p>\n<ol>\n<li>El desarrollador empuja la rama, CI se ejecuta.<\/li>\n<li>Si pasa CI, abra una solicitud de extracci\u00f3n.<\/li>\n<li>Los revisores verifican la l\u00f3gica del c\u00f3digo y aseguran que las pruebas sean adecuadas.<\/li>\n<li>Fusionar solo despu\u00e9s de que CI pase y revisar aprobado.<\/li>\n<\/ol>\n<p>Este flujo de trabajo es est\u00e1ndar en la industria, pero a\u00fan es raro en la investigaci\u00f3n. Implementarlo aumenta dr\u00e1sticamente la calidad del software.<\/p>\n<h2>Temas avanzados<\/h2>\n<h3>Pruebas de matriz para m\u00faltiples dependencias<\/h3>\n<p>Los paquetes cient\u00edficos a menudo dependen de Numpy\/Scipy con un comportamiento espec\u00edfico de versi\u00f3n. Pruebe a trav\u00e9s de una matriz de versiones de Python y dependencias:<\/p>\n<pre><code class=\"language-yaml\">strategy:\n  matrix:\n    python-version: [\"3.9\", \"3.10\", \"3.11\"]\n    numpy-version: [\"1.24\", \"1.25\", \"1.26\"]\n<\/code><\/pre>\n<p>Instale la versi\u00f3n numpy espec\u00edfica en el paso <code>Install dependencies<\/code>:<\/p>\n<pre><code class=\"language-yaml\">    - run: |\n        pip install \"numpy==${{ matrix.numpy-version }}\" scipy\n<\/code><\/pre>\n<p>Esto detecta problemas de compatibilidad con anticipaci\u00f3n.<\/p>\n<h3>Detecci\u00f3n de regresi\u00f3n de rendimiento<\/h3>\n<p>Use <a href=\"https:\/\/asv.readthedocs.io\/\">asv<\/a> para realizar un seguimiento del rendimiento a lo largo del tiempo:<\/p>\n<pre><code class=\"language-yaml\">    - name: Run benchmarks\n      run: |\n        asv run --quick --show-stderr\n      # asv compares against previous commits and reports regressions\n<\/code><\/pre>\n<p>Configure ASV para que falle el trabajo de CI si un punto de referencia es &gt;10% m\u00e1s lento que la ejecuci\u00f3n anterior. Consulte <a href=\"https:\/\/pythonspeed.com\/articles\/speed-unit-tests\/\">art\u00edculo de pythonspeed<\/a> para obtener m\u00e1s detalles.<\/p>\n<h3>Despliegue continuo de documentaci\u00f3n<\/h3>\n<p>CI puede implementar la documentaci\u00f3n autom\u00e1ticamente en las p\u00e1ginas de GitHub:<\/p>\n<pre><code class=\"language-yaml\">  deploy-docs:\n    needs: test  # Only run after tests pass\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions\/checkout@v4\n    - run: pip install -r requirements-docs.txt\n    - run: sphinx-build -b html docs\/ public\/\n    - uses: peaceiris\/actions-gh-pages@v3\n      with:\n        github_token: ${{ secrets.GITHUB_TOKEN }}\n        publish_dir: .\/public\n<\/code><\/pre>\n<p>Esto mantiene la documentaci\u00f3n sincronizada con los cambios de c\u00f3digo.<\/p>\n<h2>Gu\u00edas relacionadas<\/h2>\n<ul>\n<li><strong><a href=\"https:\/\/matforge.org\/reproducibility-and-its-role-in-debugging\/\">La reproducibilidad y su papel en la depuraci\u00f3n<\/a><\/strong>: c\u00f3mo las pr\u00e1cticas de reproducibilidad mejoran la eficiencia de la depuraci\u00f3n.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/tracking-long-term-technical-debt-in-research-software\/\">seguimiento de la deuda t\u00e9cnica a largo plazo en software de investigaci\u00f3n<\/a><\/strong> \u2013 gesti\u00f3n de la calidad del c\u00f3digo a lo largo del tiempo; IC ayuda a prevenir nuevas deudas.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/managing-research-software-through-tickets\/\">administrar software de investigaci\u00f3n a trav\u00e9s de tickets<\/a><\/strong>: integrando CI con flujos de trabajo de seguimiento de problemas.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/why-issue-tracking-is-critical-in-scientific-projects\/\">Por qu\u00e9 el seguimiento de problemas es fundamental en los proyectos cient\u00edficos<\/a><\/strong> \u2013 Comprender la importancia del seguimiento de problemas en el software cient\u00edfico desarrollo.<\/li>\n<li><strong><a href=\"https:\/\/matforge.org\/collaboration-between-developers-and-researchers-turning-innovation-into-scalable-impact\/\">Colaboraci\u00f3n entre desarrolladores y Investigadores<\/a><\/strong>: convertir la innovaci\u00f3n en un impacto escalable a trav\u00e9s del trabajo en equipo efectivo.<\/li>\n<\/ul>\n<h2>Resumen y pr\u00f3ximos pasos<\/h2>\n<p>La integraci\u00f3n continua transforma el software de investigaci\u00f3n de scripts fr\u00e1giles e indocumentados en activos confiables y mantenibles. Los pasos centrales son:<\/p>\n<ol>\n<li>Escriba las pruebas automatizadas con PyTest, usando <code>pytest.approx<\/code> para comparaciones num\u00e9ricas.<\/li>\n<li>Configure una canalizaci\u00f3n de CI (Acciones de GitHub o CI de Gitlab) que se ejecuta en cada solicitud de empuje y extracci\u00f3n.<\/li>\n<li>Use Docker o Conda para garantizar la coherencia del entorno entre CI y el desarrollo.<\/li>\n<li>Agregue informes de cobertura, pelusas y creaci\u00f3n de documentaci\u00f3n.<\/li>\n<li>Supervise el rendimiento con puntos de referencia para capturar regresiones.<\/li>\n<li>Integre CI con sus procesos existentes de seguimiento de problemas y revisi\u00f3n de c\u00f3digo.<\/li>\n<\/ol>\n<p><strong>Acciones inmediatas<\/strong>:<\/p>\n<ul>\n<li>Si no tiene pruebas, comience escribiendo algunas para las funciones m\u00e1s cr\u00edticas. Incluso la cobertura del 20% es mejor que ninguna.<\/li>\n<li>Cree un archivo de configuraci\u00f3n de CI b\u00e1sico (<code>.github\/workflows\/ci.yml<\/code> como se muestra arriba) e iterar.<\/li>\n<li>Arregle las pruebas escamosas de inmediato: erosionan la confianza.<\/li>\n<li>Agregue una \"insignia\" a su L\u00e9ame que muestra el estado de CI (por ejemplo, <img src=\"https:\/\/img.shields.io\/badge\/CI-passing-green\" alt=\"IC\">).<\/li>\n<\/ul>\n<p><strong>Cu\u00e1ndo buscar consulta<\/strong>: si su proyecto involucra dependencias complejas (MPi, c\u00f3digo GPU, bibliotecas patentadas) o tiene &gt;10,000 l\u00edneas de c\u00f3digo, considere una revisi\u00f3n profesional de su configuraci\u00f3n de CI. Ofrecemos <a href=\"\/category\/issue-tracking-tickets-technical-requests\/\">servicios de implementaci\u00f3n personalizados de CI\/CD<\/a> para equipos de investigaci\u00f3n.<\/p>\n<h2>Referencias y lectura adicional<\/h2>\n<ul>\n<li>Wilson, G., et al. (2012). <a href=\"https:\/\/www.ee.columbia.edu\/~dpwe\/e6891\/resources\/1210.0530v3.pdf\">Mejores pr\u00e1cticas de computaci\u00f3n cient\u00edfica<\/a>. <em>PLOS BIOLOG\u00cdA<\/em>.<\/li>\n<li>Boettiger, C. (2015). <a href=\"https:\/\/polaris.imag.fr\/arnaud.legrand\/research\/readings\/acm_sigops_si_rsea\/p71-boettiger.pdf\">Una introducci\u00f3n a Docker para la investigaci\u00f3n reproducible<\/a>. <em>ACM Sigops<\/em>.<\/li>\n<li>Waller, J., et al. (2015). <a href=\"https:\/\/oceanrep.geomar.de\/28433\/1\/SEN2015.pdf\">Incluyendo puntos de referencia de rendimiento en integraci\u00f3n continua<\/a>. <em>Sean<\/em>.<\/li>\n<li><a href=\"https:\/\/imperialcollegelondon.github.io\/ci-best-practice\/\">Integraci\u00f3n continua de software de investigaci\u00f3n<\/a> \u2013 Gu\u00eda de mejores pr\u00e1cticas de Imperial College London.<\/li>\n<li><a href=\"https:\/\/docs.github.com\/actions\/guides\/building-and-testing-python\">Acciones de GitHub: Creaci\u00f3n y prueba de Python<\/a> \u2013 Documentaci\u00f3n oficial.<\/li>\n<li><a href=\"https:\/\/github.com\/swcarpentry\/good-enough-practices-in-scientific-computing\">Pr\u00e1cticas lo suficientemente buenas en inform\u00e1tica cient\u00edfica<\/a> \u2013 Carpinter\u00eda de software.<\/li>\n<\/ul>\n<hr>\n<p><strong>Recuento de palabras<\/strong>: ~2,200<br> <strong>Tiempo de lectura<\/strong>: ~10 minutos<br> <strong>Audiencia de destino<\/strong>: investigadores, estudiantes graduados y desarrolladores que trabajan en proyectos cient\u00edficos de Python que necesitan establecer una calidad automatizada y confiable seguridad.<\/p>\n"},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 13<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>La integraci\u00f3n continua (CI) crea, prueba y valida autom\u00e1ticamente el c\u00f3digo de investigaci\u00f3n en cada confirmaci\u00f3n. Para el software cient\u00edfico, CI es esencial para la reproducibilidad, la detecci\u00f3n temprana de errores y el mantenimiento de la calidad a lo largo del tiempo. Implementar CI: (1) Escribir pruebas automatizadas con PyTest, (2) configurar una canalizaci\u00f3n de [&hellip;]<\/p>\n","protected":false,"raw":""},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_locale":"es_ES","_original_post":"https:\/\/matforge.org\/?p=240","iawp_total_views":0,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-590","post","type-post","status-publish","format-standard","hentry","category-issue-tracking-tickets-technical-requests","es-ES"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas - matforge.org<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas - matforge.org\" \/>\n<meta property=\"og:description\" content=\"Reading Time:  13 minutesLa integraci\u00f3n continua (CI) crea, prueba y valida autom\u00e1ticamente el c\u00f3digo de investigaci\u00f3n en cada confirmaci\u00f3n. Para el software cient\u00edfico, CI es esencial para la reproducibilidad, la detecci\u00f3n temprana de errores y el mantenimiento de la calidad a lo largo del tiempo. Implementar CI: (1) Escribir pruebas automatizadas con PyTest, (2) configurar una canalizaci\u00f3n de [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/\" \/>\n<meta property=\"og:site_name\" content=\"matforge.org\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-22T08:17:32+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/img.shields.io\/badge\/CI-passing-green\" \/>\n<meta name=\"author\" content=\"Priya Nair\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Escrito por\" \/>\n\t<meta name=\"twitter:data1\" content=\"Priya Nair\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data2\" content=\"20 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/\"},\"author\":{\"name\":\"Priya Nair\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\"},\"headline\":\"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas\",\"datePublished\":\"2026-07-22T08:17:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/\"},\"wordCount\":3536,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\",\"articleSection\":[\"Seguimiento de problemas, tickets &amp; Solicitudes T\u00e9cnicas\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/\",\"url\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/\",\"name\":\"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas - matforge.org\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\",\"datePublished\":\"2026-07-22T08:17:32+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#primaryimage\",\"url\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\",\"contentUrl\":\"https:\\\/\\\/img.shields.io\\\/badge\\\/CI-passing-green\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/matforge.org\\\/es\\\/continuous-integration-research-software-automated-testing-validation\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/matforge.org\\\/es\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#website\",\"url\":\"https:\\\/\\\/matforge.org\\\/\",\"name\":\"matforge.org\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/matforge.org\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/matforge.org\\\/#\\\/schema\\\/person\\\/2effd7bc155a5e6357f31dac970c5795\",\"name\":\"Priya Nair\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g\",\"caption\":\"Priya Nair\"},\"sameAs\":[\"http:\\\/\\\/matforge.org\"],\"url\":\"https:\\\/\\\/matforge.org\\\/author\\\/priya-nair\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas - matforge.org","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/","og_locale":"es_ES","og_type":"article","og_title":"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas - matforge.org","og_description":"Reading Time:  13 minutesLa integraci\u00f3n continua (CI) crea, prueba y valida autom\u00e1ticamente el c\u00f3digo de investigaci\u00f3n en cada confirmaci\u00f3n. Para el software cient\u00edfico, CI es esencial para la reproducibilidad, la detecci\u00f3n temprana de errores y el mantenimiento de la calidad a lo largo del tiempo. Implementar CI: (1) Escribir pruebas automatizadas con PyTest, (2) configurar una canalizaci\u00f3n de [&hellip;]","og_url":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/","og_site_name":"matforge.org","article_published_time":"2026-07-22T08:17:32+00:00","og_image":[{"url":"https:\/\/img.shields.io\/badge\/CI-passing-green","type":"","width":"","height":""}],"author":"Priya Nair","twitter_card":"summary_large_image","twitter_misc":{"Escrito por":"Priya Nair","Tiempo de lectura":"20 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#article","isPartOf":{"@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/"},"author":{"name":"Priya Nair","@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795"},"headline":"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas","datePublished":"2026-07-22T08:17:32+00:00","mainEntityOfPage":{"@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/"},"wordCount":3536,"commentCount":0,"image":{"@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#primaryimage"},"thumbnailUrl":"https:\/\/img.shields.io\/badge\/CI-passing-green","articleSection":["Seguimiento de problemas, tickets &amp; Solicitudes T\u00e9cnicas"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/","url":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/","name":"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas - matforge.org","isPartOf":{"@id":"https:\/\/matforge.org\/#website"},"primaryImageOfPage":{"@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#primaryimage"},"image":{"@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#primaryimage"},"thumbnailUrl":"https:\/\/img.shields.io\/badge\/CI-passing-green","datePublished":"2026-07-22T08:17:32+00:00","author":{"@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795"},"breadcrumb":{"@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#primaryimage","url":"https:\/\/img.shields.io\/badge\/CI-passing-green","contentUrl":"https:\/\/img.shields.io\/badge\/CI-passing-green"},{"@type":"BreadcrumbList","@id":"https:\/\/matforge.org\/es\/continuous-integration-research-software-automated-testing-validation\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/matforge.org\/es\/"},{"@type":"ListItem","position":2,"name":"Integraci\u00f3n continua para software de investigaci\u00f3n: pruebas y validaci\u00f3n automatizadas"}]},{"@type":"WebSite","@id":"https:\/\/matforge.org\/#website","url":"https:\/\/matforge.org\/","name":"matforge.org","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/matforge.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"},{"@type":"Person","@id":"https:\/\/matforge.org\/#\/schema\/person\/2effd7bc155a5e6357f31dac970c5795","name":"Priya Nair","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f11e168d4cd2f1eff83cbb851d6cff42d81d88bb59d8831ee77468aa4a5eea88?s=96&d=mm&r=g","caption":"Priya Nair"},"sameAs":["http:\/\/matforge.org"],"url":"https:\/\/matforge.org\/author\/priya-nair\/"}]}},"_links":{"self":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/590","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/comments?post=590"}],"version-history":[{"count":1,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/590\/revisions"}],"predecessor-version":[{"id":699,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/posts\/590\/revisions\/699"}],"wp:attachment":[{"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/media?parent=590"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/categories?post=590"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/matforge.org\/wp-json\/wp\/v2\/tags?post=590"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}