Using Rake to automate PHP testing on linux
May 15th, 2006
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.
Leave a Reply