【问题标题】:Docker, Docker compose - how to run RSpec testsDocker, Docker compose - 如何运行 RSpec 测试
【发布时间】:2019-07-12 13:46:27
【问题描述】:

谁能指出,-在 Docker 容器内的 Rails API 应用程序上运行 RSpec 测试的最佳方法是什么(在容器构建/运行期间)?

目标是能够将开发环境与其他环境分开,只在development模式下运行测试,只在staging, production环境下启动Puma服务器。

bundle exec rspec 命令放在什么位置合适? - 在单独的entrypoint.sh 脚本中,直接在Dockerfiledocker-compose.yml 文件中或其他解决方案中?

所有 Google 的结果以及 PragProg 的 Docker for Rails Developers 书都没有示例,运行他们提供的测试的唯一方法是针对已经运行的容器运行它们。

其实我的Dockerfile是这样的:

FROM ruby:2.6.1

RUN apt-get update -yqq
RUN apt-get install -yqq --no-install-recommends build-essential zip unzip libpq-dev libaio1 libaio-dev nodejs

ENV APP_HOME=/usr/src/app
ENV BUNDLE_PATH /gems

COPY . $APP_HOME

RUN echo "gem: --no-rdoc --no-ri" >> ~/.gemrc

WORKDIR $APP_HOME
RUN gem update --system
RUN gem install bundler
RUN bundle install

RUN ["chmod", "+x", "entrypoint.sh"]
CMD ["./entrypoint.sh"]

entrypoint.sh 看起来像这样:

#!/bin/bash

set -e

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi

./wait-for-it.sh ${DATABASE_HOST}:${DATABASE_PORT}

if [ -z "$RAILS_ENV" ]; then
  echo "RAILS_ENV variable is not set, will use development by default"
  bundle exec rails db:reset
  bundle exec rails db:migrate
  bundle exec rspec
else
  bundle exec rails s -e $RAILS_ENV -p 3000 -b 0.0.0.0
fi

最后,docker-compose.yml

version: '3.3'

services:
  api:
    build: ../..
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
      - gem_cache:/gems
    env_file:
      - ./env/database.env
      - ./env/web.env
    depends_on:
      - database
    # Keeps the stdin open, so we can attach to our app container's process and
    # do stuff such as `byebug` or `binding.pry`:
    stdin_open: true
    # Allows us to send signals (CTRL+C, CTRL+P + CTRL+Q) into the container
    tty: true
  database:
    image: postgres:9.6
    env_file:
      - ./env/database.env
    volumes:
      - db-data:/var/lib/postgresql/data
    ports:
      - 5432:5432
volumes:
  db-data:
  gem_cache:

谢谢。

【问题讨论】:

  • 这实际上不起作用,或者这是一个问题,您如何编写它是否可以接受?
  • @streetlogics,它实际上不起作用,数据库主机不可访问。它只是设置的摘录。因为镜像是构建并推送到 Rancher 的。所以两者兼而有之:要么这是一种可接受的方式,要么不是。也许要运行测试,我们不必使用 Docker,而是使用其他管道或类似的东西,这取决于可用的工具(GitLab、GitHub 等)。我将创建一个单独的经典 Docker 应用程序,看看它是否有效。
  • 就我从多个帖子中获得的信息而言,我得出的结论是,在 Docker 容器中运行测试并不是一个好的步骤,有时它可能需要很长时间,而你的映像会花费很多时间时间也是建造的。构建镜像的主要目的是提供一个类似生产的环境,而不需要在你的机器上安装任何东西。最好使用不同的管道在开发分支中运行测试,然后构建不依赖于开发/测试的生产/暂存映像。
  • 我以前做过这个管道——它需要单独的 docker-compose 文件,以便“测试”环境在运行期间获得它自己的数据库构建和种子,而不是依赖于预先存在的数据库。这是完全可能的。你提到的当然有限制,但同时,特别是如果我正在运行集成测试,我希望测试再次运行一个更好地模仿我的生产环境而不是我的开发环境的应用程序环境,特别是如果我我在生产中使用 Docker。

标签: ruby-on-rails docker rspec-rails


【解决方案1】:

试试

docker-compose run -e "RAILS_ENV=test" api bundle exec rspec spec/link/to/file.rb

【讨论】:

    【解决方案2】:

    你应该在你的主机上运行bundle exec rspec你运行任何 Docker 命令之前。

    # Install and test the application locally
    bundle install
    bundle exec rspec
    bundle exec rails server
    
    # Great, it works; now package and run it in Docker
    docker build -t ... .
    docker run -p ... --net ... --name ... ...
    

    您可能会发现设置具有一些依赖项的部分 Docker Compose 环境很有用。您可以在运行测试之前启动它们。

    docker-compose up -d mysql redis
    # Change config/settings.yml and config/database.yml to point at localhost
    bundle exec rails rspec
    

    尝试在 Docker 中运行测试会遇到两个实际问题。

    1. 如果您尝试在 Dockerfile 中运行测试,则无法访问可能在同一 docker-compose.yml 文件中定义的任何其他服务。在 Active Record 的特殊情况下,应用程序实际上无法启动,而且您甚至无法在没有可用数据库的情况下运行单元类型测试。所以你不能真正在 Dockerfile 中运行测试。

    2. 如果您尝试在应用程序启动时运行测试,您需要在 Docker 镜像中包含所有测试依赖项(这会增加您的镜像大小和潜在的安全攻击面)。您需要决定是始终运行测试(这可能会显着增加启动时间)还是只运行它们(这在普通的 Docker Compose 设置中很尴尬,但在更强大的 CI 系统中非常简单)。

    【讨论】:

    • 我更新了评论,你可以看到我正在使用wait-for-it脚本来检查数据库是否可用。
    • 感谢您的回复,它证实了我关于需要在 Docker 映像中集成开发、测试环境的想法,——它太长了。
    猜你喜欢
    • 2021-07-26
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 2021-12-01
    • 2017-12-18
    相关资源
    最近更新 更多