autotest-standalone 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +18 -0
- data/.gitignore +1 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +38 -0
- data/History.txt +709 -0
- data/Rakefile +66 -0
- data/Readme.md +93 -0
- data/VERSION +1 -0
- data/articles/getting_started_with_autotest.html +533 -0
- data/autotest-standalone.gemspec +63 -0
- data/bin/autotest +7 -0
- data/bin/unit_diff +44 -0
- data/example_dot_autotest.rb +12 -0
- data/lib/autotest.rb +822 -0
- data/lib/autotest/autoupdate.rb +26 -0
- data/lib/autotest/bundler.rb +10 -0
- data/lib/autotest/once.rb +9 -0
- data/lib/autotest/rcov.rb +27 -0
- data/lib/autotest/restart.rb +12 -0
- data/lib/autotest/timestamp.rb +9 -0
- data/lib/unit_diff.rb +272 -0
- data/test/helper.rb +6 -0
- data/test/test_autotest.rb +520 -0
- data/test/test_autotest_integration.rb +95 -0
- data/test/test_unit_diff.rb +335 -0
- metadata +96 -0
data/Rakefile
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
$LOAD_PATH << 'lib'
|
2
|
+
|
3
|
+
#rake test
|
4
|
+
require 'rake/testtask'
|
5
|
+
Rake::TestTask.new(:test) {|test| test.libs << "test"}
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc "show help"
|
9
|
+
task :help do
|
10
|
+
puts `./bin/autotest --help`
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "run autotest on itself"
|
14
|
+
task :autotest do
|
15
|
+
ruby "-Ilib -w ./bin/autotest"
|
16
|
+
end
|
17
|
+
|
18
|
+
#TODO exclude /usr/ folder
|
19
|
+
#TODO improve coverage ? only 20% atm...
|
20
|
+
desc "show rcov report"
|
21
|
+
task :rcov_info do
|
22
|
+
ruby "-Ilib -S rcov --text-report --save coverage.info test/test_*.rb"
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "update example_dot_autotest.rb with all possible constants"
|
26
|
+
task :update do
|
27
|
+
system "p4 edit example_dot_autotest.rb"
|
28
|
+
File.open "example_dot_autotest.rb", "w" do |f|
|
29
|
+
f.puts "# -*- ruby -*-"
|
30
|
+
f.puts
|
31
|
+
Dir.chdir "lib" do
|
32
|
+
Dir["autotest/*.rb"].sort.each do |s|
|
33
|
+
next if s =~ /rails|discover/
|
34
|
+
f.puts "# require '#{s[0..-4]}'"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
f.puts
|
39
|
+
|
40
|
+
Dir["lib/autotest/*.rb"].sort.each do |file|
|
41
|
+
file = File.read(file)
|
42
|
+
m = file[/module.*/].split(/ /).last rescue nil
|
43
|
+
next unless m
|
44
|
+
|
45
|
+
file.grep(/def[^(]+=/).each do |setter|
|
46
|
+
setter = setter.sub(/^ *def self\./, '').sub(/\s*=\s*/, ' = ')
|
47
|
+
f.puts "# #{m}.#{setter}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
system "p4 diff -du example_dot_autotest.rb"
|
52
|
+
end
|
53
|
+
|
54
|
+
begin
|
55
|
+
require 'jeweler'
|
56
|
+
Jeweler::Tasks.new do |gem|
|
57
|
+
gem.name = "autotest-standalone"
|
58
|
+
gem.summary = "Autotest, without ZenTest"
|
59
|
+
gem.homepage = "http://github.com/grosser/autotest"
|
60
|
+
gem.authors = ["Ryan Davis", "Michael Grosser"]
|
61
|
+
end
|
62
|
+
|
63
|
+
Jeweler::GemcutterTasks.new
|
64
|
+
rescue LoadError
|
65
|
+
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
66
|
+
end
|
data/Readme.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
Standalone autotest extracted from ZenTest.
|
2
|
+
|
3
|
+
As soon as you save a file, autotest will run the matching tests.
|
4
|
+
|
5
|
+
Improvements over ZenTest
|
6
|
+
=========================
|
7
|
+
- `-c` not run all tests after a failed test passes
|
8
|
+
- `-r` use given config file
|
9
|
+
- `-p` use parallel_tests to run tests (Test::Unit only)
|
10
|
+
- `-s` use any style you want -> `alias autospec2="autotest --style rspec2"`
|
11
|
+
- `-b` use bundle exec to run tests
|
12
|
+
- simplified test setup
|
13
|
+
- simplified packaging
|
14
|
+
- less globals
|
15
|
+
- integration tests
|
16
|
+
|
17
|
+
Install
|
18
|
+
=======
|
19
|
+
sudo gem uninstall ZenTest
|
20
|
+
sudo gem install autotest-standalone
|
21
|
+
|
22
|
+
Optional: Support for Test::Unit on Rails
|
23
|
+
sudo gem install autotest-rails-pure
|
24
|
+
Optional: [ZenTest without Autotest](http://github.com/grosser/zentest) version:
|
25
|
+
sudo gem install zentest-without-autotest
|
26
|
+
|
27
|
+
|
28
|
+
Usage
|
29
|
+
=====
|
30
|
+
- go to project folder with tests
|
31
|
+
- run `autotest`
|
32
|
+
|
33
|
+
### Options
|
34
|
+
-f, --fast-start Do not run full tests at start
|
35
|
+
-p, --parallel Run tests (Test::Unit only) in parallel -- gem install parallel_tests
|
36
|
+
-c, --no-full-after-failed Do not run full tests after failed test passed
|
37
|
+
-v, --verbose Be verbose. Prints files that autotest doesn't know how to map to tests
|
38
|
+
-q, --quiet Be quiet.
|
39
|
+
-r, --rc CONFIG Path to config file. (Defaults to ~/.autotest or current_dir/.autotest)
|
40
|
+
-s, --style STYLE Which style to use, e.g. rspec, rspec2
|
41
|
+
-b, --bundle-exec Use bundle exec to run tests
|
42
|
+
-h, --help Show this.
|
43
|
+
|
44
|
+
Windows needs [diff.exe](http://gnuwin32.sourceforge.net/packages.html)
|
45
|
+
|
46
|
+
TIPS
|
47
|
+
====
|
48
|
+
- [RSpec] if you want to use `require 'spec_helper'` -> `rspec --configure autotest`
|
49
|
+
|
50
|
+
TODO
|
51
|
+
====
|
52
|
+
- add documentation for hooks
|
53
|
+
- remove globals from unitdiff
|
54
|
+
- add some automatic notifications e.g. autotest -n -> use any notify library found
|
55
|
+
- use watchr
|
56
|
+
|
57
|
+
|
58
|
+
License
|
59
|
+
=======
|
60
|
+
|
61
|
+
### Autotest was extracted from ZenTest and improved by:
|
62
|
+
- [Charles Roper](http://twitter.com/charlesroper)
|
63
|
+
- [Shane Liebling](http://github.com/shanel)
|
64
|
+
- [Michael Grosser](http://grosser.it)
|
65
|
+
|
66
|
+
### ZenTest Authors
|
67
|
+
- http://www.zenspider.com/ZSS/Products/ZenTest/
|
68
|
+
- http://rubyforge.org/projects/zentest/
|
69
|
+
- ryand-ruby@zenspider.com
|
70
|
+
|
71
|
+
|
72
|
+
(The MIT License)
|
73
|
+
|
74
|
+
Copyright (c) 2001-2006 Ryan Davis, Eric Hodel, Zen Spider Software
|
75
|
+
|
76
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
77
|
+
a copy of this software and associated documentation files (the
|
78
|
+
"Software"), to deal in the Software without restriction, including
|
79
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
80
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
81
|
+
permit persons to whom the Software is furnished to do so, subject to
|
82
|
+
the following conditions:
|
83
|
+
|
84
|
+
The above copyright notice and this permission notice shall be
|
85
|
+
included in all copies or substantial portions of the Software.
|
86
|
+
|
87
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
88
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
89
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
90
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
91
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
92
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
93
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
4.5.0
|
@@ -0,0 +1,533 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xml:lang="en-US" lang="en-US" xmlns=
|
4
|
+
"http://www.w3.org/1999/xhtml">
|
5
|
+
<head>
|
6
|
+
<title>PH7 - Getting started with Autotest - Continuous
|
7
|
+
Testing</title>
|
8
|
+
<link href="Article.css" media="all" rel="Stylesheet" type="text/css" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<div class="content">
|
12
|
+
<h1>NOTE: This article was written in 2007. It is out of date.</h1>
|
13
|
+
<h1 style="text-align: center;">Getting started with Autotest -
|
14
|
+
Continuous Testing</h1>
|
15
|
+
<div id="abstract" class="Abstract">
|
16
|
+
<p class="first">Why manually run your tests, when the computer can
|
17
|
+
do it for you! <a href=
|
18
|
+
"http://www.zenspider.com/ZSS/Products/ZenTest/">Autotest</a> is a
|
19
|
+
great tool to speed up test-driven development with Ruby or Ruby on
|
20
|
+
Rails. Autotest makes your coding session even more productive as
|
21
|
+
<strong>it automatically runs a subset of your test suite each time
|
22
|
+
you change a file. Autotest is smart -- it figures out which subset
|
23
|
+
to run based on the files you've changed.</strong> Think of it as
|
24
|
+
<strong><q>Continuous Testing</q></strong>.</p>
|
25
|
+
<p>Autotest source code is well-documented (<a href=
|
26
|
+
"http://zentest.rubyforge.org/ZenTest/" title=
|
27
|
+
"ZenTest documentation">rdoc</a>) but finding a high level overview
|
28
|
+
online is a little more challenging. This article will get you up
|
29
|
+
and running in no time, so that you may concentrate on writing
|
30
|
+
code. <a href="getting_started_with_autotest">Let's get
|
31
|
+
started!</a></p>
|
32
|
+
</div>
|
33
|
+
<h2 id="why_autotest">Why Autotest?</h2>
|
34
|
+
<h3 id="continuous_testing">Continuous Testing</h3>
|
35
|
+
<p>The cool thing about Autotest is that you have <strong>instant
|
36
|
+
feedback on your code</strong> (tests run within a second). Even
|
37
|
+
better, <strong>the testing happens on its own</strong> so
|
38
|
+
<strong>you no longer have to switch back and forth</strong> from
|
39
|
+
the coding context to the testing context anymore (both wise
|
40
|
+
cognitively and from a <acronym title="User Interface">UI</acronym>
|
41
|
+
perspective). This effortless and immediate feedback on your code
|
42
|
+
as well as the automated and unattended test runs are quite similar
|
43
|
+
to the characteristics of <a href=
|
44
|
+
"http://www.martinfowler.com/articles/continuousIntegration.html"
|
45
|
+
title=
|
46
|
+
"Martin Fowler's legendary introduction to Continuous Integration">Continuous
|
47
|
+
Integration</a> at the team level. However, continuous integration
|
48
|
+
concentrates on improving <em>integration</em> at a <em>team</em>
|
49
|
+
level while Autotest concentrates on facilitating the
|
50
|
+
<em>development</em> for a <em>single</em> developer (or
|
51
|
+
programming-pair) <em>before</em> the code gets integrated -- hence
|
52
|
+
the term <strong><dfn>Continuous Testing</dfn></strong>.</p>
|
53
|
+
<p>As this is highly visual, <strong>have a look at Nuby on Rails'
|
54
|
+
<a href="http://topfunky.com/clients/blog/autotest-tm.mov">autotest
|
55
|
+
screencast</a></strong>.</p>
|
56
|
+
<h3 id="quicker_test_runs">Quicker Test Runs</h3>
|
57
|
+
<p>Autotest can also provide <strong>quicker test runs</strong>
|
58
|
+
than standard convention since it intelligently monitors the
|
59
|
+
changes and only runs the tests that are impacted by these changes.
|
60
|
+
In practice this is relevant only for <q>classic</q> Rails
|
61
|
+
applications because:</p>
|
62
|
+
<ul>
|
63
|
+
<li><strong>Rails conventions provide good heuristics</strong> for
|
64
|
+
Autotest to decide which tests to run when a file changes. If your
|
65
|
+
application does not stick to the classic Rails layout and naming
|
66
|
+
conventions the <q>magic</q> does not work so well anymore. In this
|
67
|
+
case, it is probably better to have Autotest <a href=
|
68
|
+
"getting_started_with_autotest#running_whole_test_suite">run your
|
69
|
+
whole test suite for all changes</a>.</li>
|
70
|
+
<li>There is value in running a <em>subset</em> of the whole test
|
71
|
+
suite <strong>only because running <q>classic</q> Rails unit tests
|
72
|
+
can be slow</strong>. This is mostly since Rails approach to unit
|
73
|
+
testing is quite unconventional and involves database access. This
|
74
|
+
approach goes against general <q>agile</q> wisdom that you should
|
75
|
+
make sure your unit tests run quickly, and do not have any
|
76
|
+
dependency for external systems. Also note that there are <a href=
|
77
|
+
"http://jayfields.blogspot.com/2006/06/ruby-on-rails-unit-tests.html">
|
78
|
+
well-documented ways</a> to have your Rails unit tests not depend
|
79
|
+
on the database and have them run blazing fast!</li>
|
80
|
+
</ul>
|
81
|
+
<h3 id="lack_of_proper_ide">Make Up for a Lack of a Proper Ruby
|
82
|
+
IDE</h3>
|
83
|
+
<p>Autotest can come in handy if your favorite IDE has limited Ruby
|
84
|
+
support, or if you prefer a more ligthweight development
|
85
|
+
environment (text editor + terminal + Autotest): it gives you an
|
86
|
+
easy and automated way to run your tests.</p>
|
87
|
+
<h2 id="install_autotest">Install Autotest</h2>
|
88
|
+
<h3>Make Sure You Already have RubyGem Installed</h3>
|
89
|
+
<p>The easiest way to install <code>Autotest</code> is to use the
|
90
|
+
<strong>ZenTest gem</strong>. If you have no idea of what a
|
91
|
+
<dfn>gem</dfn> is, or you have not installed the RubyGem packaging
|
92
|
+
system yet, please have a look at the <a href=
|
93
|
+
"http://rubygems.org/">RubyGem official website</a>. If you are
|
94
|
+
serious about Ruby development, it will be hard <em>not</em> to use
|
95
|
+
RubyGem.</p>
|
96
|
+
<h3 id="install_osx_ubuntu">OS X and Ubuntu</h3>
|
97
|
+
<p>On OS X or Ubuntu launch from a terminal:</p>
|
98
|
+
<pre class="command-box">
|
99
|
+
$ sudo gem install ZenTest
|
100
|
+
</pre>
|
101
|
+
<h3 id="install_other_unix">Other Unix flavors</h3>
|
102
|
+
<p>For other *Nix flavors, try</p>
|
103
|
+
<pre class="command-box">
|
104
|
+
$ suPassword:<span class=
|
105
|
+
"placeholder">Type root password here</span>$ gem install ZenTest
|
106
|
+
</pre>
|
107
|
+
<h2 id="run_autotest">Run autotest</h2>
|
108
|
+
<h3 id="run_rails">Ruby on Rails project</h3>
|
109
|
+
<p>Consistent with Rails principles, Autotest does not require any
|
110
|
+
configuration to run. Provided you follow classic Rails
|
111
|
+
conventions, Autotest will figure things out on its own.
|
112
|
+
<strong>Simply launch Autotest from the base directory of your Ruby
|
113
|
+
on Rails project.</strong></p>
|
114
|
+
<pre class="command-box">
|
115
|
+
$ cd <span class=
|
116
|
+
"placeholder">base directory of your Ruby on Rails project</span>$ autotest
|
117
|
+
</pre>
|
118
|
+
<p>Autotest will then run all your tests (the first time), and wait
|
119
|
+
for you to modify some code:</p>
|
120
|
+
<pre class="command-box">
|
121
|
+
$ autotest
|
122
|
+
/usr/bin/ruby1.8 -I.:lib:test -rtest/unit -e "%w[test/functional/tasks_controller_test.rb test/unit/quarter_test.rb test/unit/task_test.rb].each { |f| require f }" | unit_diff -u
|
123
|
+
Loaded suite -e
|
124
|
+
Started
|
125
|
+
.......................
|
126
|
+
Finished in 0.672928 seconds.
|
127
|
+
|
128
|
+
================================================================================
|
129
|
+
<strong>23 tests, 60 assertions, 0 failures, 0 errors</strong>
|
130
|
+
</pre>
|
131
|
+
<p>Go ahead and <strong>modify some code in your project so that a
|
132
|
+
test fails.</strong> Save the modified file to disk and Autotest
|
133
|
+
will automatically rerun some of the tests:</p>
|
134
|
+
<pre class="command-box">
|
135
|
+
/usr/bin/ruby1.8 -I.:lib:test -rtest/unit -e "%w[test/functional/tasks_controller_test.rb test/unit/task_test.rb].each { |f| require f }" | unit_diff -u
|
136
|
+
Loaded suite -e
|
137
|
+
Started
|
138
|
+
...F........
|
139
|
+
Finished in 0.42272 seconds.
|
140
|
+
|
141
|
+
1) Failure:
|
142
|
+
test_should_be_found(TaskTest) [<strong>./test/unit/task_test.rb:22</strong>]:
|
143
|
+
--- /tmp/diff6647.0 2006-11-15 20:46:43.000000000 -0800
|
144
|
+
+++ /tmp/diff6647.1 2006-11-15 20:46:43.000000000 -0800
|
145
|
+
@@ -1 +1 @@
|
146
|
+
<strong>
|
147
|
+
-Expected result
|
148
|
+
+Actual result</strong>
|
149
|
+
|
150
|
+
================================================================================
|
151
|
+
<strong>4 tests, 9 assertions, 1 failures, 0 errors</strong>
|
152
|
+
</pre>
|
153
|
+
<p>Note that autotest ran only a <em>subset</em> of your test suite
|
154
|
+
this time (4 tests out of 23 in my case). Also note that
|
155
|
+
<strong>Autotest is especially good in providing brief and relevant
|
156
|
+
feedback on the test failures</strong>.</p>
|
157
|
+
<p>Autotest focuses on running previous failures until you have
|
158
|
+
fixed them. So <strong>test failures are run until they have all
|
159
|
+
passed. Then the full test suite is run</strong> to ensure that
|
160
|
+
nothing else was inadvertently broken.</p>
|
161
|
+
<h3 id="run_ruby">Ruby Project</h3>
|
162
|
+
<p>In theory you would run Autotest the same way as you would for
|
163
|
+
any Ruby project -- even if it is not based on Rails:</p>
|
164
|
+
<pre class="command-box">
|
165
|
+
$ cd <span class=
|
166
|
+
"placeholder">base directory of your Ruby project</span>$ autotest
|
167
|
+
</pre>
|
168
|
+
<p>In practice, Autotest might have problems finding your tests or
|
169
|
+
figuring out which tests to run when you change some code. If this
|
170
|
+
is the case, take a look at the <a href=
|
171
|
+
"getting_started_with_autotest#troubleshoot_test_detection"><q>troubleshooting
|
172
|
+
test detection</q></a> section.</p>
|
173
|
+
<h3 id="full_test_run">Forcing a Full Test Run and Stopping
|
174
|
+
Autotest</h3>
|
175
|
+
<p><strong>If you want to force Autotest to run the <em>entire</em>
|
176
|
+
test suite</strong> <strong>hit <kbd>Ctrl - C</kbd> once</strong>
|
177
|
+
in the terminal running Autotest. Hitting <kbd>Ctrl - C</kbd> twice
|
178
|
+
will stop Autotest.</p>
|
179
|
+
<h2 id="configure_plugins">Configure Plugins</h2>
|
180
|
+
<p>Autotest also provides some cool plugins that enable you to
|
181
|
+
<strong>get feedback the way you want</strong>.</p>
|
182
|
+
<h3 id="create_dot_autotest">Create a <code>.autotest</code>
|
183
|
+
file</h3>
|
184
|
+
<p><strong>You configure plugins by creating a
|
185
|
+
<code>.autotest</code> file in your project base
|
186
|
+
directory</strong>. You can also provide a default configuration
|
187
|
+
for all your projects by creating a <code>.autotest</code> file in
|
188
|
+
your home directory (when present, project configuration files
|
189
|
+
override user default configuration file).</p>
|
190
|
+
<p><strong>You enable a plugin by adding a line requiring the
|
191
|
+
plugin in the <code>.autotest</code> file</strong>. For instance,
|
192
|
+
to enable the <q>Growl</q> plugin, you would add the following
|
193
|
+
line:</p>
|
194
|
+
<pre class="source-code-box">
|
195
|
+
require 'autotest/growl'
|
196
|
+
</pre>
|
197
|
+
<p>Below you will find a description of the most popular plugins
|
198
|
+
and how to enable them.</p>
|
199
|
+
<h3 id="red_green_plugin">Red / Green Plugin</h3>
|
200
|
+
<p>The <q>Red / Green</q> plugin provides color to
|
201
|
+
<code>Autotest</code> messages in the terminal window. As expected,
|
202
|
+
output is green if all the tests pass, red if some test fails.
|
203
|
+
Having red / green visual output makes it easier for one to scan
|
204
|
+
the output and quickly determine whether everything is OK or
|
205
|
+
something went wrong.</p>
|
206
|
+
<p>Visually, the <q>Red /Green</q> plugin turns</p>
|
207
|
+
<pre class="command-box">
|
208
|
+
================================================================================
|
209
|
+
200 tests, 520 assertions, 0 failures, 0 errors
|
210
|
+
</pre>
|
211
|
+
<p>into</p>
|
212
|
+
<pre class="command-box" style="color: green;">
|
213
|
+
================================================================================
|
214
|
+
200 tests, 520 assertions, 0 failures, 0 errors
|
215
|
+
</pre>
|
216
|
+
<p>or</p>
|
217
|
+
<pre class="command-box" style="color: red;">
|
218
|
+
================================================================================
|
219
|
+
5 tests, 20 assertions, 1 failures, 0 errors
|
220
|
+
</pre>
|
221
|
+
<p>To enable the <q>Red / Green</q> plugin add the following line
|
222
|
+
to your <code>.autotest</code> file:</p>
|
223
|
+
<pre class="source-code-box">
|
224
|
+
require 'autotest/redgreen'
|
225
|
+
</pre>
|
226
|
+
<h3 id="desktop_notification_plugins">Desktop Notification
|
227
|
+
Plugins</h3>
|
228
|
+
<p>You might not even have to look at <code>the Autotest</code>
|
229
|
+
terminal output to figure out the result of a test run.
|
230
|
+
<strong>Several plugins provide desktop notification messages
|
231
|
+
capabilities</strong>. In this way you can run Autotest in the
|
232
|
+
background and see popup messages when something fails.</p>
|
233
|
+
<h4 id="growl_plugin">Growl Plugin (OS X)</h4>
|
234
|
+
<p><a href="http://growl.info/">Growl</a> is a popular desktop
|
235
|
+
notification system for OSX. If you are developing on a Mac, enable
|
236
|
+
the Growl plugin by adding</p>
|
237
|
+
<pre class="source-code-box">
|
238
|
+
require 'autotest/growl'
|
239
|
+
</pre>
|
240
|
+
<p>to your <code>.autotest</code> file. Note that for this plugin
|
241
|
+
to work, you not only need to install <a href="http://growl.info/"
|
242
|
+
title="Growl website">Growl</a> <strong>but also its command line
|
243
|
+
interface: <a href=
|
244
|
+
"http://growl.info/documentation/growlnotify.php">growlnotify</a>.</strong></p>
|
245
|
+
<h4 id="snarl_plugin">Snarl Plugin (Windows)</h4>
|
246
|
+
<p><a href="http://www.fullphat.net/">Snarl</a> is a notification
|
247
|
+
system for Windows largely inspired by Growl. Autotest will use it
|
248
|
+
if you enable the Snarl plugin in your <code>.autotest</code>
|
249
|
+
file:</p>
|
250
|
+
<pre class="source-code-box">
|
251
|
+
require 'autotest/snarl'
|
252
|
+
</pre>
|
253
|
+
<h4 id="kde_notify_plugin">KDE Notify Plugin (Linux)</h4>
|
254
|
+
<p>If you are running Linux and use KDE as your desktop
|
255
|
+
environment, you will get desktop notification by adding to your
|
256
|
+
<code>.autotest</code> file:</p>
|
257
|
+
<pre class="source-code-box">
|
258
|
+
require 'autotest/kdenotify'
|
259
|
+
</pre>
|
260
|
+
<h4 id="gnome_notify_plugin">Gnome Notify plugin (Linux)</h4>
|
261
|
+
<p>If you are running Linux and use Gnome as your desktop
|
262
|
+
environment, unfortunately there is no official plugin for desktop
|
263
|
+
notification. You can still get desktop notifications by adding the
|
264
|
+
following code snipet in your <code>.autotest</code> file:</p>
|
265
|
+
<pre class="source-code-box">
|
266
|
+
module Autotest::GnomeNotify
|
267
|
+
|
268
|
+
# Time notification will be displayed before disappearing automatically
|
269
|
+
EXPIRATION_IN_SECONDS = 2
|
270
|
+
ERROR_STOCK_ICON = "gtk-dialog-error"
|
271
|
+
SUCCESS_STOCK_ICON = "gtk-dialog-info"
|
272
|
+
|
273
|
+
# Convenience method to send an error notification message
|
274
|
+
#
|
275
|
+
# [stock_icon] Stock icon name of icon to display
|
276
|
+
# [title] Notification message title
|
277
|
+
# [message] Core message for the notification
|
278
|
+
def self.notify stock_icon, title, message
|
279
|
+
options = "-t #{EXPIRATION_IN_SECONDS * 1000} -i #{stock_icon}"
|
280
|
+
system "notify-send #{options} '#{title}' '#{message}'"
|
281
|
+
end
|
282
|
+
|
283
|
+
Autotest.add_hook :red do |at|
|
284
|
+
notify ERROR_STOCK_ICON, "Tests failed", "#{at.files_to_test.size} tests failed"
|
285
|
+
end
|
286
|
+
|
287
|
+
Autotest.add_hook :green do |at|
|
288
|
+
notify SUCCESS_STOCK_ICON, "All tests passed, good job!", ""
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
</pre>
|
293
|
+
<p>For this to work <strong>you need to have <a href=
|
294
|
+
"http://trac.galago-project.org/wiki/DesktopNotifications">libnotify</a>
|
295
|
+
installed on your system and a program named
|
296
|
+
<code>notify-send</code> in your <code>PATH</code></strong>. For
|
297
|
+
most Linux distributions this simply means that you should install
|
298
|
+
the <code>libnotify-bin</code> package. If you are running Ubuntu,
|
299
|
+
run</p>
|
300
|
+
<pre class="command-box">
|
301
|
+
sudo apt-get install libnotify-bin
|
302
|
+
</pre>
|
303
|
+
<h3 id="pretty_plugin">Pretty Plugin</h3>
|
304
|
+
<p>If you are running Autotest on a Mac you can enable the
|
305
|
+
<q>pretty</q> plugin to <strong>visualize your Autotest status
|
306
|
+
history</strong> as a sequence of red and green squares:</p>
|
307
|
+
<p class="figure"><img alt="Autotest Pretty Plugin Screenshot" src=
|
308
|
+
"http://blog.zenspider.com/img/autotest_pretty.png" /></p>
|
309
|
+
<p>Of course a green square indicates passing tests while a red
|
310
|
+
square signals some test failures. If you want to get a feel of
|
311
|
+
what a session is like with this plugin enabled, ZenSpider has a
|
312
|
+
<a href=
|
313
|
+
"http://vanity.zenspider.com.nyud.net:8090/~ryan/autotest_plugins.mov"
|
314
|
+
title="ZenSpider pretty plugin video">nice video</a> demonstrating
|
315
|
+
the pretty plugin in action.</p>
|
316
|
+
<p>To enable this plugin <strong>you will need to install <a href=
|
317
|
+
"http://rubycocoa.sourceforge.net/doc/" title=
|
318
|
+
"Ruby Cocoa documentation">RubyCocoa</a></strong> and add the
|
319
|
+
folowing line to your <code>.autotest</code> file:</p>
|
320
|
+
<pre class="source-code-box">
|
321
|
+
require 'autotest/pretty'
|
322
|
+
</pre>
|
323
|
+
<h3 id="html_report_plugin">HTML Report Plugin</h3>
|
324
|
+
<p>The <q>HTML report</q> plugin <strong>publishes most recent
|
325
|
+
Autotest statuses as a web page</strong> under
|
326
|
+
<code>~/Sites/autotest.html</code>. You can then point a browser to
|
327
|
+
this page and see something like:</p>
|
328
|
+
<div class="sample-box">
|
329
|
+
<div style="COLOR:green">Sat Feb 03 14:34:09 PST 2007: 0</div>
|
330
|
+
<div style="COLOR:red">Sat Feb 03 14:33:50 PST 2007: 1</div>
|
331
|
+
<div style="COLOR:green">Sat Feb 03 14:33:45 PST 2007: 0</div>
|
332
|
+
<div style="COLOR:red">Sat Feb 03 14:33:29 PST 2007: 4</div>
|
333
|
+
<div style="COLOR:green">Sat Feb 03 14:33:19 PST 2007: 0</div>
|
334
|
+
</div>
|
335
|
+
<p>Of course the content of the web page is updated while you work.
|
336
|
+
Note that <strong>you need to have an an existing
|
337
|
+
<code>~/Sites</code> directory</strong> <em>before</em> you enable
|
338
|
+
the plugin with the following line:</p>
|
339
|
+
<pre class="source-code-box">
|
340
|
+
require 'autotest/html_report'
|
341
|
+
</pre>
|
342
|
+
<h3 id="menu_plugin">Menu Plugin</h3>
|
343
|
+
<p>Remember that, by default, hitting <code>Ctrl - C</code> once
|
344
|
+
will force Autotest to run the entire test suite, and hitting
|
345
|
+
<code>Ctrl - C</code> twice will stop Autotest? The <q>menu</q>
|
346
|
+
plugin changes this behavior: each time you hit <code>Ctrl -
|
347
|
+
C</code> it will explicitly ask you whether you want to quit,
|
348
|
+
restart or just keep going.</p>
|
349
|
+
<pre class="command-box">
|
350
|
+
c: continue q: quit r: restart menu>
|
351
|
+
</pre>
|
352
|
+
<p>Enable the menu plugin by adding the following line to your
|
353
|
+
<code>.autotest</code> file.</p>
|
354
|
+
<pre class="source-code-box">
|
355
|
+
require 'autotest/menu'
|
356
|
+
</pre>
|
357
|
+
<h3 id="timestamp_plugin">Timestamp Plugin</h3>
|
358
|
+
<p>While Autotest waits for you to save a file, the timestamp
|
359
|
+
plugin prints a message with the current time. Messages look
|
360
|
+
like:</p>
|
361
|
+
<pre class="command-box">
|
362
|
+
# waiting... Sat Feb 03 15:56:23 EST 2007
|
363
|
+
</pre>
|
364
|
+
<p>To enable the timestamp plugin add the following to your
|
365
|
+
<code>.autotest</code> file:</p>
|
366
|
+
<pre class="source-code-box">
|
367
|
+
require 'autotest/timestamp'
|
368
|
+
</pre>
|
369
|
+
<h3>Getting More Information</h3>
|
370
|
+
<p>Your Autotest install comes with a sample <code>.autotest</code>
|
371
|
+
file listing all available plugins. It is named
|
372
|
+
<code>example_dot_autotest.rb</code>. You will find it in the gems
|
373
|
+
install directory. Most likely this directory will look like:</p>
|
374
|
+
<ul>
|
375
|
+
<li><code>/usr/local/lib/ruby/gems/1.8/gems/ZenTest-3.4.3/</code>
|
376
|
+
on OS X.</li>
|
377
|
+
<li><code>/usr/lib/ruby/gems/1.8/gems/ZenTest-3.4.3/</code> on
|
378
|
+
other Unix platforms</li>
|
379
|
+
</ul>
|
380
|
+
<p>Interesting plugins that are not distributed with Autotest can
|
381
|
+
also be found within <a href=
|
382
|
+
"http://rubyforge.org/tracker/?atid=1680&group_id=419&func=browse">
|
383
|
+
autotest pending patches</a>. The <a href=
|
384
|
+
"http://rspec.rubyforge.org/" title=
|
385
|
+
"RSpec project website">RSpec</a> patches you will find there will
|
386
|
+
be of particular interest to those of you that enjoy <a href=
|
387
|
+
"http://behaviour-driven.org/" title=
|
388
|
+
"Official Behavior Driven Development website">behavior-driven
|
389
|
+
development</a>.</p>
|
390
|
+
<h2 id="troubleshoot_test_detection">Troubleshooting Autotest Test
|
391
|
+
Detection</h2>
|
392
|
+
<p>Whether Autotest does not work out of the box for you or its
|
393
|
+
magics eludes you, it is always good to get some understanding of
|
394
|
+
the heuristics that Autotest uses to figure which test(s) to
|
395
|
+
run.</p>
|
396
|
+
<h3 id="rails_heuristics">Heuristics for Rails</h3>
|
397
|
+
<p>Autotest automatically discovers Ruby on Rails projects by
|
398
|
+
checking for a <code>config/environment.rb</code> file. If there is
|
399
|
+
one, Autotest will base its logic on standard Rails file mappings
|
400
|
+
and conventions.</p>
|
401
|
+
<p>If for some reason you want to force Ruby on Rails mode you can
|
402
|
+
always launch Autotest it with the <code>-rails</code> option:</p>
|
403
|
+
<pre class="command-box">
|
404
|
+
$ autotest -rails
|
405
|
+
</pre>
|
406
|
+
<p>A <em>simplified</em> version of Autotest heuristics in this
|
407
|
+
mode would be:</p>
|
408
|
+
<ul>
|
409
|
+
<li>When changing a test file, only this file is run (e.g.
|
410
|
+
<code>test/unit/foo_test.rb</code> →
|
411
|
+
<code>test/unit/foo_test.rb</code>).</li>
|
412
|
+
<li>When changing a model file, only associated unit test file is
|
413
|
+
run (e.g. <code>app/models/foo.rb</code> →
|
414
|
+
<code>test/unit/foo_test.rb</code>).</li>
|
415
|
+
<li>When changing a controller file, associated functional test
|
416
|
+
file is run (e.g. <code>app/controllers/foo_controller.rb</code>
|
417
|
+
→ <code>test/functional/foo_controller_test.rb</code>).</li>
|
418
|
+
<li>When changing a fixture file, associated unit test and
|
419
|
+
functional test are run (e.g. <code>app/fixtures/foos.yml</code>
|
420
|
+
→ <code>test/unit/foo_test.rb</code> +
|
421
|
+
<code>test/functional/foo_controller_test.rb</code>).</li>
|
422
|
+
<li>When changing a helper file, associated functional test file is
|
423
|
+
run (e.g. <code>app/helpers/foo_helper.rb</code> →
|
424
|
+
<code>test/functional/foo_controller_test.rb</code>).</li>
|
425
|
+
<li>When changing <code>application_helper.rb</code> file all
|
426
|
+
functional test files are run (e.g.
|
427
|
+
<code>application_helper.rb</code> →
|
428
|
+
<code>test/functional/*_test.rb</code>).</li>
|
429
|
+
<li>When changing a file under the <code>config</code> directory,
|
430
|
+
all tests are run.</li>
|
431
|
+
</ul>
|
432
|
+
<p>You've got the idea. Actual heuristics are a little more complex
|
433
|
+
and also handle the concept of <code>view</code> and
|
434
|
+
<code>controller</code> tests. <strong>For a more thourough
|
435
|
+
understanding have look at the <code>rails_autotest.rb</code>
|
436
|
+
file</strong> in ZenTest gem install directory.</p>
|
437
|
+
<p>In case these heuristics do not play well with your own
|
438
|
+
conventions, do not give up yet: <strong>you can always configure
|
439
|
+
Autotest to <a href=
|
440
|
+
"getting_started_with_autotest#running_whole_test_suite">run the
|
441
|
+
whole test suite for all changes</a></strong>.</p>
|
442
|
+
<h3 id="ruby_heuristics">Heuristics for Non Rails Projects</h3>
|
443
|
+
<p>For non Rails project, Autotest uses a simple naming scheme to
|
444
|
+
map implementation files to test files:</p>
|
445
|
+
<ul>
|
446
|
+
<li>Test files must be stored in the <code>test</code>
|
447
|
+
directory</li>
|
448
|
+
<li>Implementation files must be stored in the <code>lib</code>
|
449
|
+
directory</li>
|
450
|
+
<li>Test files names must start with <code>test_</code></li>
|
451
|
+
<li>Test class names must start with <code>Test</code></li>
|
452
|
+
<li>Test files corresponding to a specific implementation file must
|
453
|
+
be named <code>test_*<span class="placeholder">name of
|
454
|
+
implementation file</span>.rb</code></li>
|
455
|
+
</ul>
|
456
|
+
<p>If you can live with these conventions, Autotest will work
|
457
|
+
out-of-the-box for you. If these conventions are not your cup of
|
458
|
+
tea and you have your own, the next paragraph explains how to
|
459
|
+
configure Autotest so that it runs the whole test suite each time
|
460
|
+
you save a file.</p>
|
461
|
+
<h3 id="running_whole_test_suite">Running the Whole Test Suite for
|
462
|
+
All Changes</h3>
|
463
|
+
<p>If for some reason Autotest heuristics do not work for you, you
|
464
|
+
can customize them in your <code>.autotest</code> file with a
|
465
|
+
little bit of work.</p>
|
466
|
+
<p>For instance, if your entire test suite runs quickly (as it
|
467
|
+
should), you can easily configure Autotest to run the whole test
|
468
|
+
suite for any change by adding the following code to your
|
469
|
+
<code>.autotest</code> file:</p>
|
470
|
+
<pre class="command-box">
|
471
|
+
#
|
472
|
+
# Override autotest default magic deciding which test to run when
|
473
|
+
# a file is changed : enable more flexible naming conventions
|
474
|
+
# trading some of the efficiency: we rerun all the tests each time.
|
475
|
+
#
|
476
|
+
class Autotest
|
477
|
+
|
478
|
+
def test_files_for(filename)
|
479
|
+
return Dir["test/**/*.rb"]
|
480
|
+
end
|
481
|
+
|
482
|
+
end
|
483
|
+
</pre>
|
484
|
+
<h2>Conclusion</h2>
|
485
|
+
<p>Autotest provides an easy and effortless way to run your tests:
|
486
|
+
just save a file. This is a great way to get quick feedback on your
|
487
|
+
code and avoid any context switch. Autotest automated test runs are
|
488
|
+
also extremelly valuable if your favorite IDE has poor Ruby
|
489
|
+
support, or if you prefer a more ligthweight development
|
490
|
+
environment (text editor + terminal + Autotest).</p>
|
491
|
+
<p>Autotest also tries hard to be smart on deciding which tests to
|
492
|
+
run:</p>
|
493
|
+
<ul>
|
494
|
+
<li>It only runs the tests affected by your latest code
|
495
|
+
changes.</li>
|
496
|
+
<li>When some tests fail, Autotest focuses on running previous
|
497
|
+
failures until you have fixed them. Once they pass, the full test
|
498
|
+
suite is run to ensure that nothing else was inadvertently
|
499
|
+
broken.</li>
|
500
|
+
</ul>
|
501
|
+
<p>On deciding which tests to run, Autotest <q>magic</q> works out
|
502
|
+
of the box if your application follows classic Ruby on Rails
|
503
|
+
conventions. If this is not your cup of tea, it is extremely easy
|
504
|
+
to customize Autotest to fit your conventions.</p>
|
505
|
+
<p>Via its plugins Autotest also offers a lot of interesting
|
506
|
+
feedback options, from terminal output to html publishing to
|
507
|
+
desktop notifications. The pretty plugin offers a highly visual
|
508
|
+
representation of your test runs history, which could be useful
|
509
|
+
when teaching Test Driven Development (green, red, green, red,
|
510
|
+
...).</p>
|
511
|
+
<p>On the flip side, It is important to note that Autotest does not
|
512
|
+
fit all developement styles: Some developers like better control on
|
513
|
+
which tests they are running. While working on a piece of code,
|
514
|
+
they will typically focuss on a few tests (which they know they
|
515
|
+
could have broken), and then run the whole test suite just before
|
516
|
+
committing. Autotest emulates this as well as it can with his focus
|
517
|
+
on running previous failures; but ultimately a human will always
|
518
|
+
have a better intuition, especially if your project does not follow
|
519
|
+
classic Rails conventions.</p>
|
520
|
+
<p>In all cases, it is worth spending some time playing with
|
521
|
+
Autotest and experiment with its innovative, lightweight and
|
522
|
+
effortless approach to test runs, what I have been calling
|
523
|
+
<q>continuous testing</q>.</p>
|
524
|
+
</div>
|
525
|
+
<p class="Copyright">© Copyright Philippe Hanrigou, all rights
|
526
|
+
reserved.</p>
|
527
|
+
<p class="License">This work is licensed under a <a rel="license"
|
528
|
+
href="http://creativecommons.org/licenses/by/2.5/">Creative Commons
|
529
|
+
Attribution 2.5 License</a>.</p>
|
530
|
+
<p class="License">Used and distributed with permission from
|
531
|
+
Philippe Hanrigou.</p>
|
532
|
+
</body>
|
533
|
+
</html>
|