diff --git a/test/engine/erubi_test_suite_test.rb b/test/engine/erubi_test_suite_test.rb
new file mode 100644
index 000000000..f39186bc1
--- /dev/null
+++ b/test/engine/erubi_test_suite_test.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+require_relative "../test_helper"
+require_relative "../../lib/herb/engine"
+
+# These tests are adapted from the erubi test suite at:
+# https://github.com/jeremyevans/erubi/blob/master/test/test.rb
+#
+# Each test verifies that Herb::Engine produces the exact same evaluated output
+# as Erubi::Engine for the given template and options.
+module Engine
+ class ErubiTestSuiteTest < Minitest::Spec
+ include SnapshotUtils
+
+ ERUBI_OPTS = { enforce_erubi_equality: true, enforce_actionview_erubi_equality: false }.freeze
+
+ test "handles literal erb escape with double percent" do
+ template = <<~ERB.chomp
+
+ <%% for item in @items %>
+
+ | <%# i+1 %> |
+ <%# item %> |
+
+ <%% end %>
+
+ ERB
+
+ assert_evaluated_snapshot(template, { :@items => [2], i: 0 }, **ERUBI_OPTS)
+ end
+
+ test "double percent escapes erb tag" do
+ template = "<%%= 'literal' %>"
+
+ assert_evaluated_snapshot(template, {}, **ERUBI_OPTS)
+ end
+
+ test "double percent with equals escapes erb expression" do
+ template = "<%%== 'literal' %>"
+
+ assert_evaluated_snapshot(template, {}, **ERUBI_OPTS)
+ end
+
+ test "code tag with trailing content preserves whitespace" do
+ template = " <% x = 1 %> b\n<%= x %>"
+
+ assert_evaluated_snapshot(template, {}, **ERUBI_OPTS)
+ end
+
+ test "trim false with code tags preserves whitespace" do
+ template = " <% x = 1 %>\n<%= x %>\n"
+
+ assert_evaluated_snapshot(template, {}, trim: false, **ERUBI_OPTS)
+ end
+
+ test "trim false with comment tags preserves whitespace" do
+ template = " <%# comment %>\ntext\n"
+
+ assert_evaluated_snapshot(template, {}, trim: false, **ERUBI_OPTS)
+ end
+
+ test "code tag with string containing erb-like content" do
+ template = "<% x = '<%' %><%= x %>"
+
+ assert_evaluated_snapshot(template, {}, **ERUBI_OPTS)
+ end
+
+ test "literal percent with different prefix and postfix" do
+ template = <<~ERB.chomp
+
+ <%% for item in @items %>
+
+
+ <%% end %>
+ <%%= "literal" %>
+
+ ERB
+
+ assert_evaluated_snapshot(
+ template,
+ { :@items => [2], i: 0 },
+ literal_prefix: "{%",
+ literal_postfix: "%}",
+ **ERUBI_OPTS
+ )
+ end
+ end
+end
diff --git a/test/snapshots/engine/erubi_test_suite_test/test_0001_handles_literal_erb_escape_with_double_percent_15dbef6a69ba2d8a8cda73694c518a2d.txt b/test/snapshots/engine/erubi_test_suite_test/test_0001_handles_literal_erb_escape_with_double_percent_15dbef6a69ba2d8a8cda73694c518a2d.txt
new file mode 100644
index 000000000..5ee514d97
--- /dev/null
+++ b/test/snapshots/engine/erubi_test_suite_test/test_0001_handles_literal_erb_escape_with_double_percent_15dbef6a69ba2d8a8cda73694c518a2d.txt
@@ -0,0 +1,10 @@
+---
+source: "Engine::ErubiTestSuiteTest#test_0001_handles literal erb escape with double percent"
+input: "{source: \"\\n<%% for item in @items %>\\n \\n | <%# i+1 %> | \\n <%# item %> | \\n
\\n <%% end %>\\n
\", locals: {\"@items\": [2], i: 0}, options: {}}"
+---
+
\ No newline at end of file
diff --git a/test/snapshots/engine/erubi_test_suite_test/test_0002_double_percent_escapes_erb_tag_af6693e78fc378ccf02bbf3c33fea315.txt b/test/snapshots/engine/erubi_test_suite_test/test_0002_double_percent_escapes_erb_tag_af6693e78fc378ccf02bbf3c33fea315.txt
new file mode 100644
index 000000000..763a53504
--- /dev/null
+++ b/test/snapshots/engine/erubi_test_suite_test/test_0002_double_percent_escapes_erb_tag_af6693e78fc378ccf02bbf3c33fea315.txt
@@ -0,0 +1,5 @@
+---
+source: "Engine::ErubiTestSuiteTest#test_0002_double percent escapes erb tag"
+input: "{source: \"<%%= 'literal' %>\", locals: {}, options: {}}"
+---
+literal
\ No newline at end of file
diff --git a/test/snapshots/engine/erubi_test_suite_test/test_0004_code_tag_with_trailing_content_preserves_whitespace_deac58b9a48c3a82beafaa26ce5f1f3f.txt b/test/snapshots/engine/erubi_test_suite_test/test_0004_code_tag_with_trailing_content_preserves_whitespace_deac58b9a48c3a82beafaa26ce5f1f3f.txt
new file mode 100644
index 000000000..82887392c
--- /dev/null
+++ b/test/snapshots/engine/erubi_test_suite_test/test_0004_code_tag_with_trailing_content_preserves_whitespace_deac58b9a48c3a82beafaa26ce5f1f3f.txt
@@ -0,0 +1,6 @@
+---
+source: "Engine::ErubiTestSuiteTest#test_0004_code tag with trailing content preserves whitespace"
+input: "{source: \" <% x = 1 %> b\\n<%= x %>\", locals: {}, options: {}}"
+---
+ b
+1
\ No newline at end of file
diff --git a/test/snapshots/engine/erubi_test_suite_test/test_0005_trim_false_with_code_tags_preserves_whitespace_faa9cbb4f5c5cf9505d4b8beb5a69a95.txt b/test/snapshots/engine/erubi_test_suite_test/test_0005_trim_false_with_code_tags_preserves_whitespace_faa9cbb4f5c5cf9505d4b8beb5a69a95.txt
new file mode 100644
index 000000000..a7c7023fe
--- /dev/null
+++ b/test/snapshots/engine/erubi_test_suite_test/test_0005_trim_false_with_code_tags_preserves_whitespace_faa9cbb4f5c5cf9505d4b8beb5a69a95.txt
@@ -0,0 +1,5 @@
+---
+source: "Engine::ErubiTestSuiteTest#test_0005_trim false with code tags preserves whitespace"
+input: "{source: \" <% x = 1 %>\\n<%= x %>\\n\", locals: {}, options: {trim: false}}"
+---
+1
diff --git a/test/snapshots/engine/erubi_test_suite_test/test_0006_trim_false_with_comment_tags_preserves_whitespace_504fe15a2a9022962b1032671a82d7d5.txt b/test/snapshots/engine/erubi_test_suite_test/test_0006_trim_false_with_comment_tags_preserves_whitespace_504fe15a2a9022962b1032671a82d7d5.txt
new file mode 100644
index 000000000..b3ee28f74
--- /dev/null
+++ b/test/snapshots/engine/erubi_test_suite_test/test_0006_trim_false_with_comment_tags_preserves_whitespace_504fe15a2a9022962b1032671a82d7d5.txt
@@ -0,0 +1,5 @@
+---
+source: "Engine::ErubiTestSuiteTest#test_0006_trim false with comment tags preserves whitespace"
+input: "{source: \" <%# comment %>\\ntext\\n\", locals: {}, options: {trim: false}}"
+---
+text
diff --git a/test/snapshots/engine/erubi_test_suite_test/test_0008_literal_percent_with_different_prefix_and_postfix_b835968f32021adc6988946e1b1bc86e.txt b/test/snapshots/engine/erubi_test_suite_test/test_0008_literal_percent_with_different_prefix_and_postfix_b835968f32021adc6988946e1b1bc86e.txt
new file mode 100644
index 000000000..3ae41928b
--- /dev/null
+++ b/test/snapshots/engine/erubi_test_suite_test/test_0008_literal_percent_with_different_prefix_and_postfix_b835968f32021adc6988946e1b1bc86e.txt
@@ -0,0 +1,9 @@
+---
+source: "Engine::ErubiTestSuiteTest#test_0008_literal percent with different prefix and postfix"
+input: "{source: \"\\n <%% for item in @items %>\\n \\n
\\n <%% end %>\\n <%%= \\\"literal\\\" %>\\n
\", locals: {\"@items\": [2], i: 0}, options: {literal_prefix: \"{%\", literal_postfix: \"%}\"}}"
+---
+
\ No newline at end of file