May, 2006

15
May 06

Using Rake to automate PHP testing on linux

I’m getting really into Rake, a build tool like Make written in (and therefore able to use the full power of) Ruby. Martin Fowler has a nice article about it.

I’ve been doing some PHP work again recently and, inspired by autotest, knocked together a Rake task which monitors directories and runs my tests when it notices a change. Unlike autotest, which checks for changes every few seconds, this task uses inotify and is rapido enough that it always manages to start the tests before I can switch consoles. Of course, this can be used for running anything, not just the PHP tests I’ve been using recently.

Aside: Simpletest is the nice PHP testing package that I use.

Requirements

  • Linux kernel with inotify (version 2.6.?+)
  • Ruby – only tested with 1.8.4
  • Rake – only tested with 0.7.1
  • ruby-inotify – only tested with 0.3.0, older versions will probably not work

 1 desc "Run the tests." 
 2 task :test do
 3   # assign "out" so that test errors don't cause an exit
 4   out = system "php test/init.php" 
 5 end
 6
 7 desc "Run tests automatically when files change" 
 8 task :keep_testing => [ :test ] do
 9   require 'io/INotify'
10   require 'find'
11
12   # allows us to re-run the tests
13   class Rake::Task
14     attr_accessor :already_invoked
15   end
16   Rake::Task[:test].already_invoked = false
17
18   inotify = INotify::INotify.new
19
20   thread = Thread.new do
21     inotify.each_event do |event|
22       # .swp files are used by Vim
23       if event.type == 'modify' and event.filename !~ /.swp$/
24         puts "#{event.filename} modified..." 
25         puts "===" 
26         Rake::Task[:test].invoke
27         Rake::Task[:test].already_invoked = false
28         puts "" 
29       end
30     end
31   end
32
33   # default list of directories
34   ENV["directories"] ||= 'lib test'
35
36   # start watching the directories
37   ENV["directories"].split.each do |directory|
38     Find.find(directory) do |file|
39       if ['.svn', 'CVS', 'RCS'].include? File.basename(file) or !File.directory? file
40         Find.prune
41       else
42         begin
43           puts "Adding #{file}" 
44           inotify.watch_dir(file)
45         rescue
46           puts "Skipping #{file}: #{$!}" 
47         end
48       end
49     end
50   end
51   puts "" 
52
53   thread.join
54 end

The default list of directories (relative to the current directory) is specified on line 34. You can override this at runtime by specifying the “directories” environment variable.


5
May 06

ScottishClimbs has a wiki!

In case you missed it over on SC, we launched our wiki last night!

We expect the entire site to migrate over to the wiki in the coming months and this is a direct replacement for SC3. A wiki should be such a perfect fit for the community-based contribution model that has been the basis of ScottishClimbs all along.