diff --git a/src/lua/tap.lua b/src/lua/tap.lua
index 34c4f3fe6012135a9ad3072af70e9f6294742d4e..67cb4026cf86ca7f852bda811e4af8bb58f30d44 100644
--- a/src/lua/tap.lua
+++ b/src/lua/tap.lua
@@ -126,6 +126,20 @@ local function cmpdeeply(got, expected, extra)
     return true
 end
 
+local function like(test, got, pattern, message, extra)
+    extra = extra or {}
+    extra.got = got
+    extra.expected = pattern
+    return ok(test, string.match(tostring(got), pattern) ~= nil, message, extra)
+end
+
+local function unlike(test, got, pattern, message, extra)
+    extra = extra or {}
+    extra.got = got
+    extra.expected = pattern
+    return ok(test, string.match(tostring(got), pattern) == nil, message, extra)
+end
+
 local function is(test, got, expected, message, extra)
     extra = extra or {}
     extra.got = got
@@ -141,7 +155,7 @@ local function isnt(test, got, unexpected, message, extra)
 end
 
 
-local function isdeeply(test, got, expected, message, extra)
+local function is_deeply(test, got, expected, message, extra)
     extra = extra or {}
     extra.got = got
     extra.expected = expected
@@ -268,7 +282,9 @@ test_mt = {
         isboolean = isboolean;
         isudata   = isudata;
         iscdata   = iscdata;
-        isdeeply  = isdeeply;
+        is_deeply = is_deeply;
+        like      = like;
+        unlike    = unlike;
     }
 }
 
diff --git a/test/app/lua/serializer_test.lua b/test/app/lua/serializer_test.lua
index 22f7b028b2668163aa3aedb1efd4be5474c169f6..3adb18518d913d8112c498d3a6ca19aeaa398d13 100644
--- a/test/app/lua/serializer_test.lua
+++ b/test/app/lua/serializer_test.lua
@@ -18,7 +18,7 @@ local function rt(test, s, x)
     else
         xstr = tostring(x)
     end
-    test:isdeeply(x, x1, "encode/decode for "..xstr)
+    test:is_deeply(x, x1, "encode/decode for "..xstr)
 end
 
 local function test_unsigned(test, s)
diff --git a/test/app/msgpack.test.lua b/test/app/msgpack.test.lua
index b101b361bff04ee2d2d1f8f7196d8f06cbed3073..8fd8b15d8edbb603ee4fa2e59671a627c5404d7f 100755
--- a/test/app/msgpack.test.lua
+++ b/test/app/msgpack.test.lua
@@ -25,11 +25,11 @@ local function test_offsets(test, s)
     local a
     local offset = 1
     a, offset = s.decode(dump, offset)
-    test:isdeeply(a, arr1, "decoded part1")
+    test:is_deeply(a, arr1, "decoded part1")
     test:is(offset, 5, "offset of part2")
 
     a, offset = s.decode(dump, offset)
-    test:isdeeply(a, arr2, "decoded part2")
+    test:is_deeply(a, arr2, "decoded part2")
     test:is(offset, 9, "offset of end")
 
     test:ok(not pcall(s.decode, dump, offset), "invalid offset")
diff --git a/test/app/msgpackffi.test.lua b/test/app/msgpackffi.test.lua
index 3a9e2fc76477cd7b1459f4cf494420deb86f889e..a3fdf7504b1041778d2bd06aafd07b6346e5db09 100755
--- a/test/app/msgpackffi.test.lua
+++ b/test/app/msgpackffi.test.lua
@@ -25,11 +25,11 @@ local function test_offsets(test, s)
     local a
     local offset = 1
     a, offset = s.decode(dump, offset)
-    test:isdeeply(a, arr1, "decoded part1")
+    test:is_deeply(a, arr1, "decoded part1")
     test:is(offset, 5, "offset of part2")
 
     a, offset = s.decode(dump, offset)
-    test:isdeeply(a, arr2, "decoded part2")
+    test:is_deeply(a, arr2, "decoded part2")
     test:is(offset, 9, "offset of end")
 
     test:ok(not pcall(s.decode, dump, offset), "invalid offset")
diff --git a/test/app/tap.result b/test/app/tap.result
index a26757e5bf0de39ea0266d114785af85f9dafc64..3e7882331599fad91d2a2f6d2aefa9efa7a62a43 100644
--- a/test/app/tap.result
+++ b/test/app/tap.result
@@ -1,5 +1,5 @@
 TAP version 13
-1..31
+1..32
 ok - true
 ok - extra information is not printed on success
 not ok - extra printed using yaml only on failure
@@ -118,7 +118,7 @@ not ok - failed subtests
   planned: 1
   failed: 1
   ...
-    # isdeeply
+    # is_deeply
     1..6
     ok - 1 and 1
     ok - abc and abc
@@ -136,10 +136,16 @@ not ok - failed subtests
       expected: 5
       got: 4
       ...
-    # isdeeply: end
+    # is_deeply: end
 not ok - failed subtests
   ---
   planned: 6
   failed: 2
   ...
+    # like
+    1..2
+    ok - like(abcde, cd)
+    ok - unlike(abcde, acd)
+    # like: end
+ok - like
 # failed subtest: 15
diff --git a/test/app/tap.test.lua b/test/app/tap.test.lua
index cc2d9bf3828395259b466ecc27e284bfd6cdaa62..a823faaa9ced0977fa00253d76442f1a9ca3a8a6 100755
--- a/test/app/tap.test.lua
+++ b/test/app/tap.test.lua
@@ -20,7 +20,7 @@ test.trace = false
 -- ok, fail and skip predicates
 --
 
-test:plan(31) -- plan to run 3 test
+test:plan(32) -- plan to run 3 test
 test:ok(true, 'true') -- basic function
 local extra = { state = 'some userful information to debug on failure',
         details = 'a table argument formatted using yaml.encode()' }
@@ -117,18 +117,25 @@ end)
 
 
 
-test:test('isdeeply', function(t)
+test:test('is_deeply', function(t)
     t:plan(6)
 
-    t:isdeeply(1, 1, '1 and 1')
-    t:isdeeply('abc', 'abc', 'abc and abc')
-    t:isdeeply({}, {}, 'empty tables')
-    t:isdeeply({1}, {1}, '{1} and {1}')
-    t:isdeeply({1}, {2}, '{1} and {2}')
-    t:isdeeply({1, 2, { 3, 4 }}, {1, 2, { 3, 5 }}, '{1,2,{3,4}} and {1,2,{3,5}}')
+    t:is_deeply(1, 1, '1 and 1')
+    t:is_deeply('abc', 'abc', 'abc and abc')
+    t:is_deeply({}, {}, 'empty tables')
+    t:is_deeply({1}, {1}, '{1} and {1}')
+    t:is_deeply({1}, {2}, '{1} and {2}')
+    t:is_deeply({1, 2, { 3, 4 }}, {1, 2, { 3, 5 }}, '{1,2,{3,4}} and {1,2,{3,5}}')
 
 end)
 
+
+test:test('like', function(t)
+    t:plan(2)
+    t:like('abcde', 'cd', 'like(abcde, cd)')
+    t:unlike('abcde', 'acd', 'unlike(abcde, acd)')
+end)
+
 --
 -- Finish root test. Since we used non-callback variant, we have to
 -- call check explicitly.