Picky: Integration Testing Tweet
This is a post in the Picky series on its workings.
Let me start off by saying that it’s embarrassing that this topic is discussed only as Picky 2.3.0 is released. Especially as a proponent of test driven design. (Picky has 1300 tests and 50% more spec code than normal code)
So let’s check out how you can write the most beautifully tested Picky servers. Oh yeah.
Doin’ it
As of 2.3.0, if you use picky generate unicorn_server
, you’ll get a rake spec
for free which already runs integration specs on the example data.
Let’s look at the example, and after that, at each separate part.
require 'spec_helper'
require 'picky-client/spec'
describe 'Integration Tests' do
before(:all) do
Indexes.index_for_tests
Indexes.load_from_cache
end
let(:books) { Picky::TestClient.new(PickySearch, :path => '/books') }
# Testing a count of results.
#
it { books.search('a s').total.should == 42 }
# Testing a specific order of result ids.
#
it { books.search('alan').ids.should == [259, 307, 449] }
# Testing an order of result categories.
#
it { books.search('alan').should have_categories(['author'], ['title']) }
it { books.search('alan p').should have_categories(['author', 'title'], ['title', 'author']) }
end
It starts off like any RSpec file, by requiring spec_helper
. Then we require the spec part of the picky client.
What does it do? It provides us with the testing counterpart of the client’s Picky::Client
, which is Picky::TestClient
.
The test client works almost exactly like the real client, with the exception that the test client never sends HTTP requests, but uses your app’s Rack adapter. But more about that later.
require 'spec_helper'
require 'picky-client/spec'
Next, we set up the environment for the tests, i.e. get the indexes up and running.
Indexes.index_for_tests
is a special index method that does not fork and runs silently (to not disturb the deadly test bugs that trawl the area).
before(:all) do
Indexes.index_for_tests
Indexes.load_from_cache
end
Indexes.load_from_cache
loads the generated index (caches) into memory (or just leaves them alone in Redis).
Now we’re ready to do some testing!
let(:books) { Picky::TestClient.new(PickySearch, :path => '/books') }
This sets up an accessor for your tests. You give the TestClient
your Application’s constant, PickySearch
here, and give it the path to send queries to, here '/books'
. This only works if you route
the path '/books'
to a Search
in your application/app.rb
, of course.
That’s it! Easy so far, right?
# Testing a count of results.
#
it { books.search('a s').total.should == 42 }
books
is the test client we defined with the let
, above. As with the normal Picky::Client
, it offers a #search(text, options = {})
method.
As return value, we get a hash with the result data. However, it has already been enriched through Picky::Convenience
, which you might know if you’ve set up a client webapp already.
This means we get a #total
method, but also #ids
, #empty?
, #allocations
and more which are less useful for testing.
So to test the count of results, just use #total
on the result of the search.
To get a sorted array of the top ids, use – surprise – #ids
.
# Testing a specific order of result ids.
#
it { books.search('alan').ids.should == [259, 307, 449] }
Also useful is to test if the category combination boosting/weights are correct. So if author
, like in the first example below, should be boosted, use the have_categories
matcher to check for that.
# Testing an order of result categories.
#
it { books.search('alan').should have_categories(['author'], ['title']) }
it { books.search('alan p').should have_categories(['author', 'title'], ['title', 'author']) }
And that’s how you do integration testing in Picky.
About time. Test away!
spec_helper and Rakefile
This is what your spec/spec_helper.rb
would look like:
ENV['PICKY_ENV'] = 'test'
require 'picky'
SearchLog = Loggers::Search.new ::Logger.new(STDOUT)
puts "Using STDOUT as test log."
Loader.load_application
In the Rakefile
just add
require 'rspec'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new :spec
if you haven’t done this already.
Sidenote
Should any RSpec vs. Test::Unit controversy erupt around Picky… just kidding ;)
Conclusion
So we’ve seen
- how you do integration testing in Picky
Hope you learnt something new!
Next Picky: Environmental ConsiderationsShare
Previous Picky 2.2.0