Docker,Docker compose - 如何运行 RSpec 测试

bel*_*ros 7 ruby-on-rails rspec-rails docker

任何人都可以指出 - 在 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"]
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

最后,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:
Run Code Online (Sandbox Code Playgroud)

谢谢你。

小智 9

尝试

docker-compose run -e "RAILS_ENV=test" api bundle exec rspec spec/link/to/file.rb
Run Code Online (Sandbox Code Playgroud)


Dav*_*aze 2

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

# 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 ... ...
Run Code Online (Sandbox Code Playgroud)

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

docker-compose up -d mysql redis
# Change config/settings.yml and config/database.yml to point at localhost
bundle exec rails rspec
Run Code Online (Sandbox Code Playgroud)

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

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

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