Megatest
Megatest is a test-unit like framework with a focus on usability, and designed with continuous integration in mind.
Installation
Install the gem and add to the application's Gemfile by executing:
$ bundle add megatest
Usage
Writing Tests
Test suites are Ruby classes that inherit from Megatest::Test
.
Test cases are be defined with the test
macro, or for compatibility with existing test suites,
by defining a method starting with test_
.
All the classic test-unit
and minitest
assertion methods are available:
class SomeTest < MyApp::Test
setup do
@user = User.new("George")
end
test "the truth" do
assert_equal true, Some.truth
end
def test_it_works
assert_predicate 2, :even?
end
end
By convention, all the test_helper.rb
files are automatically loaded,
which allows to centralize dependencies and define some helpers.
require "some_dependency"
module MyApp
class Test < Megatest::Test
def some_helper(arg)
end
end
end
It also allow to define test inside context
blocks, to make it easier to group
related tests together and have them share a common name prefix.
class SomeTest < MyApp::Test
context "when on earth" do
test "1 is odd" do
App.location = "earth"
assert_predicate 1, :odd?
end
test "2 is even" do
App.location = "earth"
assert_predicate 2, :even?
end
end
end
Note however that context blocks aren't test suites, they don't have their own setup or teardown
blocks, nor their own namespaces.
Command Line
Contrary to many alternatives, megatest
provide a convenient CLI interface to easily run specific tests.
Run all tests in a directory:
$ megatest
$ megatest test/integration
Runs tests using 8 processes:
$ megatest -j 8
Run a test at the specific line:
$ megatest test/some_test.rb:42 test/other_test.rb:24
Run all tests matching a pattern:
$ megatest test/some_test.rb:/matching
For more detailed usage, run megatest --help
.
CI Parallelization
Megatest offer multiple feature to allow running test suites in parallel across
many CI jobs.
Sharding
The simplest way is sharding. Each worker will run its share of the test cases.
Many CI systems provide a way to run the same command on multiple nodes,
and will generally expose environment variables to help split the workload.
- label: "Run Unit Tests"
run: megatest --workers-count $CI_NODE_INDEX --worker-id $CI_NODE_TOTAL
parallel: 8
Note that Megatest makes no effort at balancing the shards as it has no
information about how long each individual test case is expected to take.
However it does shard test cases individually, so it avoids the most common issue which is
very large test suites containing lots of slow test cases being sharded as one unit.
If you are using CircleCI, Buildkite or HerokuCI, the workers count and worker id
will be automatically inferred from the environment.
Redis Distribution
A more efficient way to parallelize tests on CI is to use a Redis server to act as a queue.
This allow to efficiently and dynamically ensure a near perfect test case balance across all
the workers. And if for some reason one of the worker is lost or crashes, no test is lost,
which for builds with hundreds of parallel jobs, is essential for stability.
- label: "Run Unit Tests"
run: megatest --queue redis://redis-ci.example.com --build-id $CI_BUILD_ID --worker-id $CI_JOB_ID
parallel: 128
soft_fail: true
- label: "Unit Test Results"
run: megatest report --queue redis://redis-ci.example.com --build-id $CI_BUILD_ID
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/byroot/megatest.