使用 FastAPI 在 github 操作上运行测试失败,因为它首先尝试连接到托管数据库

问题描述 投票:0回答:1

我正在尝试使用 github actions 设置 CI 管道,但失败了。我认为它失败的原因是 FastAPI 尝试首先与生产数据库建立连接,然后运行数据库覆盖。另一种理论是容器可以是“沙箱”,这会阻止与生产数据库的连接。

这是我的工作流程代码:

name: Python application

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      postgres:
        # Docker Hub image
        image: postgres
        # Provide the password for postgres
        env:
          POSTGRES_USER: test
          POSTGRES_DB: test
          POSTGRES_PASSWORD: testing
        ports:
          - 5432:5432
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
    - uses: actions/checkout@v2
    - name: Set up Python 3.9
      uses: actions/setup-python@v2
      with:
        python-version: 3.9
    - name: Install dependencies
      run: |
        cd backend
        python -m pip install --upgrade pip
        pip install flake8 pytest
        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
    - name: Lint with flake8
      run: |
        # stop the build if there are Python syntax errors or undefined names
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
    - name: Test with pytest
      env:
        NAME: ${{ secrets.NAME }}
        USERNAME: ${{ secrets.USERNAME }}
        PASSWORD: ${{ secrets.PASSWORD }}
        PORT: ${{ secrets.PORT }}
        URL: ${{ secrets.URL }}
      run: |
        cd backend
        python -m pytest tests/

这是在 FastAPI 中设置测试环境的代码:

from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database import Base, get_db
from main import app 
import json

SQLALCHEMY_DATABASE_URL = 'postgresql://test:testing@localhost:5432/test'

engine = create_engine(
    SQLALCHEMY_DATABASE_URL, connect_args={}
)

TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)

def override_get_db():
    try:
        db = TestingSessionLocal()
        yield db
    finally:
        db.close()

app.dependency_overrides[get_db] = override_get_db

client = TestClient(app)

这是错误:

E   sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: No such file or directory
E       Is the server running locally and accepting
E       connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

从错误堆栈跟踪中我可以看到错误从我的代码中的这一行开始,女巫是与生产数据库连接的代码的一部分。它位于 main.py

models.Base.metadata.create_all(bind=engine)

运行服务器工作正常,在本地运行测试也工作正常,只有通过 github 操作运行测试时才会出现问题。 FastAPI 不应该首先运行覆盖吗?

postgresql continuous-integration pytest github-actions fastapi
1个回答
0
投票

失败是因为 CI 运行器上没有运行 postgres 实例。因此,当您的应用程序尝试到达

postgresql://test:testing@localhost:5432/test
时,它无法找到它。此外,尝试将外部世界中的产品(或任何环境)数据库连接到运行器也是个坏主意。另一种方法是使用
testing.postgresql
。这将在临时目录中创建一个数据库。但为此,您可能需要通过应用程序的 docker 映像或 CI yml 文件将
libpq-dev
gcc
安装在运行程序中。

© www.soinside.com 2019 - 2024. All rights reserved.