Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Launching a web server inside ruby tests

I'm writing a library to wrap tsung's functionality in a way that can be better used by rails applications. I want to write some integration tests that boil down to the following:

  1. launch a simple web server
  2. run tsung-recorder via the library
  3. launch selenium, with a firefox profile configured to use the tsung proxy, and have this fetch a page from the server launched in step 1
  4. examine the recorded library (it exists, it's in the correct location, etc.)

For step 1, while I could launch a vanilla rails app externally (e.g., %x{rails s} ), I'm pretty sure there's a better way to programmatically create a simple web server suitable for testing.

tl;dr - What's a way to programmatically launch a simple web server inside a test?

like image 641
Ben Taitelbaum Avatar asked Apr 15 '12 22:04

Ben Taitelbaum


People also ask

How do I run a Web server in Ruby?

You could try with ruby -run -e httpd . -p 8000 , which will start a WEBrick server on your current directory. Show activity on this post. Just type rails s or rails server into the terminal.

What is Ruby web server?

Ruby on Rails — A web-app framework that includes everything needed to create database-backed web applications according to the Model-View-Controller (MVC) pattern.

How do I start a puma server?

Puma has a built-in status and control app that can be used to query and control Puma. Puma will start the control server on localhost port 9293. All requests to the control server will need to include control token (in this case, token=foo ) as a query parameter. This allows for simple authentication.


1 Answers

You can roll your own simple server. Here's a quick example using thin and rspec (those gems, plus rack, must be installed):

# spec/support/test_server.rb
require 'rubygems'
require 'rack'

module MyApp
  module Test
    class Server
      def call(env)
        @root = File.expand_path(File.dirname(__FILE__))
        path = Rack::Utils.unescape(env['PATH_INFO'])
        path += 'index.html' if path == '/'
        file = @root + "#{path}"

        params = Rack::Utils.parse_nested_query(env['QUERY_STRING'])

        if File.exists?(file)
          [ 200, {"Content-Type" => "text/html"}, File.read(file) ]
        else
          [ 404, {'Content-Type' => 'text/plain'}, 'file not found' ]
        end
      end
    end
  end
end

Then in your spec_helper:

# Include all files under spec/support
Dir["./spec/support/**/*.rb"].each {|f| require f}

# Start a local rack server to serve up test pages.
@server_thread = Thread.new do
  Rack::Handler::Thin.run MyApp::Test::Server.new, :Port => 9292
end
sleep(1) # wait a sec for the server to be booted

This will serve any file that you store in the spec/support directory. Including itself. For all other requests it will return a 404.

This is basically what capybara does as mentioned in the previous answer, minus a lot of sophistication.

like image 126
Thilo Avatar answered Sep 19 '22 04:09

Thilo