news 2026/7/5 15:05:19

AI 全栈开发实战(11):CI/CD 与自动化测试——从 pytest 到 GitHub Actions

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI 全栈开发实战(11):CI/CD 与自动化测试——从 pytest 到 GitHub Actions

AI 项目的 CI/CD 怎么做?自动化测试和部署流水线搭建

代码写完了,怎么保证每次修改不会破坏已有功能?怎么自动部署到服务器?

本篇回答三个问题:

  1. 怎么写 AI 项目的自动化测试?
  2. CI/CD 流水线怎么配?
  3. 部署自动化怎么做?

怎么写 AI 项目的自动化测试?

后端测试(pytest)

# backend/tests/test_api.pyimportpytestfromhttpximportASGITransport,AsyncClientfromapp.mainimportapp@pytest.fixturedefclient():transport=ASGITransport(app=app)returnAsyncClient(transport=transport,base_url="http://test")@pytest.mark.asyncioasyncdeftest_health_check(client):"""健康检查接口测试。"""response=awaitclient.get("/api/health")assertresponse.status_code==200assertresponse.json()["status"]=="ok"@pytest.mark.asyncioasyncdeftest_register(client):"""用户注册接口测试。"""importrandom email=f"test{random.randint(10000,99999)}@example.com"response=awaitclient.post("/api/auth/register",json={"email":email,"password":"test123456","nickname":"测试用户",})assertresponse.status_code==201data=response.json()assert"access_token"indataassertdata["user"]["email"]==email@pytest.mark.asyncioasyncdeftest_login_invalid_password(client):"""错误密码登录测试。"""response=awaitclient.post("/api/auth/login",json={"email":"nonexist@example.com","password":"wrong",})assertresponse.status_code==401@pytest.mark.asyncioasyncdeftest_create_knowledge_base(client):"""创建知识库测试(需先登录)。"""# 先注册importrandom email=f"kb{random.randint(10000,99999)}@example.com"reg=awaitclient.post("/api/auth/register",json={"email":email,"password":"test123456","nickname":"test"})token=reg.json()["access_token"]# 创建知识库response=awaitclient.post("/api/knowledge-bases",json={"name":"测试知识库","description":"测试描述"},headers={"Authorization":f"Bearer{token}"})assertresponse.status_code==201assertresponse.json()["name"]=="测试知识库"

测试数据库隔离

测试不应该用生产数据库。用 pytest 的 fixture 隔离:

# backend/tests/conftest.pyimportpytestfromapp.databaseimportengine,Basefromsqlalchemy.ext.asyncioimportcreate_async_engine@pytest.fixture(autouse=True)asyncdefsetup_db():"""每个测试用例使用独立的数据库会话。"""# 使用 SQLite 内存数据库进行测试test_engine=create_async_engine("sqlite+aiosqlite:///:memory:")asyncwithtest_engine.begin()asconn:awaitconn.run_sync(Base.metadata.create_all)yieldawaittest_engine.dispose()

CI/CD 流水线怎么配?

GitHub Actions 配置

# .github/workflows/ci.ymlname:CIon:push:branches:[main,develop]pull_request:branches:[main]jobs:test:runs-on:ubuntu-latestservices:postgres:image:postgres:16-alpineenv:POSTGRES_DB:know_testPOSTGRES_USER:knowPOSTGRES_PASSWORD:know_testports:-5432:5432options:--health-cmd pg_isready--health-interval 10s--health-timeout 5s--health-retries 5redis:image:redis:7-alpineports:-6379:6379options:--health-cmd "redis-cli ping"--health-interval 10s--health-timeout 5s--health-retries 5steps:-uses:actions/checkout@v4-name:Set up Pythonuses:actions/setup-python@v5with:python-version:"3.11"-name:Install dependenciesrun:|cd backend pip install -r requirements.txt pip install pytest httpx pytest-asyncio-name:Run testsenv:DATABASE_URL:postgresql+asyncpg://know:know_test@localhost:5432/know_testREDIS_URL:redis://localhost:6379/0run:|cd backend pytest tests/ -v --cov=app --cov-report=term-missing

代码质量检查

# 在 ci.yml 中加一个 lint joblint:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-uses:actions/setup-python@v5with:python-version:"3.11"-run:pip install ruff mypy-run:ruff check backend/-run:mypy backend/--ignore-missing-imports

