Тест контроллера CodeShip rspec не пройден
Я пытаюсь сделать мое приложение готовым к использованию через CodeShip.
Он прекрасно работает при использовании Travis CI (за исключением некоторых интеграционных тестов, но это уже другая история) и, конечно, на моей локальной машине. Однако тот же код не может быть проверен только в одном определенном месте, если CodeShipping. Я бы не удивился, если бы сбой был связан с тестированием функций, но он не удался в спецификации контроллера!
Ошибка CodeShip:
Failures:
1) ParrotsController GET #index with filters returns by id
Failure/Error: expect(json.count).to eq 1
expected: 1
got: 0
(compared using ==)
# ./spec/controllers/parrots_controller_spec.rb:117:in `block (4 levels) in <top (required)>'
Это так странно, потому что ниже и выше есть почти одинаковые тесты. Я не удивлюсь, если бы проблема была в javascript и функциях, но это всего лишь тест контроллера! Я действительно расстроен.
Команды настройки CodeShip:
npm install -g bower
bower install
rvm use 2.2.3 --install
bundle install
export RAILS_ENV=test
bundle exec rake db:migrate --trace
bundle exec rake db:test:prepare
bundle exec rake db:schema:load
Тестовые команды CodeShip:
export CODECLIMATE_REPO_TOKEN=blahblah
xvfb-run -a bundle exec rspec spec
Код действия
def index
# TODO Below code is not ideal, needs optimizing
begin
p = Parrot.all # I could use @parrots everywhere, but 'p' is shorter for bunch of selects
[:ancestors, :descendants, :children, :parents].each do |selector|
(p = p & Parrot.find(params[selector].to_i).try(selector)) if params[selector]
end
# Temporary solution for nil elements within 'p' when wrong 'selector' ids given
p.each { |_p| p.delete _p if _p.nil? } if p
(p = p.select { |_p| _p.age >= params[:age_min].to_i }) if params[:age_min]
(p = p.select { |_p| _p.age <= params[:age_max].to_i }) if params[:age_max]
(p = p.select { |_p| _p.sex == params[:sex] }) if params[:sex]
(p = p.select { |_p| _p.id == params[:id].to_i }) if params[:id]
(p = p.select { |_p| _p.tribal == (params[:tribals] == 'true' || params[:tribal] == true) }) unless params[:tribals].nil?
(p = p.select { |_p| _p.color == Color.find_by_name(params[:color]) }) unless params[:color].blank?
(p = p.select { |_p| _p.name.downcase.include?(params[:name].downcase) }) unless params[:name].blank?
@parrots = p
rescue Exception => e
@error = e
end
respond_to do |format|
format.json do
render layout: false, status: (@error ? :unprocessable_entity : :ok)
end
end
end
index.json.jbuilder
if @error
json.error @error.to_s
else
json.array! @parrots, :id, :name, :age, :color_id, :sex, :tribal, :color_hex
end
Тестовый код
describe 'GET #index' do
before do
@grandmother = create(:parrot, name: 'FooMother', age: 40, sex: 'female', tribal: true, color_name: 'green')
@grandfather = create(:parrot, name: 'FooFather', age: 50, sex: 'male', tribal: true, color_name: 'green')
@mother = create(:parrot, name: 'Foo', age: 20, sex: 'female', tribal: true, color_name: 'red', father_id: @grandfather.id, mother_id: @grandmother.id)
@father = create(:parrot, name: 'Bar', age: 30, sex: 'male', tribal: true, color_name: 'red')
@son = create(:parrot, name: 'FoobarSon', age: 3, sex: 'male', tribal: true, color_name: 'green', father_id: @father.id, mother_id: @mother.id)
@daughter = create(:parrot, name: 'FoobarDaughter', age: 5, sex: 'female', tribal: false, color_name: 'blue', father_id: @father.id, mother_id: @mother.id)
end
context 'no filters' do
it ' returns all' do
get :index, format: :json
expect(json.count).to eq 6
end
end
context 'with filters' do
it 'returns older than' do
get :index, format: :json, age_min: 20
expect(json.count).to eq 4
expect(json.collect{ |p| p['id'] }).to include @grandmother.id
end
it 'returns younger than' do
get :index, format: :json, age_max: 30
expect(json.count).to eq 4
expect(json.collect{ |p| p['id'] }).to_not include @grandmother.id
end
it 'returns with age in range' do
get :index, format: :json, age_min: 20, age_max: 40
expect(json.count).to eq 3
expect(json.collect{ |p| p['id'] }).to_not include @grandfather.id
expect(json.collect{ |p| p['id'] }).to_not include @son.id
end
it 'returns by id' do # todo doesn't pass in CodeShip only. Why?!
get :index, format: :json, id: 2
expect(json.count).to eq 1
expect(json.collect{ |p| p['name'] }).to include @grandfather.name
end
# Other tests...
end
end