diff --git a/modules/ts/include/opencv2/ts/ts.hpp b/modules/ts/include/opencv2/ts/ts.hpp
index fcef5896c643eaddd6655a2495826a4db245174d..ea0c979115cfd530f5cfe60d5b53335a1a12a143 100644
--- a/modules/ts/include/opencv2/ts/ts.hpp
+++ b/modules/ts/include/opencv2/ts/ts.hpp
@@ -578,6 +578,13 @@ int main(int argc, char **argv) \
     return RUN_ALL_TESTS(); \
 }
 
+// This usually only makes sense in perf tests with several implementations,
+// some of which are not available.
+#define CV_TEST_FAIL_NO_IMPL() do { \
+    ::testing::Test::RecordProperty("custom_status", "noimpl"); \
+    FAIL() << "No equivalent implementation."; \
+} while (0)
+
 #endif
 
 #include "ts_perf.hpp"
diff --git a/modules/ts/misc/testlog_parser.py b/modules/ts/misc/testlog_parser.py
index 841ad2e130d0a9268d17c30abb16d4aba2d027ba..4ab0a3ef2f3e9ebedbe57fefab9c998d5990fd5e 100755
--- a/modules/ts/misc/testlog_parser.py
+++ b/modules/ts/misc/testlog_parser.py
@@ -14,13 +14,13 @@ class TestInfo(object):
         self.value_param = xmlnode.getAttribute("value_param")
         self.type_param = xmlnode.getAttribute("type_param")
 
+        custom_status = xmlnode.getAttribute("custom_status")
         failures = xmlnode.getElementsByTagName("failure")
-        if len(failures) > 0:
-            if any("No equivalent implementation" in f.getAttribute("message")
-                   for f in failures):
-                self.status = "notimpl"
-            else:
-                self.status = "failed"
+
+        if len(custom_status) > 0:
+            self.status = custom_status
+        elif len(failures) > 0:
+            self.status = "failed"
         else:
             self.status = xmlnode.getAttribute("status")