diff --git a/gnu/packages/ruby.scm b/gnu/packages/ruby.scm
index e507c816c8..59895240f8 100644
--- a/gnu/packages/ruby.scm
+++ b/gnu/packages/ruby.scm
@@ -32,6 +32,7 @@
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (gnu packages)
   #:use-module (gnu packages base)
+  #:use-module (gnu packages check)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages databases)
   #:use-module (gnu packages dbm)
@@ -3795,6 +3796,141 @@ It is intended be used by all Cucumber implementations to parse
     (home-page "https://github.com/cucumber-attic/gherkin")
     (license license:expat)))
 
+(define-public ruby-aruba
+  (package
+    (name "ruby-aruba")
+    (version "0.14.7")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (rubygems-uri "aruba" version))
+       (sha256
+        (base32
+         "0x27352n15dsyf5ak246znfawbrm502q15r4msjw3cis17jlcy1l"))))
+    (build-system ruby-build-system)
+    (arguments
+     '(;; TODO: There are a few test failures
+       ;; 357 examples, 7 failures
+       #:tests? #f
+       #:test-target "spec"
+       #:phases
+       (modify-phases %standard-phases
+         (add-before 'check 'remove-unnecessary-dependencies
+           (lambda _
+             (substitute* "Gemfile"
+               ((".*byebug.*") "\n")
+               ((".*pry.*") "\n")
+               ((".*yaml.*") "\n")
+               ((".*bcat.*") "\n")
+               ((".*kramdown.*") "\n")
+               ((".*rubocop.*") "\n")
+               ((".*cucumber-pro.*") "\n")
+               ((".*cucumber.*") "\n")
+               ((".*license_finder.*") "\n")
+               ((".*rake.*") "gem 'rake'\n")
+               ((".*simplecov.*") "\n")
+               ((".*relish.*") "\n"))
+             (substitute* "spec/spec_helper.rb"
+               ((".*simplecov.*") "")
+               (("^SimpleCov.*") ""))
+             (substitute* "aruba.gemspec"
+               (("spec\\.add\\_runtime\\_dependency 'cucumber'.*")
+                "spec.add_runtime_dependency 'cucumber'"))
+             #t))
+         (add-before 'check 'set-home
+           (lambda _ (setenv "HOME" "/tmp") #t)))))
+    (native-inputs
+     `(("bundler" ,bundler)
+       ("ruby-rspec" ,ruby-rspec)
+       ("ruby-fuubar" ,ruby-fuubar)))
+    (propagated-inputs
+     `(("ruby-childprocess" ,ruby-childprocess)
+       ("ruby-contracts" ,ruby-contracts)
+       ("ruby-cucumber" ,ruby-cucumber)
+       ("ruby-ffi" ,ruby-ffi)
+       ("ruby-rspec-expectations" ,ruby-rspec-expectations)
+       ("ruby-thor" ,ruby-thor)))
+    (synopsis "Test command-line applications with Cucumber, RSpec or Minitest")
+    (description
+     "Aruba is an extension for Cucumber, RSpec and Minitest for testing
+command-line applications.  It supports applications written in any
+language.")
+    (home-page "https://github.com/cucumber/aruba")
+    (license license:expat)))
+
+;; A version of ruby-aruba without tests run so that circular dependencies can
+;; be avoided.
+(define ruby-aruba-without-tests
+  (package
+    (inherit ruby-aruba)
+    (arguments '(#:tests? #f))
+    (propagated-inputs
+     (map (lambda (input)
+            (if (string=? (car input) "ruby-cucumber")
+                `("ruby-cucumber" ,ruby-cucumber-without-tests)
+                input))
+          (package-propagated-inputs ruby-aruba)))
+    (native-inputs '())))
+
+(define-public ruby-cucumber
+  (package
+    (name "ruby-cucumber")
+    (version "3.1.2")
+    (source
+     (origin
+       (method git-fetch)
+       (uri (git-reference
+             (url "https://github.com/cucumber/cucumber-ruby.git")
+             (commit (string-append "v" version))))
+       (file-name (git-file-name name version))
+       (sha256
+        (base32
+         "0764wp2cjg60qa3l69q1dxda5g06a01n5w92szqbf89d2hgl47n3"))))
+    (build-system ruby-build-system)
+    (arguments
+     '(#:test-target "spec"
+       #:phases
+       (modify-phases %standard-phases
+         ;; Don't run or require rubocop, the code linting tool, as this is a
+         ;; bit unnecessary.
+         (add-after 'unpack 'dont-run-rubocop
+           (lambda _
+             (substitute* "Rakefile"
+               ((".*rubocop/rake\\_task.*") "")
+               ((".*RuboCop.*") ""))
+             #t)))))
+    (propagated-inputs
+     `(("ruby-builder" ,ruby-builder)
+       ("ruby-cucumber-core" ,ruby-cucumber-core)
+       ("ruby-cucumber-wire" ,ruby-cucumber-wire)
+       ("ruby-cucumber-expressions" ,ruby-cucumber-expressions)
+       ("ruby-diff-lcs" ,ruby-diff-lcs)
+       ("ruby-gherkin" ,ruby-gherkin)
+       ("ruby-multi-json" ,ruby-multi-json)
+       ("ruby-multi-test" ,ruby-multi-test)))
+    (native-inputs
+     `(("bundler" ,bundler)
+       ;; Use a untested version of aruba, to avoid a circular dependency, as
+       ;; ruby-aruba depends on ruby-cucumber.
+       ("ruby-aruba", ruby-aruba-without-tests)
+       ("ruby-rspec" ,ruby-rspec)
+       ("ruby-pry" ,ruby-pry)
+       ("ruby-nokogiri" ,ruby-nokogiri)))
+    (synopsis "Describe automated tests in plain language")
+    (description
+     "Cucumber is a tool for running automated tests written in plain
+language.  It's designed to support a Behaviour Driven Development (BDD)
+software development workflow.")
+    (home-page "https://cucumber.io/")
+    (license license:expat)))
+
+(define ruby-cucumber-without-tests
+  (package (inherit ruby-cucumber)
+    (arguments
+     '(#:tests? #f))
+    (native-inputs
+     '())))
+
 (define-public ruby-cucumber-core
   (package
     (name "ruby-cucumber-core")
