aboutsummaryrefslogtreecommitdiffstats
path: root/railties/doc/guides/source/creating_plugins/test_setup.txt
blob: 64236ff11097452c3ab9c78f22310a0ae96bbc60 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
== Preparation ==

=== Create the basic app ===

The examples in this guide require that you have a working rails application.  To create a simple rails app execute:

------------------------------------------------
gem install rails
rails yaffle_guide
cd yaffle_guide
script/generate scaffold bird name:string
rake db:migrate
script/server
------------------------------------------------

Then navigate to http://localhost:3000/birds.  Make sure you have a functioning rails app before continuing.

.Editor's note:
NOTE: The aforementioned instructions will work for sqlite3.  For more detailed instructions on how to create a rails app for other databases see the API docs.


=== Generate the plugin skeleton ===

Rails ships with a plugin generator which creates a basic plugin skeleton. Pass the plugin name, either 'CamelCased' or 'under_scored', as an argument. Pass `\--with-generator` to add an example generator also.

This creates a plugin in 'vendor/plugins' including an 'init.rb' and 'README' as well as standard 'lib', 'task', and 'test' directories.

Examples:
----------------------------------------------
./script/generate plugin yaffle
./script/generate plugin yaffle --with-generator
----------------------------------------------

To get more detailed help on the plugin generator, type `./script/generate plugin`.

Later on this guide will describe how to work with generators, so go ahead and generate your plugin with the `\--with-generator` option now:

----------------------------------------------
./script/generate plugin yaffle --with-generator
----------------------------------------------

You should see the following output:

----------------------------------------------
create  vendor/plugins/yaffle/lib
create  vendor/plugins/yaffle/tasks
create  vendor/plugins/yaffle/test
create  vendor/plugins/yaffle/README
create  vendor/plugins/yaffle/MIT-LICENSE
create  vendor/plugins/yaffle/Rakefile
create  vendor/plugins/yaffle/init.rb
create  vendor/plugins/yaffle/install.rb
create  vendor/plugins/yaffle/uninstall.rb
create  vendor/plugins/yaffle/lib/yaffle.rb
create  vendor/plugins/yaffle/tasks/yaffle_tasks.rake
create  vendor/plugins/yaffle/test/core_ext_test.rb
create  vendor/plugins/yaffle/generators
create  vendor/plugins/yaffle/generators/yaffle
create  vendor/plugins/yaffle/generators/yaffle/templates
create  vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb
create  vendor/plugins/yaffle/generators/yaffle/USAGE
----------------------------------------------

To begin just change one thing - move 'init.rb' to 'rails/init.rb'.

=== Setup the plugin for testing ===

If your plugin interacts with a database, you'll need to setup a database connection.  In this guide you will learn how to test your plugin against multiple different database adapters using Active Record.  This guide will not cover how to use fixtures in plugin tests.

To setup your plugin to allow for easy testing you'll need to add 3 files:

 * A 'database.yml' file with all of your connection strings
 * A 'schema.rb' file with your table definitions
 * A test helper method that sets up the database

*vendor/plugins/yaffle/test/database.yml:*

----------------------------------------------
sqlite:
  :adapter: sqlite
  :dbfile: vendor/plugins/yaffle/test/yaffle_plugin.sqlite.db

sqlite3:
  :adapter: sqlite3
  :dbfile: vendor/plugins/yaffle/test/yaffle_plugin.sqlite3.db

postgresql:
  :adapter: postgresql
  :username: postgres
  :password: postgres
  :database: yaffle_plugin_test
  :min_messages: ERROR

mysql:
  :adapter: mysql
  :host: localhost
  :username: root
  :password: password
  :database: yaffle_plugin_test
----------------------------------------------

For this guide you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following:

*vendor/plugins/yaffle/test/schema.rb:*

[source, ruby]
----------------------------------------------
ActiveRecord::Schema.define(:version => 0) do
  create_table :hickwalls, :force => true do |t|
    t.string :name
    t.string :last_squawk
    t.datetime :last_squawked_at
  end
  create_table :wickwalls, :force => true do |t|
    t.string :name
    t.string :last_tweet
    t.datetime :last_tweeted_at
  end
  create_table :woodpeckers, :force => true do |t|
    t.string :name
  end
end
----------------------------------------------

*vendor/plugins/yaffle/test/test_helper.rb:*

[source, ruby]
----------------------------------------------
ENV['RAILS_ENV'] = 'test'
ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'

require 'test/unit'
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))

def load_schema
  config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
  ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")

  db_adapter = ENV['DB']

  # no db passed, try one of these fine config-free DBs before bombing.
  db_adapter ||=
    begin
      require 'rubygems'
      require 'sqlite'
      'sqlite'
    rescue MissingSourceFile
      begin
        require 'sqlite3'
        'sqlite3'
      rescue MissingSourceFile
      end
    end

  if db_adapter.nil?
    raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
  end

  ActiveRecord::Base.establish_connection(config[db_adapter])
  load(File.dirname(__FILE__) + "/schema.rb")
  require File.dirname(__FILE__) + '/../rails/init.rb'
end
----------------------------------------------

Now whenever you write a test that requires the database, you can call 'load_schema'.

=== Run the plugin tests ===

Once you have these files in place, you can write your first test to ensure that your plugin-testing setup is correct.  By default rails generates a file in 'vendor/plugins/yaffle/test/yaffle_test.rb' with a sample test.  Replace the contents of that file with:

*vendor/plugins/yaffle/test/yaffle_test.rb:*

[source, ruby]
----------------------------------------------
require File.dirname(__FILE__) + '/test_helper.rb'

class YaffleTest < Test::Unit::TestCase
  load_schema
  
  class Hickwall < ActiveRecord::Base
  end

  class Wickwall < ActiveRecord::Base
  end
  
  def test_schema_has_loaded_correctly
    assert_equal [], Hickwall.all
    assert_equal [], Wickwall.all
  end
  
end
----------------------------------------------

To run this, go to the plugin directory and run `rake`:

----------------------------------------------
cd vendor/plugins/yaffle
rake
----------------------------------------------

You should see output like:

----------------------------------------------
/opt/local/bin/ruby -Ilib:lib "/opt/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader.rb" "test/yaffle_test.rb" 
-- create_table(:hickwalls, {:force=>true})
   -> 0.0220s
-- create_table(:wickwalls, {:force=>true})
   -> 0.0077s
-- initialize_schema_migrations_table()
   -> 0.0007s
-- assume_migrated_upto_version(0)
   -> 0.0007s
Loaded suite /opt/local/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake/rake_test_loader
Started
.
Finished in 0.002236 seconds.

1 test, 1 assertion, 0 failures, 0 errors
----------------------------------------------

By default the setup above runs your tests with sqlite or sqlite3.  To run tests with one of the other connection strings specified in database.yml, pass the DB environment variable to rake:

----------------------------------------------
rake DB=sqlite
rake DB=sqlite3
rake DB=mysql
rake DB=postgresql
----------------------------------------------

Now you are ready to test-drive your plugin!