Can anybody point it out, - what is the best approach to run RSpec tests on a Rails API app inside a Docker container (during the container build/run) ?
The aim is to be able to separate the development environment from other ones and to run tests only in development
mode, start Puma server only in staging, production
environments.
What is the right place to put bundle exec rspec
command, - in a separate entrypoint.sh
script, Directly in Dockerfile
, docker-compose.yml
file, or other solutions?
All the Googles results as well as Docker for Rails Developers book by PragProg have no examples and the only way to run the tests theys provide is to run them against an already running container.
Actually, my Dockerfile
looks like that:
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"]
The entrypoint.sh
looks like that:
#!/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
And finally, 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:
Thank you.
You need a test environment that is identical to the container environment where you will run the code for production (use the same image i.e. ). It is fine to run tests on the image after deployment. I wouldn't include them as part of the dockerfile. Apply tests to that environment and when they pass tag the build.
Docker Hub can automatically test changes to your source code repositories using containers. You can enable Autotest on any Docker Hub repository to run tests on each pull request to the source code repository to create a continuous integration testing service.
Running tests by their file or directory names is the most familiar way to run tests with RSpec. RSpec can take a file name or directory name and run the file or the contents of the directory. So you can do: rspec spec/jobs to run the tests found in the jobs directory.
Finally, if you want to run the integration tests, run this command: docker-compose up integration-tests . That command will run the . NET 5.0 and SQL Server containers and then execute the tests.
try
docker-compose run -e "RAILS_ENV=test" api bundle exec rspec spec/link/to/file.rb
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With