Docker 镜像构建与推送

build:needs:[test,lint]runs-on:ubuntu-latestif:github.ref == 'refs/heads/main'steps:-uses:actions/checkout@v4-name:Set up Docker Buildxuses:docker/setup-buildx-action@v3-name:Log in to Docker Hubuses:docker/login-action@v3with:username:${{secrets.DOCKER_USERNAME}}password:${{secrets.DOCKER_PASSWORD}}-name:Build and push backenduses:docker/build-push-action@v5with:context:./backendpush:truetags:yourdockerhub/know-backend:latestcache-from:type=ghacache-to:type=gha,mode=max-name:Build and push frontenduses:docker/build-push-action@v5with:context:./frontendpush:truetags:yourdockerhub/know-frontend:latestcache-from:type=ghacache-to:type=gha,mode=max

部署自动化怎么做?

自动部署到服务器

deploy:needs:[build]runs-on:ubuntu-latestif:github.ref == 'refs/heads/main'steps:-name:Deploy via SSHuses:appleboy/ssh-action@v1.0.3with:host:${{secrets.DEPLOY_HOST}}username:${{secrets.DEPLOY_USER}}key:${{secrets.DEPLOY_KEY}}script:|cd /opt/know docker compose pull docker compose up -d --force-recreate docker image prune -f

完整 CI/CD 流水线

提交代码 → 自动测试 → 代码检查 → 构建镜像 → 推送到仓库 → 自动部署 git push pytest ruff docker docker push ssh deploy

本地测试常用命令

# 运行所有测试cdbackend&&pytest tests/-v# 运行单个测试文件pytest tests/test_api.py-v# 运行单个测试函数pytest tests/test_api.py::test_register-v# 带覆盖率报告pytest tests/--cov=app --cov-report=html# 代码格式检查ruff check app/# 类型检查mypy app/

总结

环节工具作用
单元测试pytest + httpx保证接口正确性
代码质量ruff + mypy保证代码规范
CIGitHub Actions自动运行测试和检查
CDDocker + SSH自动构建和部署

本文是《AI 全栈开发实战——做一个真正的产品》系列的第 11 篇。


如果觉得有用,欢迎点赞 + 收藏 + 关注。这个系列从产品定义写到生产上线,全部代码开源可运行,带你从零交付一个真正的 AI 产品。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 15:04:17

Codex App 26.616 新功能教程:Record Replay 录制与回放使用指南

Codex App 26.616 新功能教程:Record & Replay 录制与回放使用指南 SEO关键词: Codex App 26.616、Codex Record Replay、Codex录制与回放、Codex技能录制、Codex Computer Use、Codex插件、Codex工作流自动化、OpenAI Codex教程 最近 OpenAI 发布了…

作者头像 李华
网站建设 2026/7/5 15:03:39

MS10-018漏洞深度剖析:从内存破坏原理到Metasploit实战利用

1. 项目概述:一次针对经典浏览器漏洞的深度剖析今天想和大家深入聊聊一个在渗透测试学习和实战演练中绕不开的经典案例:针对MS10-018漏洞的浏览器攻击。这个漏洞编号对于很多老手来说,可能承载着一段“远古”的记忆,但对于希望系统…

作者头像 李华
网站建设 2026/7/5 14:57:22

F3闪存检测工具:3步识别扩容盘,保护你的数据安全

F3闪存检测工具:3步识别扩容盘,保护你的数据安全 【免费下载链接】f3 F3 - Fight Flash Fraud 项目地址: https://gitcode.com/gh_mirrors/f3/f3 F3(Fight Flash Fraud)是一款专业的开源闪存检测工具,专门用于识…

作者头像 李华
网站建设 2026/7/5 14:56:13

26. 【C语言】编译前的“文本大师”:预处理器指令

从第一个 hello.c 开始&#xff0c;我们几乎每个程序开头都有 #include <stdio.h>。你一直知道它是“引入头文件”&#xff0c;但你可能没深想过&#xff1a;那个 # 到底是什么&#xff1f;#include 和 #define 又是怎么工作的&#xff1f; 它们都归属于 C 语言的预处理…

作者头像 李华