yaocloud / yao

Yet Another OpenStack API wrapper
MIT License
35 stars 12 forks source link

bundle exec rake test TEST=test/yao/resources/test_<リソース名>.rb を実行できるようにする #113

Closed hiboma closed 5 years ago

hiboma commented 5 years ago

困っていること

Rakefile bundle exec rake test TEST=test/yao/resources/test_subnet.rb というコマンドで、テストの対象を絞り込んで実行できるようになっているのですが Yao::Resource::* の一部のテストは下記のようなエラーで失敗します

 $ bundle exec rake test TEST=test/yao/resources/test_subnet.rb
/Users/hito/.rbenv/versions/2.6.1/bin/ruby -I"lib:test" -r config -I"/Users/hito/git/yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib" "/Users/hito/git/yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib/rake/rake_test_loader.rb" "test/yao/resources/test_subnet.rb" 
Loaded suite /Users/hito/git/yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib/rake/rake_test_loader
Started
E
============================================================================================================================================================================================================
/Users/hito/git/yao/test/yao/resources/test_subnet.rb:4:in `setup'
Error: test_network(TestSubnet): NoMethodError: undefined method `pool' for nil:NilClass
============================================================================================================================================================================================================
E
============================================================================================================================================================================================================
/Users/hito/git/yao/test/yao/resources/test_subnet.rb:4:in `setup'
Error: test_subnet(TestSubnet): NoMethodError: undefined method `pool' for nil:NilClass
============================================================================================================================================================================================================
E
============================================================================================================================================================================================================
/Users/hito/git/yao/test/yao/resources/test_subnet.rb:4:in `setup'
Error: test_tenant(TestSubnet): NoMethodError: undefined method `pool' for nil:NilClass
============================================================================================================================================================================================================

Finished in 0.005076 seconds.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3 tests, 0 assertions, 0 failures, 3 errors, 0 pendings, 0 omissions, 0 notifications
0% passed
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
591.02 tests/s, 0.00 assertions/s
rake aborted!
Command failed with status (1): [ruby -I"lib:test" -r config -I"/Users/hito/git/yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib" "/Users/hito/git/yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib/rake/rake_test_loader.rb" "test/yao/resources/test_subnet.rb" ]
/Users/hito/.rbenv/versions/2.6.1/bin/bundle:23:in `load'
/Users/hito/.rbenv/versions/2.6.1/bin/bundle:23:in `<main>'
Tasks: TOP => test
(See full trace by running task with --trace)

なぜ失敗するのか?

これの原因は、個別でのテスト実行時に Yao.default_client が初期化されていないことです.

でも、bundle exec rake test だとテスト成功するじゃん?

個別に実行するとテストはこけるのに、 bundle exec rake test では全部のテストが成功するのか? という疑問があがるでしょう

原因は?

これは bundle exec rake test の際に、 別のテストである test/yao/test_auth.rb で Yao.default_client が初期化された状態が Yao::Resoruce:: のテストでも副作用を持っている のが原因(?) です

class TestAuth < Test::Unit::TestCase
  include AuthStub

  def setup
    @auth_url = "http://endpoint.example.com:12345/v2.0"
    username = "udzura"
    tenant   = "example"
    password = "XXXXXXXX"

    👉 stub_auth_request(@auth_url, username, password, tenant)

    👉 Yao.config.set :auth_url, @auth_url
    👉 @token = Yao::Auth.new(tenant_name: tenant, username: username, password: password)
  end

👉 のコードで生成された「状態」が、Yao::Resources::* に副作用 (依存) をもたらしているということです

Yao.configure, Yao.default_client はグローバルに作用するクラス/オブジェクトなので、初期化を明示的に行わないとないとテスト間で暗黙の依存関係を生んでしまいます.

テスト間の依存によって意図しないテストのこけ方/ 通り方をするので注意が必要だと思っています.

この PR で直すこと

test/yao/test_auth.rb に依存しなくても Yao::Resource::* をテストできるようにします

具体的には、Yao::Resource::* のテスト内で AuthStub.stub_client というヘルパーを呼び出して Yao.configure, Yao.default_client を逐一初期化し 単体で実行/通せるように修正します

 $ bundle exec rake test TEST=test/yao/resources/test_subnet.rb
/Users/hito/.rbenv/versions/2.6.1/bin/ruby -I"lib:test" -r config -I"/Users/hito/git/__yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib" "/Users/hito/git/__yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib/rake/rake_test_loader.rb" "test/yao/resources/test_subnet.rb" 
Loaded suite /Users/hito/git/__yao/vendor/bundle/ruby/2.6.0/gems/rake-10.5.0/lib/rake/rake_test_loader
Started
..
Finished in 0.038423 seconds.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 tests, 13 assertions, 0 failures, 0 errors, 0 pendings, 0 omissions, 0 notifications
100% passed
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
52.05 tests/s, 338.34 assertions/s
pyama86 commented 5 years ago

最高です!

hiboma commented 5 years ago

Thank you ! ^^