Test Tube

Version Yard documentation License

A test tube to conduct software experiments safely 🧪

TestTube is a Ruby library designed to safely execute and evaluate code experiments. It provides: - Complete exception handling (including SystemExit and other system-level exceptions) - A flexible matcher-based testing approach - Two distinct testing methods: code execution (invoke) and value testing (pass) - Clear experiment results with actual values, errors, and matcher results

A researcher experimenting with Ruby code

Installation

Add this line to your application’s Gemfile:

ruby gem "test_tube"

And then execute:

sh bundle install

Or install it yourself as:

sh gem install test_tube

Usage

Basic Usage

First, make TestTube available:

ruby require "test_tube"

TestTube provides two main ways to conduct experiments:

  1. Execute and test code with invoke:
    • Safely executes blocks of code
    • Catches ALL exceptions, including system-level ones
    • Perfect for testing potentially dangerous operations
  2. Test direct values with pass:
    • Tests pre-computed values
    • Simpler and more direct approach
    • Ideal when you already have the value to test

Simple Example

Let’s test if a value equals 42 using a custom matcher:

```ruby class BeTheAnswer def match? 42.equal?(yield) end end

Using invoke to execute code

experiment = TestTube.invoke(matcher: BeTheAnswer.new, negate: false) do “101010”.to_i(2) # Converting binary to decimal end experiment.got # => true experiment.actual # => 42 experiment.error # => nil

Or using pass with a direct value

experiment = TestTube.pass(42, matcher: BeTheAnswer.new, negate: false) experiment.got # => true experiment.actual # => 42 experiment.error # => nil ```

Integration with Matchi

TestTube works seamlessly with the Matchi matcher library:

sh gem install matchi

```ruby require “matchi”

Testing for exceptions

experiment = TestTube.invoke( matcher: Matchi::RaiseException.new(:NoMethodError), negate: false ) { “foo”.blank? } experiment.got # => true experiment.actual # => #<NoMethodError: undefined method `blank?’ for “foo”:String>

Testing floating-point arithmetic

experiment = TestTube.invoke( matcher: Matchi::Be.new(0.3), negate: false ) { 0.1 + 0.2 } experiment.got # => false experiment.actual # => 0.30000000000000004

Handling errors gracefully

experiment = TestTube.invoke( matcher: Matchi::Match.new(/^foo$/), negate: false ) { BOOM } experiment.got # => nil experiment.error # => #<NameError: uninitialized constant BOOM> experiment.actual # => nil ```

Key Features

  • Safe Execution: Catches all exceptions, including system-level ones
  • Flexible Testing: Support for custom matchers and the Matchi library
  • Clear Results: Easy access to actual values, errors, and test results
  • Two Testing Modes: Choose between code execution and direct value testing
  • Framework Friendly: Perfect for building testing frameworks and tools

Contact

  • Source code: https://github.com/fixrb/test_tube
  • Chinese blog post: https://ruby-china.org/topics/41390
  • Japanese blog post: https://qiita.com/cyril/items/36174b619ff1852c80ec

Versioning

Test Tube follows Semantic Versioning 2.0.

License

The gem is available as open source under the terms of the MIT License.

Sponsors

This project is sponsored by Sashité