Railtie 및 Generator의 Spec 테스트
Spec 시험을 못 본 이유.
Rails는 initialize를 여러 번 사용할 수 없습니다.
Rails3.2에서 Rails::Application이 두 개 이상의 하위 클래스를 상속하면 오류가 발생합니다.app = Class.new(::Rails::Application)
app = Class.new(::Rails::Application)
> RuntimeError: You cannot have more than one Rails::Application
여러 번 불러서는 안 된다initialize!
.app = Class.new(::Rails::Application)
app.initialize!
app.initialize!
> RuntimeError: Application has been already initialized.
Rails4에서는 이 문제가 발생하지 않았지만 3.2를 테스트 대상에서 삭제하기에는 너무 이르다.
공략 방법
그리고 오랜 고민 끝에 공략했다.
rspec 내에서 fork
포크 과정에서 테스트를 진행하면 인티리얼즈 레일즈에서 가능합니다.
이때 반드시 고려해야 할 것은 다음과 같은 두 가지이다
app = Class.new(::Rails::Application)
app = Class.new(::Rails::Application)
> RuntimeError: You cannot have more than one Rails::Application
app = Class.new(::Rails::Application)
app.initialize!
app.initialize!
> RuntimeError: Application has been already initialized.
그리고 오랜 고민 끝에 공략했다.
rspec 내에서 fork
포크 과정에서 테스트를 진행하면 인티리얼즈 레일즈에서 가능합니다.
이때 반드시 고려해야 할 것은 다음과 같은 두 가지이다
Coverage 통합
Coveralls
원래는 각 루비와gem의 Coverage를 합친 것으로 포크라도 합칠 수 있었다.로컬에서 단순cov를 사용하는 경우 프로세스 간에 서로 커버된 결과를 덮어쓰기 때문에 결과가 올바르지 않습니다.
스펙 테스트에 다음과 같은 내용을 써서 해결합니다.
spec/spec_helper.rb
resultset_path = SimpleCov::ResultMerger.resultset_path
FileUtils.rm resultset_path if File.exists? resultset_path
SimpleCov.use_merging true
SimpleCov.at_exit do
SimpleCov.command_name "fork-#{$$}"
SimpleCov.result.format!
end
우선SimpleCov.use_merging true
, 이것은 이전에 실행된coverage의 결과를 합병하는 설정이다.합병
cucumber
테스트와rspec
테스트 등에 사용됩니다.단, rspec의 프로세스 fork가 되면, 이렇게 병합된 키도 같기 때문에 덮어씁니다.
따라서 비결은
SimpleCov
의at_exit
를 고리로 합치기 전에 버튼을 바꾸는 것이다.SimpleCov.at_exit do
SimpleCov.command_name "fork-#{$$}"
SimpleCov.result.format!
end
그리고 이렇게 되면 과거의 테스트도 합병되어 시작할 때 초기화된다.resultset_path = SimpleCov::ResultMerger.resultset_path
FileUtils.rm resultset_path if File.exists? resultset_path
이렇게 하면 포크의 rspec의 Coverage를 순조롭게 합병할 수 있습니다!테스트 결과의 sync
rspec 코드를 상당히 읽었어요.
spec/support/fork_helper.rb
shared_context 'forked spec' do
around do |example|
read, write = IO.pipe
pid = fork do
$stdout.sync = true
$stderr.sync = true
res = example.run
Marshal.dump(res, write)
write.close
end
Process.waitpid2 pid
res = Marshal.load(read)
example.example.send :set_exception, res if res && !res.empty?
read.close
end
end
spec/rack/dev-mark/railtie_spec.rbrequire 'spec_helper'
describe Rack::DevMark::Railtie do
include_context 'forked spec'
before do
@app = Class.new(::Rails::Application)
@app.config.active_support.deprecation = :stderr
@app.config.eager_load = false
end
context "rack_dev_mark enable" do
before do
@app.config.rack_dev_mark.enable = true
@app.initialize!
end
it 'inserts the middleware' do
expect(@app.middleware.middlewares).to include(Rack::DevMark::Middleware)
end
end
end
이런 느낌의 코드로 돌파했다.프로세스는 fork의 프로세스와 파이프를 교환하여 테스트 결과를 파이프로 부모 프로세스에 보내는 테스트 결과입니다.
그리고 포크 프로세스의 결과를 포크의 결과로 처리하는 데 성공했다.
그다음에 풀록!
Rails4 이상을 지원하면 여러 앱을 제작할 수 있고, 레일티와 generator의 테스트도 간단하다.
Reference
이 문제에 관하여(Railtie 및 Generator의 Spec 테스트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/dtaniwaki/items/ddfafcdfb0ee670410cb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)