Talks
Summarized using AI

Spork

by Tim C. Harper

In the presentation titled 'Spork' by Tim C. Harper at the LoneStarRuby Conf 2009, the speaker addresses the challenge of long test cycle times in Ruby applications using RSpec and Cucumber frameworks. The speaker explains how these applications take approximately 15 seconds to start due to the extensive loading of gems and dependencies, which is a significant bottleneck when testing code.

To mitigate this issue, Tim Harper introduces 'Spork', a tool developed to fork a copy of the process and run specs without corrupting the state of the tests. This approach allows for faster test execution while maintaining the integrity of the loading process. Key aspects of the presentation include:

  • Problem Identification: The long startup time of 15 seconds and the unreliability of the Spec Server due to Rails constant unloading issues.
  • Solution - Spork: By forking the process, libraries can be loaded once, and the fork can be discarded after running the tests, preventing corruption and speeding up the process significantly.
  • Demo of RSpec Setup: The speaker demonstrates setting up RSpec with Spork and demonstrates how code changes can influence testing speeds depending on how the pre-fork and each-run blocks are configured.
  • Performance Improvement: The demo shows a dramatic reduction in execution time from over seven seconds to approximately 0.816 seconds after implementing Spork, highlighting the effectiveness of this tool in improving test speed.
  • Versatility of Spork: Tim emphasizes that Spork is not limited to RSpec and Cucumber; it can also support other testing frameworks like Test Unit and is compatible with Merb.

The session concludes with an invitation for questions, emphasizing the importance of fast specifications for productive development. Spork proves to be a valuable tool for developers looking to optimize their testing workflow and reduce feedback loops.

00:00:20.460 Thank you.
00:00:21.359 So, uh, I use RSpec and Cucumber. I enjoy both of the tools. One of the problems we had was that it takes about 15 seconds for one of our applications to start up. We load a lot of gems and dependencies.
00:00:30.119 This increases the cycle time of our tests. We write some code, and then we run our tests. Fifteen seconds later, we find out whether or not it compiled and worked. This delay is very prohibitive.
00:00:39.360 We used the Spec Server, which was also problematic as it relied on the Rails constant unloading algorithm that they employed. There are many ways to break that algorithm, and we were breaking it. It would work for a few runs, and then it would get into a corrupted state, causing all of our specs to fail for no apparent reason. This was also unacceptable.
00:00:58.079 I set out to solve this problem. I had been doing some work with forking before, and I thought, 'Why don't we just fork a copy of the process and run the specs in that fork?' This way, we benefit from having all of our libraries loaded initially, and then we can simply discard that copy of the process.
00:01:17.400 This method allows us to run the tests repeatedly without the process becoming corrupted. I'm going to do a quick demo to show how this approach can benefit you.
00:01:32.939 One other thing to note is that Spork is not specifically tailored to RSpec or Cucumber. While it does support both, it is not limited to them; support for Test Unit and any other framework can also be added. Additionally, it works with application frameworks like Merb, so if you're a Merb user, there's someone working on Merb integration for Spork.
00:01:53.400 Now, onto the demo. I have here a brief demo app. I'm going to rewind and run a command to generate our spec. This command creates the necessary structure for using RSpec.
00:02:06.960 Here's our RSpec helper file, which is essential for setting up tests. We can create a simple example spec that describes a basic assertion. For instance, we could specify that 'true should be true.'
00:02:28.200 Now, when we run that example spec using the command, we need to ensure that we load the spec helper file as well. I’ll run the command to execute the example spec.
00:02:49.080 After executing the spec, the output shows the execution time, which is approximately 2.791 seconds. However, if we introduce a sleep command to simulate a longer loading time, it takes significantly longer, around 7.879 seconds.
00:03:01.980 Next, to set up RSpec with Spork, we're going to bootstrap our RSpec helper. This creates two blocks: a pre-fork block that runs once and an each-run block that executes every time we invoke our specs. This distinction allows us to differentiate between what is pre-loaded and what is loaded with each test run.
00:03:18.680 The advantage of placing items in the pre-fork block is that it speeds up loading; however, those items won't be reloaded with each test run. Consequently, to see any changes to code, we would need to restart Spork to reload those changes.
00:03:38.520 Now, I'll go through our original spec helper and basically place it into the pre-fork block, removing unnecessary comments and ensuring that our spec helpers load each time we run the tests. This will enable any tweaks to be applied during each run.
00:03:54.180 Once I've done that, I simply start Spork, and it's as simple as that. However, I must note that there is a known issue with RSpec that we need to resolve. Spork should handle the detection of the Rails framework being loaded.
00:04:01.680 Now let's run the command again to see the difference in execution time after implementing Spork. The time has dropped significantly from over seven seconds to approximately 0.816 seconds. This reduction in time shows how effectively Spork can speed up our testing process.
00:04:40.139 So the process can be repeated, resulting in fast specs. And with that, I’d like to open the floor for questions.
00:05:01.680 Thank you for your attention. If you have any questions, feel free to ask.
Explore all talks recorded at LoneStarRuby Conf 2009
+14