1

CodeShip でアプリをビルドできるようにしようとしています。

Travis CI を使用すると (いくつかの統合テストを除きますが、これは別の話です)、もちろん私のローカル マシンでうまくビルドされます。ただし、CodeShipping の場合、同じコードを特定の 1 か所だけでテストするのに失敗します。失敗が機能テストに関するものであったとしても驚かないでしょうが、コントローラーの仕様内で失敗します!

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
4

0 に答える 0